Reputation: 148
I suppose my question is what is the correct way to statically link to Boost when creating an archive, when Boost is just compiled and stored in my home directory, not in the system? The idea behind creating my program as a library is that I will be able to redistribute the library file for others to link against in their programs.
I want to make a C++ library file I can link to on Linux. I don't really care if it's static or dynamic, but static might make it easier for me.
The issue I'm having is that the examples I find don't tell you how to link other libraries in your library. My library uses Boost, and I have built Boost but I don't have permission to move it outside my user area.
I've tried making a static archive like this:
Compiling the cpp files:
g++ -O3 -ffast-math -Wall -Wextra -g -I./ -I../../boost/ -c BuddyManager.cpp -o build/BuddyManager.o
Creating a static archive:
ar rcs build/libppmi.a ../../boost/lib/libboost_system.a build/Application.o build/DataBlock.o (etc with all my object files listed after)
But it gives undefined reference errors when I later link to the .a file I created.
I managed to create my library by building a shared library SO file on Mac, but on that system Boost was installed in the standard system location. When I built a shared library on Linux I got the error "hidden symbol `__dso_handle' in /usr/lib/crtbegin.o is referenced by DSO" and I often had problems with it not being able to find the Boost .SO files. I therefore decided to change to static linking.
The system is running on Scientific Linux SL release 5.3 (Boron) and I'm using gcc-4.6.2. However, I want this to be portable to pretty much all versions of GCC.
Thanks. If anything isn't clear or you want more details please ask.
undefined reference to `boost::thread::interrupt()'
boost/boost/thread/pthread/thread_data.hpp:247: undefined reference to `boost::this_thread::hiden::sleep_until(timespec const&)'
boost/boost/archive/detail/iserializer.hpp:158: undefined reference to `boost::archive::detail::basic_iserializer::~basic_iserializer()'
They all seem to be in Boost. It can't find the references that should be in the Boost archives.
ar rcs build/libppmi.a ../../boost/lib/libboost_system.a ../../boost/lib/libboost_iostreams.a ../../boost/lib/libboost_serialization.a ../../boost/lib/libboost_thread.a build/Application.o build/DataBlock.o build/Iteration.o build/Launcher.o build/Message.o build/Network.o build/Processes.o build/DataBlockManager.o build/Communicator.o build/NetworkServer.o build/NetworkClientSession.o build/NetworkMessage.o build/NetworkConnection.o build/Threadable.o build/BuddyManager.o
This works ok. It's when I use the archive it breaks. I have also tried extracting the .o files from the boost libraries but this gives other linker errors about pthread libraries.
Upvotes: 3
Views: 4272
Reputation: 171451
You're creating an archive of archives, but when the linker looks in an archive it expects object files. The linker will look in libppmi.a
and skip all the non-object files, including libboost_system.a
, because it doesn't know what to do with them, and so won't find any Boost symbols. You can confirm that by linking with -t
(if you're linking using gcc
or g++
then use -Wl,-t
to pass -t
through to the linker) which prints the name of each file as the linker processes it, and you'll see it doesn't process the nested archives.
If you want to include all the Boost code in your archive then you need to list the individual objects (either by referring to them directly where you built Boost or by extracting them from the Boost archives then adding them to your new archive.)
This works ok. It's when I use the archive it breaks.
Of course, all that does it create an archive containing the files you listed. Creating an archive just involves putting a load of separate files into one big file and you can put almsot any file type in there. It can't really go wrong, but that doesn't mean the result is correct or usable.
I have also tried extracting the .o files from the boost libraries but this gives other linker errors about pthread libraries.
That's the right approach, but you've hit a different problem, so solve that instead of giving up on the approach. If you're using Boost.Thread then you need to compile and link with -pthread
Upvotes: 1