tags:

views:

282

answers:

3

I'm trying to create a shared object (.so) that will make it so, by including one shared object with -lboost, I implicitly include all the boost libraries. Here's what I tried:

#!/bin/sh
BOOST_LIBS="-lboost_date_time-gcc43-mt -lboost_filesystem-gcc43-mt"
  #truncated for brevity
g++ $BOOST_LIBS -shared -Wl,-soname,libboost.so.1 -o libboost.so.1.0
ln -si libboost.so.1.0 libboost.so.1
ln -si libboost.so.1 libboost.so

After placing all 3 created files (libboost.so libboost.so.1 libboost.so.1.0) in the same directory as all the boost libraries, I tried compiling a test program with it (which depends on -lboost_date_time-gcc43-mt):

g++ -lboost test.cpp

Doing this, I got the same undefined reference message as not having -lboost. Having -lboost_date_time-gcc43-mt works, but that's too wordy :) How do I get -lboost to automatically bring in the other shared libraries?

+1  A: 

You don't. Not really, anyway.

The linker is stripping out all of the symbol dependencies because the .so doesn't use them.

You can get around this, perhaps, by writing a linker script that declares all of the symbols you need as EXTERN() dependencies. But this implies that you'll need to list all of the mangled names for the symbols you need. Not at all worth the effort, IMO.

greyfade
Ah, so I guess I'd have to write some code that references every single symbol in the dependencies or, rather, use a sane approach that doesn't strip the dependencies? Or is creating dummy .so's practically impossible?
Joey Adams
Edited.
greyfade
Okay, thanks. I suppose I'll just set up a convenient environment variable to drop in when building: g++ $lboost alive.cpp
Joey Adams
If you're not already using Makefiles, you should. You might also want to consider using an auto-configure tool. It'll make developing lots easier.
greyfade
+1  A: 

I don't have a solution for creating a dummy '.so', but I do have something that will simplify your life... I highly suggest that you try using cross-platform make (CMake). In CMake, linking against those libraries is easy:

FIND_PACKAGE(Boost 1.37 COMPONENTS date_time filesystem REQUIRED)
ADD_EXECUTABLE(myexecutable ${myexecutable_SRCS}) 
TARGET_LINK_LIBRARIES(myexecutable ${Boost_LIBRARIES}) 

The commands above, if placed in a "CMakeLists.txt" file, is all you need to:

  1. Verify that Boost 1.37 or later is installed, with the "date_time" and "filesystem" libraries installed.
  2. Create an executable named "myexecutable" from the sources listed in the corresponding variable.
  3. Link the executable "myexecutable" against the boost "date_time" and "filesystem" libraries.

See also: Why the KDE project switched to CMake.

Michael Aaron Safyan
+1  A: 

Actually, making one .so depend on all boost .so files is quite possible (but might not actually help you). I've just tried this:

$ export BOOST_ROOT=/home/ghost/Work/Boost/boost-svn
$ g++ -shared -Wl,-soname,libboost.so -o libboost.so $BOOST_ROOT/stage/lib/libboost_program_options.so
$ g++ -L . -I $BOOST_ROOT first.cpp -lboost -Wl,-R$BOOST_ROOT/stage/lib
$ LD_LIBRARY_PATH=.:$BOOST_ROOT/stage/lib ./a.out

And it did work. However, note that dancing with -R and LD_LIBRARY_PATH. I don't know an way how you can include the path to Boost .so inside your libboost.so so that they are used both for linking and actually running the application. I can include rpath inside libboost.so just fine, but it's ignored when resolving symbols for the application.

Vladimir Prus