The direct answer to my question is in the --[no-]allow-shlib-undefined
option to ld, I think. From the man page:
The default behaviour is to report errors for any undefined symbols referenced in shared libraries if the linker is being used to create an executable, but to allow them if the linker is being used to create a shared library.
Therefore, when I build with -shared
, the symbols in boost_system are undefined, but the default behaviour of ld is not to care. It can be told to care:
$ g++ -fPIC -shared -Wl,--no-allow-shlib-undefined -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc6j1de3.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Similarly, we can tell it not to care when building an executable:
$ g++ -Wl,--allow-shlib-undefined -o test test.cc -lboost_timer
/tmp/ccUHoCIU.o: In function `__static_initialization_and_destruction_0(int, int)':
test.cc:(.text+0x7a): undefined reference to `boost::system::generic_category()'
test.cc:(.text+0x86): undefined reference to `boost::system::generic_category()'
test.cc:(.text+0x92): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
But creating the binary fails without being able to define those symbols.
Thanks @CharlesBailey for pointing me in the right direction!