I trying to build brief software. Firstly I create the ./lib/libbrief.so, and secondly I am trying to build main file. The makefile which included in .zip file:
CC=g++
SOURCES=main.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=main
//#Only enable -msse4.2 on CPUs supporting the POPCNT instruction
CFLAGS = -Wall -DNDEBUG -O3 -march=nocona #-msse4.2
//#CFLAGS = -Wall -DDEBUG -g -O0 -fno-inline-functions
LDFLAGS = -Wl
//# BRIEF
CFLAGS += -I../brief/include
LDFLAGS += -L../brief/lib -lbrief
//# OpenCV
CFLAGS += `pkg-config opencv --cflags`
LDFLAGS += `pkg-config opencv --libs`
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) -g -c $(CFLAGS) $< -o $#
clean:
rm -f $(OBJECTS) $(EXECUTABLE) matches.png
However I am getting errors, related with opencv. The errors found:
g++ -Wl -L../brief/lib -lbrief `pkg-config opencv --libs` main.o -o main
main.o: In function `~BRIEF':
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:203:
undefined reference to `cvReleaseImage'
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:204:
undefined reference to `cvReleaseImage'
main.o: In function `BRIEF':
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:156:
undefined reference to `cvCreateImage'
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:157:
undefined reference to `cvCreateImage'
main.o: In function `TestSampler<signed char>::sampleGaussian(signed char*, int, int)'
main.o: In function `BRIEF':
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:156:
undefined reference to `cvCreateImage'
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:157:
undefined reference to `cvCreateImage'
main.o: In function `TestSampler<signed char>::sampleGaussian(signed char*, int, int)':
main.o: In function `BRIEF::writeTests(std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&) const':
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:511:
undefined reference to `utils::stdoutError(std::basic_string<char,
std::char_traits<char>,
std::allocator<char> >, char const*, int, char const*)'
main.o: In function `BRIEF::readTests(std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)':
Desktop/asdf/brief_v1.0/test_app/../brief/include/brief/BRIEF.hpp:524:
undefined reference to `utils::stdoutError(std::basic_string<char,
std::char_traits<char>,
std::allocator<char> >, char const*, int, char const*)'
main.o: In function `detectSURF':
Desktop/asdf/brief_v1.0/test_app/main.cpp:92: undefined reference to
`cvCreateMemStorage'
Desktop/asdf/brief_v1.0/test_app/main.cpp:101: undefined reference to
`cvExtractSURF'
Desktop/asdf/brief_v1.0/test_app/main.cpp:106: undefined reference to
`cvGetSeqElem'
main.o: In function `timeDescription(int)':
Desktop/asdf/brief_v1.0/test_app/main.cpp:201: undefined reference to
`cvLoadImage'
Desktop/asdf/brief_v1.0/test_app/main.cpp:214: undefined reference to
`cvReleaseImage'
main.o: In function `~BRIEF':
What have to do to build proper the main.cpp?
You must list all the object files on the link like before the libraries that they use.
See, for example, Why does the order in which libraries are linked sometimes cause errors in GCC?
Related
I just implemented the distributed version of a database project using gRPC. When I tried to make with my makefile, I keep getting the undefined reference errors with protobuf and gRPC. Parts of the outputs of make is below. I only included a portion of it because of the word limits.
g++ -o rundb benchmarks/ycsb_query.o benchmarks/tpcc_wl.o benchmarks/ycsb_wl.o benchmarks/ycsb_store_procedure.o benchmarks/tpcc_query.o benchmarks/tpcc_helper.o benchmarks/tpcc_store_procedure.o concurrency_control/lock_manager.o concurrency_control/tictoc_manager.o concurrency_control/row_f1.o concurrency_control/row_lock.o concurrency_control/f1_manager.o concurrency_control/row_tictoc.o storage/catalog.o storage/index_hash.o storage/index_btree.o storage/index_base.o storage/row.o storage/log.o storage/table.o system/stats.o system/manager.o system/cc_manager.o system/thread.o system/global.o system/logging_thread.o system/store_procedure.o system/txn.o system/worker_thread.o system/parser.o system/workload.o system/txn_table.o system/main.o system/caching.o utils/helper.o utils/semaphore_sync.o utils/packetize.o grpc/grpc_async_client.o grpc/grpc_sync_server.o grpc/grpc_async_server.o grpc/grpc_sync_client.o -Wall -L./libs -pthread -lrt -std=c++0x -O3 -ljemalloc -lprotobuf -Wall -g -std=c++11 -I. -I./benchmarks -I./concurrency_control -I./storage -I./system -I./transport -I./utils -I./grpc -I./grpc_system -D NOGRAPHITE=1 -O3 -g -ggdb
/usr/bin/ld: concurrency_control/lock_manager.o: in function `google::protobuf::internal::GenericTypeHandler<sundial_rpc::SundialRequest_TupleData>::New(google::protobuf::Arena*)':
/usr/local/include/google/protobuf/repeated_field.h:802: undefined reference to `sundial_rpc::SundialRequest_TupleData* google::protobuf::Arena::CreateMaybeMessage<sundial_rpc::SundialRequest_TupleData>(google::protobuf::Arena*)'
/usr/bin/ld: system/stats.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const& sundial_rpc::SundialRequest_RequestType_Name<unsigned int>(unsigned int)':
/home/libin/Sundial/./grpc_system/sundial_grpc.pb.h:105: undefined reference to `sundial_rpc::SundialRequest_RequestType_descriptor()'
/usr/bin/ld: system/stats.o: in function `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const& sundial_rpc::SundialResponse_ResponseType_Name<unsigned int>(unsigned int)':
/home/libin/Sundial/./grpc_system/sundial_grpc.pb.h:136: undefined reference to `sundial_rpc::SundialResponse_ResponseType_descriptor()'
/usr/bin/ld: system/txn.o: in function `google::protobuf::internal::GenericTypeHandler<sundial_rpc::SundialResponse_TupleData>::New(google::protobuf::Arena*)':
/usr/local/include/google/protobuf/repeated_field.h:802: undefined reference to `sundial_rpc::SundialResponse_TupleData* google::protobuf::Arena::CreateMaybeMessage<sundial_rpc::SundialResponse_TupleData>(google::protobuf::Arena*)'
/usr/bin/ld: system/txn.o: in function `TxnManager::RemoteNodeInfo::~RemoteNodeInfo()':
/home/libin/Sundial/system/txn.h:102: undefined reference to `sundial_rpc::SundialResponse::~SundialResponse()'
/usr/bin/ld: /home/libin/Sundial/system/txn.h:102: undefined reference to `sundial_rpc::SundialRequest::~SundialRequest()'
/usr/bin/ld: system/txn.o: in function `sundial_rpc::SundialRequest::SundialRequest()':
/home/libin/Sundial/./grpc_system/sundial_grpc.pb.h:494: undefined reference to `sundial_rpc::SundialRequest::SundialRequest(google::protobuf::Arena*)'
/usr/bin/ld: system/txn.o: in function `sundial_rpc::SundialResponse::SundialResponse()':
/home/libin/Sundial/./grpc_system/sundial_grpc.pb.h:909: undefined reference to `sundial_rpc::SundialResponse::SundialResponse(google::protobuf::Arena*)'
/usr/bin/ld: system/txn.o: in function `TxnManager::send_remote_read_request(unsigned long, unsigned long, unsigned long, unsigned long, access_t)':
/home/libin/Sundial/system/txn.cpp:301: undefined reference to `sundial_rpc::SundialRequest::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:302: undefined reference to `sundial_rpc::SundialResponse::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:309: undefined reference to `sundial_rpc::SundialResponse::SundialResponse(sundial_rpc::SundialResponse const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:309: undefined reference to `sundial_rpc::SundialRequest::SundialRequest(sundial_rpc::SundialRequest const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:309: undefined reference to `sundial_rpc::SundialRequest::~SundialRequest()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:309: undefined reference to `sundial_rpc::SundialResponse::~SundialResponse()'
/usr/bin/ld: system/txn.o: in function `google::protobuf::internal::GenericTypeHandler<sundial_rpc::SundialRequest_ReadRequest>::New(google::protobuf::Arena*)':
/usr/local/include/google/protobuf/repeated_field.h:802: undefined reference to `sundial_rpc::SundialRequest_ReadRequest* google::protobuf::Arena::CreateMaybeMessage<sundial_rpc::SundialRequest_ReadRequest>(google::protobuf::Arena*)'
/usr/bin/ld: system/txn.o: in function `TxnManager::process_2pc_phase1()':
/home/libin/Sundial/system/txn.cpp:351: undefined reference to `sundial_rpc::SundialRequest::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:352: undefined reference to `sundial_rpc::SundialResponse::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:362: undefined reference to `sundial_rpc::SundialResponse::SundialResponse(sundial_rpc::SundialResponse const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:362: undefined reference to `sundial_rpc::SundialRequest::SundialRequest(sundial_rpc::SundialRequest const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:362: undefined reference to `sundial_rpc::SundialRequest::~SundialRequest()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:362: undefined reference to `sundial_rpc::SundialResponse::~SundialResponse()'
/usr/bin/ld: system/txn.o: in function `TxnManager::process_2pc_phase2(RC)':
/home/libin/Sundial/system/txn.cpp:420: undefined reference to `sundial_rpc::SundialRequest::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:421: undefined reference to `sundial_rpc::SundialResponse::Clear()'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:429: undefined reference to `sundial_rpc::SundialResponse::SundialResponse(sundial_rpc::SundialResponse const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:429: undefined reference to `sundial_rpc::SundialRequest::SundialRequest(sundial_rpc::SundialRequest const&)'
/usr/bin/ld: /home/libin/Sundial/system/txn.cpp:429: undefined reference to `sundial_rpc::SundialRequest::~SundialRequest()'
/usr/bin/ld: /home/libin/Sundial/grpc/grpc_sync_client.cpp:37: undefined reference to `sundial_rpc::Sundial_GRPC_SYNC::Stub::contactRemote(grpc_impl::ClientContext*, sundial_rpc::SundialRequest const&, sundial_rpc::SundialResponse*)'
/usr/bin/ld: /home/libin/Sundial/grpc/grpc_sync_client.cpp:36: undefined reference to `grpc_impl::ClientContext::~ClientContext()'
/usr/bin/ld: grpc/grpc_sync_client.o: in function `sundial_rpc::Sundial_GRPC_SYNC::Stub::~Stub()':
/home/libin/Sundial/./grpc_system/sundial_grpc.grpc.pb.h:73: undefined reference to `vtable for sundial_rpc::Sundial_GRPC_SYNC::Stub'
/usr/bin/ld: grpc/grpc_sync_client.o: in function `sundial_rpc::Sundial_GRPC_SYNC::Stub::~Stub()':
/home/libin/Sundial/./grpc_system/sundial_grpc.grpc.pb.h:73: undefined reference to `vtable for sundial_rpc::Sundial_GRPC_SYNC::Stub'
/usr/bin/ld: grpc/grpc_sync_client.o: in function `Sundial_Sync_Client::contactRemote(unsigned long, sundial_rpc::SundialRequest, sundial_rpc::SundialResponse)':
/home/libin/Sundial/grpc/grpc_sync_client.cpp:36: undefined reference to `grpc_impl::ClientContext::~ClientContext()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:20: rundb] Error 1
I did read some other previous posts suggesting it is caused by not linking the protobuf library but I did include it in LDFLAGS. The makefile is below.
CC=g++
CFLAGS=-Wall -g -std=c++11
.SUFFIXES: .o .cpp .h
SRC_DIRS = ./ ./benchmarks/ ./concurrency_control/ ./storage/ ./system/ ./transport/ ./utils/ ./grpc/ ./grpc_system/
INCLUDE = -I. -I./benchmarks -I./concurrency_control -I./storage -I./system -I./transport -I./utils -I./grpc -I./grpc_system
CFLAGS += $(INCLUDE) -D NOGRAPHITE=1 -O3 -g -ggdb
LDFLAGS = -Wall -L./libs -pthread -lrt -std=c++0x -O3 -ljemalloc -lprotobuf
LDFLAGS += $(CFLAGS)
CPPS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)*.cpp))
OBJS = $(CPPS:.cpp=.o)
DEPS = $(CPPS:.cpp=.d)
all:rundb
rundb : $(OBJS)
$(CC) -o $# $^ $(LDFLAGS)
-include $(OBJS:%.o=%.d)
%.d: %.cpp
$(CC) -MM -MT $*.o -MF $# $(CFLAGS) $<
%.o: %.cpp %.d
$(CC) -c $(CFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f rundb *.o */*.o *.d */*.d
So I thought LDFLAGS = -Wall -L./libs -pthread -lrt -std=c++0x -O3 -ljemalloc -lprotobuf would resolve this but it did not.
You can try following these two steps:
Step 1:
Add the below two lines in your makefile:
CFLAGS += `pkg-config --cflags protobuf grpc`
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-lgrpc++_reflection\
-ldl
Please refer this Makefile (C++ grpc example for load balancing): https://chromium.googlesource.com/external/github.com/grpc/grpc/+/HEAD/examples/cpp/load_balancing/Makefile
Your Makefile should look like this:
CC=g++
CFLAGS=-Wall -g -std=c++11
# Add the below line
CFLAGS += `pkg-config --cflags protobuf grpc`
.SUFFIXES: .o .cpp .h
SRC_DIRS = ./ ./benchmarks/ ./concurrency_control/ ./storage/ ./system/ ./transport/ ./utils/ ./grpc/ ./grpc_system/
INCLUDE = -I. -I./benchmarks -I./concurrency_control -I./storage -I./system -I./transport -I./utils -I./grpc -I./grpc_system
CFLAGS += $(INCLUDE) -D NOGRAPHITE=1 -O3 -g -ggdb
LDFLAGS = -Wall -L./libs -pthread -lrt -std=c++0x -O3 -ljemalloc -lprotobuf
LDFLAGS += $(CFLAGS)
# Add the below line
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-lgrpc++_reflection\
-ldl
CPPS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)*.cpp))
OBJS = $(CPPS:.cpp=.o)
DEPS = $(CPPS:.cpp=.d)
all:rundb
rundb : $(OBJS)
$(CC) -o $# $^ $(LDFLAGS)
-include $(OBJS:%.o=%.d)
%.d: %.cpp
$(CC) -MM -MT $*.o -MF $# $(CFLAGS) $<
%.o: %.cpp %.d
$(CC) -c $(CFLAGS) -o $# $<
.PHONY: clean
clean:
rm -f rundb *.o */*.o *.d */*.d
Step 2:
In your command prompt, you need to find the path of two files:
Path of "protobuf.pc"
Path of "grpc.pc"
You can find the path using these commands:
sudo find / -name "protobuf.pc"
Example output: /usr/local/lib/pkgconfig
sudo find / -name "grpc.pc"
Example output: /usr/lib/pkgconfig"
At last, you need to add these two paths separated by colon (:) in the environment variable "PKG_CONFIG_PATH" by running this command:
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
Now, you can run your commands and proceed further.
NOTE:
In step 2, if both protobuf.pc and grpc.pc are present in the same directory,
then you need to specify only that directory in the environment variable.
Example:
sudo find / -name "protobuf.pc"
Example output: /lib64/pkgconfig
sudo find / -name "grpc.pc"
Example output: /lib64/pkgconfig
In this case, you can set environment variable as:
export PKG_CONFIG_PATH="/lib64/pkgconfig"
This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 6 years ago.
I have a project with several .cpp and .h files, and I am trying to split the source into core / generic stuff, and application specific code. Based on that, I separated the code files into a Common folder and compiled it as a library. Below is the Makefile for that lib:
CFLAGS=-std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
OUTPUTFILE=libcommon.a
all: $(OUTPUTFILE)
$(OUTPUTFILE): $(OBJECTS)
ar rcs $(OUTPUTFILE) $(OBJECTS)
.cpp.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $# $(GPROF)
clean:
rm -f $(OBJECTS) $(OUTPUTFILE)
Then I created a sample main file just to try out the compilation of an app using that library.
Here is the code of the main source file:
#include "../Common/Functions.h"
#include "../Common/Logger.h"
int main() {
Logger::Init(false, false);
Logger::Debug("Test");
string path = Functions::GetAppPath();
Logger::Debug("App Path: ", path.c_str());
return 0;
}
The functions file that is being referenced uses boost, and here is the makefile for this app that uses the library:
CC=g++
CFLAGS=-Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib
LDFLAGS=-I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common
LIBS=-lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon
SOURCES = $(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=testApp
GPROF=-pg
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $# $(LIBS) $(GPROF)
.cpp.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $# $(GPROF)
clean:
rm -rf *o $(OBJECTS)
When I try to compile, I get the following errors, complaining about undefined references to boost:
g++ -Wl,--verbose -std=c++11 -g -c -pedantic -Wall -Wextra -I../boost_1_57_0 -L../boost_1_57_0/stage/lib main.cpp -o main.o -pg
g++ -I../boost_1_57_0 -L../boost_1_57_0/stage/lib -L../boost_libs/lib -L/usr/lib64 -L/usr/kerberos/lib -L/usr/lib -L../Common main.o -o testApp -lz -lkrb5 -lk5crypto -lcom_err -lresolv -lm -lpthread -lrt -lboost_system -lboost_filesystem -lboost_thread -lboost_date_time -rdynamic -lcurl -lcommon -pg
../Common/libcommon.a(Functions.o): In function `Functions::GetAppPath()':
/media/software/Robots/Common/Functions.cpp:43: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::initial_path()':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:583: undefined reference to `boost::filesystem::detail::initial_path(boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `boost::filesystem::system_complete(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:655: undefined reference to `boost::filesystem::detail::system_complete(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Functions.o): In function `unsigned short boost::date_time::month_str_to_ushort<boost::gregorian::greg_month>(std::string const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/date_time/date_parsing.hpp:67: undefined reference to `boost::gregorian::greg_month::get_month_map_ptr()'
../Common/libcommon.a(Logger.o): In function `Logger::Cleanup()':
/media/software/Robots/Common/Logger.cpp:84: undefined reference to `boost::thread::interrupt()'
../Common/libcommon.a(Logger.o): In function `Logger::InitFile(std::string, bool, std::_Ios_Openmode)':
/media/software/Robots/Common/Logger.cpp:186: undefined reference to `boost::filesystem::path::parent_path() const'
/media/software/Robots/Common/Logger.cpp:187: undefined reference to `boost::filesystem::path::parent_path() const'
../Common/libcommon.a(Logger.o): In function `Logger::Process()':
/media/software/Robots/Common/Logger.cpp:241: undefined reference to `boost::this_thread::interruption_point()'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data_base::thread_data_base()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/pthread/thread_data.hpp:143: undefined reference to `vtable for boost::detail::thread_data_base'
../Common/libcommon.a(Logger.o): In function `boost::thread::start_thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:179: undefined reference to `boost::thread::start_thread_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::thread::~thread()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:254: undefined reference to `boost::thread::detach()'
../Common/libcommon.a(Logger.o): In function `boost::thread::get_id() const':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:741: undefined reference to `boost::thread::native_handle()'
../Common/libcommon.a(Logger.o): In function `boost::thread::join()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:767: undefined reference to `boost::thread::join_noexcept()'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::exists(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:404: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::filesystem::create_directories(boost::filesystem::path const&)':
/media/software/Robots/Common/../boost_1_57_0/boost/filesystem/operations.hpp:523: undefined reference to `boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*)'
../Common/libcommon.a(Logger.o): In function `boost::detail::thread_data<void (*)()>::~thread_data()':
/media/software/Robots/Common/../boost_1_57_0/boost/thread/detail/thread.hpp:90: undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
../Common/libcommon.a(Logger.o):(.rodata._ZTIN5boost6detail11thread_dataIPFvvEEE[_ZTIN5boost6detail11thread_dataIPFvvEEE]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
collect2: error: ld returned 1 exit status
Needless to say that the project as a whole compiles with no issue.
This is my first attempt at building a c++ linux library and using it in another application, so I might be doing a rookie mistake, so bear that in mind.
Help is very much appreciated.
Thank you.
The order of libraries on the command line is significant to the linker. It processes libraries from left to right, resolving as-yet unresolved references already known to it against any functions provided by the current library.
Moreover, and particularly relevant here, if a given library contains references to functions that it does not itself provide then the linker does not resolve those against libraries it has already processed. That's why you have unresolved references: you have -lcommon last among your libraries, so function references therein will be resolved against only the C standard library.
It is valid to list libraries more than once in the link command, and sometimes that is needed, but in this case I think it makes sense simply to put -lcommon as the first library instead of the last. That will resolve the issue. You can even conceptualize this as putting the library most closely related to the main program closest to it in the link command.
I'm compiling a program with 3 source files: main.cpp, DataHandler.cpp and DataHandler.h.
I use a makefile that contains the following code to build:
Makefile
OBJECTS = main.o DataHandler.o
CC = g++
DEBUG = -g
CFLAGS = -c -std=c++11
LFLAGS = -lopendnp3 -lopenpal -lasiodnp3 -lasiopal -lpthread -std=c++11
lvoutstation : $(OBJECTS)
$(CC) $(LFLAGS) $(OBJECTS) -o lvoutstation
main.o : main.cpp DataHandler.h
$(CC) $(CFLAGS) main.cpp
DataHandler.o : DataHandler.cpp DataHandler.h
$(CC) $(CFLAGS) DataHandler.cpp
.PHONY : clean
clean :
rm lvoutstation $(OBJECTS)
It build main.o and DataHandler.o fine, but when it gets to compiling the action executable, it gives linking erros to all my asiodnp3 and opendnp3 namespace function / class calls.
When I run the following command:
g++ -o lvoutstation main.o DataHandler.o -lopendnp3 -lopenpal -lasiodnp3
-lasiopal -lpthread -std=c++11
It works fine..
I don't understand where the linking error comes in?
EDIT
Upon request for the error message:
g++ -lopendnp3 -lopenpal -lasiodnp3 -lasiopal -std=c++11 main.o DataHandler.o -o lvoutstation
main.o: In function `main':
main.cpp:(.text+0x85): undefined reference to `asiodnp3::DNP3Manager::DNP3Manager(unsigned int, openpal::ICryptoProvider*, std::function<void ()>, std::function<void ()>)'
main.cpp:(.text+0xb7): undefined reference to `asiodnp3::DNP3Manager::AddLogSubscriber(openpal::ILogHandler*)'
main.cpp:(.text+0xf0): undefined reference to `opendnp3::ChannelRetry::Default()'
main.cpp:(.text+0x123): undefined reference to `asiodnp3::DNP3Manager::AddTCPServer(char const*, unsigned int, opendnp3::ChannelRetry const&, std::string const&, unsigned short)'
main.cpp:(.text+0x19f): undefined reference to `opendnp3::EventBufferConfig::AllTypes(unsigned short)'
main.cpp:(.text+0x1d6): undefined reference to `opendnp3::DefaultOutstationApplication::Instance()'
main.cpp:(.text+0x2c8): undefined reference to `asiodnp3::DNP3Manager::~DNP3Manager()'
main.o: In function `opendnp3::LinkConfig::LinkConfig(bool, bool)':
main.cpp:(.text._ZN8opendnp310LinkConfigC2Ebb[_ZN8opendnp310LinkConfigC5Ebb]+0x75): undefined reference to `openpal::TimeDuration::Seconds(long)'
main.cpp:(.text._ZN8opendnp310LinkConfigC2Ebb[_ZN8opendnp310LinkConfigC5Ebb]+0x87): undefined reference to `openpal::TimeDuration::Minutes(long)'
main.o: In function `opendnp3::OutstationConfig::OutstationConfig()':
main.cpp:(.text._ZN8opendnp316OutstationConfigC2Ev[_ZN8opendnp316OutstationConfigC5Ev]+0x14): undefined reference to `opendnp3::OutstationParams::OutstationParams()'
main.cpp:(.text._ZN8opendnp316OutstationConfigC2Ev[_ZN8opendnp316OutstationConfigC5Ev]+0x56): undefined reference to `opendnp3::EventBufferConfig::EventBufferConfig(unsigned short, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short, unsigned short)'
main.o: In function `asiodnp3::ConsoleLogger::Instance()':
main.cpp:(.text._ZN8asiodnp313ConsoleLogger8InstanceEv[_ZN8asiodnp313ConsoleLogger8InstanceEv]+0x5): undefined reference to `asiodnp3::ConsoleLogger::instance'
DataHandler.o: In function `DataHandler::ReadMeasurements(asiodnp3::IOutstation*)':
DataHandler.cpp:(.text+0xfe): undefined reference to `asiodnp3::MeasUpdate::MeasUpdate(asiodnp3::IOutstation*)'
DataHandler.cpp:(.text+0x11d): undefined reference to `opendnp3::Analog::Analog(double)'
DataHandler.cpp:(.text+0x137): undefined reference to `asiodnp3::MeasUpdate::Update(opendnp3::Analog const&, unsigned short, opendnp3::EventMode)'
DataHandler.cpp:(.text+0x159): undefined reference to `asiodnp3::MeasUpdate::~MeasUpdate()'
DataHandler.cpp:(.text+0x17b): undefined reference to `asiodnp3::MeasUpdate::~MeasUpdate()'
collect2: error: ld returned 1 exit status
make: *** [lvoutstation] Error 1
The makefile just works as expected. Your action becomes actually different from your command line sample
$(CC) $(LFLAGS) $(OBJECTS) -o lvoutstation
will expand to
g++ -lopendnp3 -lopenpal -lasiodnp3 -lasiopal -lpthread -std=c++11 \
main.o DataHandler.o -o lvoutstation
The order of object files and libraries matters for the linking process.
You can fix the linker errors providing the libraries after the object files:
$(CC) $(OBJECTS) $(LFLAGS) -o lvoutstation
I have been struggling all day for this problem. I use some libraries in my project and I always got some compilation errors complaining that undefined reference.
The relevant files are as follows:
encode.cc//the main file
url_codec.h//the header of the libraries, got some function definition in it
libimageenc.a
libmbpicenc.a
liburlaes.a
liburldecode.a
The makefile is like:
cflags = -Wall -O2 -fPIC
libpath=./libs/
libs+=$(libpath)liburlaes.a
libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a
cxx = g++
bin = encode
all: $(bin)
srcs = $(shell ls *.cc *.cpp)
objs = $(srcs:%.cc=%.o)
$(bin):${objs}
$(cxx) $(cflags) $(inc) -o $# ${objs} ${libs}
$(objs):%.o:%.cc
$(cxx) $(cflags) $(inc) -c -o $# $<
clean:
rm -f *.o
rm -f *.bak
rm -f $(bin)
The g++ compiler complains that:
g++ -Wall -O2 -fPIC -o encode encode.o ./libs/liburlaes.a ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a
./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&)':
url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
collect2: ld returned 1 exit status
But all these function are well defined in liburlaes.a as shown by nm -C
nm -C liburlaes.a | grep -i 'aes'
decode_byaes.o:
U AES_cbc_encrypt
U AES_set_decrypt_key
U AES_set_encrypt_key
00000060 T decode_byaes
00000000 T encode_byaes
00000110 T init_byaes_decrypt_key
000000c0 T init_byaes_encrypt_key
U decode_byaes
U encode_byaes
U init_byaes_decrypt_key
U init_byaes_encrypt_key
Things won't get better by moving the liburlaes.a to the end of libs, the output is exactly as above. And move libimageenc backward will make it worse, with more symbols claimed undefined:
libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a
libs+=$(libpath)liburlaes.a
So, how can I fix this?
UPDATES
I tried to put the liburlaes.a in both side, but it doesn't work, I wrap the libaray with '**' to emphasize :
g++ -Wall -O2 -fPIC -o encode encode.o **./libs/liburlaes.a** ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a **./libs/liburlaes.a**
./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int&)':
url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
collect2: ld returned 1 exit status
make: *** [encode] Error 1
Yes, the order of libraries definitely matter. You need to put whatever uses the library first, then the library.
I have had cases where library A depends on something in library B, and library B needs something in library A, so you then need to put library A twice in the list.
The way the linker works is that it processes the object files, then reads the libraries to resolve the symbols not present in the object files. If the library has the object "files" to solve the dependency, then those parts are included. It then goes on to the next library. It doesn't "remember" what it has seen in the previous libraries.
How about this,just put liburlaes.a right behind the liburldecode.a.
g++ -Wall -O2 -fPIC -o encode encode.o ./libs/liburldecode.a **./libs/liburlaes.a **./libs/libimageenc.a ./libs/libmbpicenc.a
I'm trying to compile the following c++ code that implements Context Tree Switching (More info on the download page):
Zip archive, 0.2 MB
which requires some boost libraries. I download the latest version from boost.org and built all libraries that needed building following the instructions on the website. I also modified the makefile included in the archive to add the boost lib path and boost_system, but I still get an error. Here's the makefile i'm using:
PROGRAM = cts
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
CFLAGS = -Wall
LDFLAGS = -lboost_program_options -lboost_filesystem -lboost_system
$(PROGRAM): $(OBJECTS) Makefile
g++ $(CFLAGS) -L/home/users/mnembrini/opt/boost/lib $(LDFLAGS) -o $(PROGRAM) $(OBJECTS)
# Include known dependecies from -MMD
#-include $(OBJECTS:.o=.d)
%.o: %.cpp
g++ -MMD $(CFLAGS) -I/home/users/mnembrini/opt/boost/include -c $<
clean:
rm -f $(OBJECTS) *.d
.PHONY: clean
where boost is in ~/opt/boost (constains lib and include subdir). And here's the linking error:
mnembrini#meem:~/src/cts-v1 $ make
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c ac.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c cts.cpp
cts.cpp: In member function ‘virtual void SwitchingTree::update(bit_t)’:
cts.cpp:402:12: warning: variable ‘snc’ set but not used [-Wunused-but-set-variable]
cts.cpp: In member function ‘virtual double SwitchingTree::prob(bit_t)’:
cts.cpp:432:12: warning: variable ‘snc’ set but not used [-Wunused-but-set-variable]
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c ctw.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c icsilog.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c main.cpp
g++ -MMD -Wall -I/home/users/mnembrini/opt/boost/include -c PowFast.cpp
g++ -Wall -L/home/users/mnembrini/opt/boost/lib -lboost_program_options -lboost_filesystem -lboost_system -o cts ac.o cts.o ctw.o icsilog.o main.o PowFast.o
cts.o: In function `__static_initialization_and_destruction_0(int, int)':
cts.cpp:(.text+0x1743): undefined reference to `boost::system::generic_category()'
cts.cpp:(.text+0x174f): undefined reference to `boost::system::generic_category()'
cts.cpp:(.text+0x175b): undefined reference to `boost::system::system_category()'
ctw.o: In function `__static_initialization_and_destruction_0(int, int)':
ctw.cpp:(.text+0xfcf): undefined reference to `boost::system::generic_category()'
ctw.cpp:(.text+0xfdb): undefined reference to `boost::system::generic_category()'
ctw.cpp:(.text+0xfe7): undefined reference to `boost::system::system_category()'
main.o: In function `showHelp()':
main.cpp:(.text+0x1c): undefined reference to `boost::program_options::operator<<(std::basic_ostream<char, std::char_traits<char> >&, boost::program_options::options_description const&)'
main.o: In function `initOptions(int, char**, boost::program_options::variables_map&)':
main.cpp:(.text+0x10f): undefined reference to `boost::program_options::options_description::add_options()'
main.cpp:(.text+0x129): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, char const*)'
main.cpp:(.text+0x13e): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x153): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x166): undefined reference to `boost::program_options::options_description_easy_init::operator()(char const*, boost::program_options::value_semantic const*, char const*)'
main.cpp:(.text+0x1d6): undefined reference to `boost::program_options::store(boost::program_options::basic_parsed_options<char> const&, boost::program_options::variables_map&, bool)'
main.cpp:(.text+0x200): undefined reference to `boost::program_options::notify(boost::program_options::variables_map&)'
main.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x1f13): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x1f1f): undefined reference to `boost::system::generic_category()'
[snip (2-3 screens like above)]
collect2: ld returned 1 exit status
make: *** [cts] Error 1
I'm using Gcc 4.6.3 on Ubuntu 12.04 64bit.
Place all the libraries after all the object files within the command line. The order is important here, unlike on some other operating systems.
You need to (just like n.m earlier wrote) make sure you have the correct order of the linking.
Basically some implementations care about what order you link object but also libraries.
If you link a library that hasnt yet been referenced by previous code it will be discarded. I remember coming up with a solution to hack in different (versions of) libraries in a program by referencing the same symbol but in an object linked after the first one and then re-link another library version:
-lyourprojwantingv1 -llibraryofv1 -lyourprojwantingv2 -llibraryofv2
Personally i think this is all just madness! (All of it!)