Failure linking when using an extra library - c++

When I build a simple C++ program with glog library (Google's logging library which is not used in the code), I get "undefined reference" errors. When I remove the -lglog from the build command, the link succeeds.
Notice that the library that I added to the link is not used in the code at all and despite that it caused the build to fail. In addition, the glog and log4cpp libraries are supposed to be independent.
Can you explain this unusual behavior?
Environment: Ubuntu 14.04
Code:
//test.cpp
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
int main() {
log4cpp::Appender *appender;
appender = new log4cpp::FileAppender("default", "program.log");
return 0;
}
Working build command:
$ g++ test.cpp -llog4cpp -lpthread
Failing build command:
$ g++ test.cpp -llog4cpp -lglog -lpthread
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_key_create'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_getspecific'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_key_delete'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_setspecific'
collect2: error: ld returned 1 exit status
EDIT:
This command also builds successfully:
g++ test.cpp -llog4cpp -lpthread -lglog
This command fails (change the order of libs):
$ g++ test.cpp -llog4cpp -lglog -lpthread
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_key_create'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_getspecific'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_key_delete'
//usr/local/lib/liblog4cpp.so: undefined reference to `pthread_setspecific'
collect2: error: ld returned 1 exit status
This succeeds:
$ g++ test.cpp -pthread -llog4cpp
This fails:
$ g++ test.cpp -pthread -llog4cpp -lglog
EDIT 2:
I studied the duplicate suggestions (1) and (2) to find out maybe there's something useful to me there, but it turned out irrelevant because these cases doesn't address the situation where a library that is not used in the code is added to the link and make it fail.
EDIT 3:
The files from my environment (glog libs, log4cpp libs, used log4cpp headers and test.cpp): log_test.zip.

Related

What's the differece between of link to a dynamic file and as a input object?

I use g++ to link my project (an executable mono_kitti) and my project is dependent on a thirdparty library Pangolin. When I do the link action with -lpangolin option:
g++ -L../../lib -lORB_SLAM2 -lpangolin mono_kitti.o -o mono_kitti
it returns:
mono_kitti.o:(.data+0x0): undefined reference to `vtable for pangolin::Handler'
mono_kitti.o:(.data+0x8): undefined reference to `vtable for pangolin::HandlerScroll'
mono_kitti.o: In function `pangolin::Handler::~Handler()':
mono_kitti.cc:(.text._ZN8pangolin7HandlerD2Ev[_ZN8pangolin7HandlerD5Ev]+0x13): undefined reference to `vtable for pangolin::Handler'
mono_kitti.o: In function `pangolin::HandlerScroll::~HandlerScroll()':
mono_kitti.cc:(.text._ZN8pangolin13HandlerScrollD2Ev[_ZN8pangolin13HandlerScrollD5Ev]+0x13): undefined reference to `vtable for pangolin::HandlerScroll'
collect2: error: ld returned 1 exit status
But When I use this command:
g++ -L../../lib -lORB_SLAM2 mono_kitti.o /usr/local/lib/libpangolin.so -o mono_kitti
it succeeded.
But it failed again when I tried to swap the order of them:
g++ -L../../lib -lORB_SLAM2 /usr/local/lib/libpangolin.so mono_kitti.o -o mono_kitti
and returns things identical with the first case above (-lpangolin option).
I'm very confused about these results, could someone can explain the differece between them? Many thanks!
When the linker sees the library (the -lpangolin option in your case), it doesn't yet have any unresolved references to that library, so it discards it.
If you put the object file before the library, so your command line look like e.g.
g++ mono_kitti.o -L../../lib -lORB_SLAM2 -lpangolin -o mono_kitti
Then the linker have all the unresolved references from mono_kitti.o and will pull them from the libraries.

Netbeans : Adding "Compile Line - Additional Options" "-lboost_system" at the end of compile command

I am using Netbeans as IDE and have been trying to build a piece of code which uses boost library, but I am getting below error
g++ -c -g -MMD -MP -MF "build/Debug/GNU-Linux-x86/tcpproxy_server.o.d" -o build/Debug/GNU-Linux-x86/tcpproxy_server.o tcpproxy_server.cpp
mkdir -p dist/Debug/GNU-Linux-x86
g++ -o dist/Debug/GNU-Linux-x86/tcp_proxy build/Debug/GNU-Linux-x86/tcpproxy_server.o
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function __static_initialization_and_destruction_0(int, int)':
/usr/include/boost/system/error_code.hpp:221: undefined reference toboost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:222: undefined reference to boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:223: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::system::error_code::error_code()':
/usr/include/boost/system/error_code.hpp:322: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::asio::error::get_system_category()':
/usr/include/boost/asio/error.hpp:230: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::thread_exception::thread_exception(int, char const*)':
/usr/include/boost/thread/exceptions.hpp:51: undefined reference toboost::system::system_category()'
collect2: error: ld returned 1 exit status
So I did some online search for error and found out that I have to add "-lboost_system" in my compile command.
I added it in "project->properties->build->c++ compiler-> Additional Options" but still the same error.
g++ -lboost_system -o dist/Debug/GNU-Linux-x86/tcp_proxy build/Debug/GNU-Linux-x86/tcpproxy_server.o
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function __static_initialization_and_destruction_0(int, int)':
/usr/include/boost/system/error_code.hpp:221: undefined reference toboost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:222: undefined reference to boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:223: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::system::error_code::error_code()':
/usr/include/boost/system/error_code.hpp:322: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::asio::error::get_system_category()':
/usr/include/boost/asio/error.hpp:230: undefined reference toboost::system::system_category()'
build/Debug/GNU-Linux-x86/tcpproxy_server.o: In function boost::thread_exception::thread_exception(int, char const*)':
/usr/include/boost/thread/exceptions.hpp:51: undefined reference toboost::system::system_category()'
collect2: error: ld returned 1 exit status
I found out that I have to add it in the end of compile line, for example :
"g++ tcp_proxy.cpp -o tcpproxy -lboost_system"
This I tried and its working, but netbeans is adding "Addition Options" at the start
like:
g++ -lboost_system -o dist/Debug/GNU-Linux-x86/tcp_proxy build/Debug/GNU-Linux-x86/tcpproxy_server.o
Is there any way I can configure netbeans to add my option in end ?
So, I did some more search and found a question with somewhat my problem
link to the post :
C++ Boost on linux via Netbeans remote developement: undefined reference to boost::filesystem::path::codecvt()
This says that I can use following way to link a library:
Project Properties > Linker > Libraries > Add Library > Select the .a files.
This somewhat solves my issue, I am getting success with this try now:
g++ -c -g -MMD -MP -MF "build/Debug/GNU-Linux-x86/tcpproxy_server.o.d" -o build/Debug/GNU-Linux-x86/tcpproxy_server.o tcpproxy_server.cpp
mkdir -p dist/Debug/GNU-Linux-x86
g++ -o dist/Debug/GNU-Linux-x86/tcp_proxy build/Debug/GNU-Linux-x86/tcpproxy_server.o -lboost_system
But I am still not sure If this is the right approach OR why adding it in addition compiler options not working.

Linking libcurl while cross compiling with mingw32 under Linux for Windows

I have compiled libcurl using mingw32 and am trying to link it with my program using mingw32 for a Windows system from my Linux machine.
I was outputted the files, libcurl-4.dll libcurl.a libcurl.la libcurl.lai.
I have included them in my mingw32 libs folder at: /usr/x86_64-w64-mingw32/lib
I was able to find a few other topics on linking with the libstdc++ and libgcc to take care dependency errors while executed but when trying to add libcurl.a it will not compile period.
I used the following:
$ x86_64-w64-mingw32-g++ main.cpp -o hello.exe -static-libgcc -static-libstdc++ -static "/usr/x86_64-w64-mingw32/lib/libcurl.a" -lpthread
However, I cannot not get it to use the libcurl.a and am continuing to receive these errors.
/tmp/ccIceRus.o:main.cpp:(.text+0xde): undefined reference to `__imp_curl_easy_init'
/tmp/ccIceRus.o:main.cpp:(.text+0x106): undefined reference to `__imp_curl_easy_setopt'
/tmp/ccIceRus.o:main.cpp:(.text+0x122): undefined reference to `__imp_curl_easy_setopt'
/tmp/ccIceRus.o:main.cpp:(.text+0x13e): undefined reference to `__imp_curl_easy_setopt'
/tmp/ccIceRus.o:main.cpp:(.text+0x159): undefined reference to `__imp_curl_easy_setopt'
/tmp/ccIceRus.o:main.cpp:(.text+0x169): undefined reference to `__imp_curl_easy_perform'
/tmp/ccIceRus.o:main.cpp:(.text+0x180): undefined reference to `__imp_curl_easy_strerror'
/tmp/ccIceRus.o:main.cpp:(.text+0x197): undefined reference to `__imp_curl_easy_cleanup'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccIceRus.o: bad reloc address 0x80 in section `.xdata'
collect2: error: ld returned 1 exit status
What am I doing wrong?. I can not get past this. I know it has to be some stupid issue.
Thank you.
I was able to solve the question by specifying -DCURL_STATICLIB, as well as linking some other dependencies.
x86_64-w64-mingw32-g++ main.cpp -o hello.exe -DCURL_STATICLIB -static -lstdc++ -lgcc -lpthread -lcurl -lwldap32 -lws2_32

Can we put two files with main() in makefile?

I have client server code client.cpp and server.cpp both with main().
Server need to be executed first and remain alive till not uninterrupted.
server.cpp includes two cpp files that I have created:
#include "serverFunction.cpp"
#include "serverFunction2.cpp"
Both of this also include serverFunction.h .
How to write makefile for this? I have used pthread so -lpthread at the end.
Individually I compile in this manner:
g++ -o a LinServer.cpp -lpthread
I tried with this:
all: LinServer LinClient
LinServer:
g++ -o a LinServer.cpp -pthread
LinClient:
g++ -o b LinClient.cpp -pthread
But it gives this error:
LinServer.o: In function `main':
LinServer.cpp:(.text+0x6dd): undefined reference to `pthread_create'
LinServer.cpp:(.text+0x6e9): undefined reference to `pthread_detach'
LinServer.o: In function `__static_initialization_and_destruction_0(int, int)':
LinServer.cpp:(.text+0xb3e): undefined reference to `std::ios_base::Init::Init()'
LinServer.cpp:(.text+0xb55): undefined reference to `std::ios_base::Init::~Init()'
LinServer.o:(.eh_frame+0x7b): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
make: *** [LinServer] Error 1
You have specified the library incorrectly:
g++ -o a LinServer.cpp -pthread
It should be -lpthread, not -pthread (the -l option means compiling with library).
Your problems are not related with having two main() functions, but the answer is - yes, you can compile two files with main() function in the same Makefile, but only if the files belongs to different output files (different binaries).
Your error messages look like there is something wrong with your linker settings or with your configuration of standard C++ library (the linker seems unable to see it).

Boost.Asio installation issue

i have already installed boost libraries with bjam install, but when i'm compiling programme:
#include boost/asio.hpp
int main()
{
return 0;
}
such errors occur:
/tmp/ccVR3eeF.o: In function `__static_initialization_and_destruction_0(int, int)':
sda.cpp:(.text+0x52): undefined reference to `boost::system::generic_category()'
sda.cpp:(.text+0x5e): undefined reference to `boost::system::generic_category()'
sda.cpp:(.text+0x6a): undefined reference to `boost::system::system_category()'
/tmp/ccVR3eeF.o: In function `boost::asio::error::get_system_category()':
sda.cpp:(.text._ZN5boost4asio5error19get_system_categoryEv[boost::asio::error::get_system_category()]+0x5): undefined reference to `boost::system::system_category()'
/tmp/ccVR3eeF.o: In function `boost::asio::detail::posix_tss_ptr_create(unsigned int&)':
sda.cpp:(.text._ZN5boost4asio6detail20posix_tss_ptr_createERj[boost::asio::detail::posix_tss_ptr_create(unsigned int&)]+0x19): undefined reference to `pthread_key_create'
/tmp/ccVR3eeF.o: In function `boost::asio::detail::posix_tss_ptr<boost::asio::detail::call_stack<boost::asio::detail::task_io_service>::context>::~posix_tss_ptr()':
sda.cpp:(.text._ZN5boost4asio6detail13posix_tss_ptrINS1_10call_stackINS1_15task_io_serviceEE7contextEED2Ev[boost::asio::detail::posix_tss_ptr<boost::asio::detail::call_stack<boost::asio::detail::task_io_service>::context>::~posix_tss_ptr()]+0x15): undefined reference to `pthread_key_delete'
/tmp/ccVR3eeF.o: In function `boost::asio::detail::posix_tss_ptr<boost::asio::detail::call_stack<boost::asio::detail::strand_service::strand_impl>::context>::~posix_tss_ptr()':
sda.cpp:(.text._ZN5boost4asio6detail13posix_tss_ptrINS1_10call_stackINS1_14strand_service11strand_implEE7contextEED2Ev[boost::asio::detail::posix_tss_ptr<boost::asio::detail::call_stack<boost::asio::detail::strand_service::strand_impl>::context>::~posix_tss_ptr()]+0x15): undefined reference to `pthread_key_delete'
collect2: ld returned 1 exit status
what do i have to do? how can i build those libraries?
Boost.Asio requires the Boost.System library as well; you need to add -lboost_system to your linker command line.
As you add features to your program, you might also need other parts of Boost, like Boost.Thread, Boost.Date_Time, and so on. See http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/using.html for details.
I use netbeans so i typed '-lboost_system' in additional lines ! That was a mistake.
Additional lines are put before objects, and because of that i had the same error. Then i found out if i run from console and put -lboost_system at the VERY END everything works greate. At the end i found the right place to set in netbeans (in library not command section) and that field adds it at the end!
Remember, not only counts if you have the library in command ! THE POSITION does count :) Remember to put library at end and verify it :)
Work great:
g++.exe -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS -c -g -MMD -MP -MF async_client.o.d -o async_client.o async_client.cpp
g++.exe -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS -o async_client async_client.o -lws2_32 -lboost_chrono -lboost_system -lboost_thread
Doesn't work:
g++.exe -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS -c -g -MMD -MP -MF async_client.o.d -o async_client.o async_client.cpp
g++.exe -D_WIN32_WINNT=0x0501 -D__USE_W32_SOCKETS -lws2_32 -lboost_chrono -lboost_system -lboost_thread -o async_client async_client.o