Boost.Test multiple linkage question
All, I've been ripping out my hair all day, and I can't seem to determine a straight answer from the Googles. Can I link _multiple_ boost unit test dynamic libraries into a single binary and have all of them detected? For instance... src lib liba foo.cpp liba_unittests.cpp libb bar.cpp libb_unittests.cpp libd baz.cpp libd_unittests.cpp lib liba.so liba_ut.so libb.so libb_ut.so libd.so libd_ut.so bin ut unittest_driver When I build this infrastructure out, everything compiles. I've checked the compilation command and it looks like everything is on the command line, but there's explicit indication that unittest_driver actually read or linked any of the lib*_ut.so files. If I make individual unit test drivers in, say, liba, the driver works fine. If I link everything into a single unittest_driver binary, I keep getting the dreaded empty test tree. I have -DBOOST_ALL_DYN_LINK set in my CXXFLAGS so that shouldn't be the problem. And I only have BOOST_TEST_MAIN set in the driver; still no joy. Any help (or a definitive, "no you idiot, you can't do that!") would be greatly appreciated. Thanks. -RMH
[Please do not mail me a copy of your followup]
Rob Harris
Can I link _multiple_ boost unit test dynamic libraries into a single binary and have all of them detected?
Having all of them detected is the tricky part because "detection" relies on static constructors registering the test cases. That means that you need the static constructors in the shared objects to execute properly w.r.t. the test framework's static constructors.
For instance...
src lib liba foo.cpp liba_unittests.cpp libb bar.cpp libb_unittests.cpp libd baz.cpp libd_unittests.cpp lib liba.so liba_ut.so libb.so libb_ut.so libd.so libd_ut.so bin ut unittest_driver
When I build this infrastructure out, everything compiles. I've checked the compilation command and it looks like everything is on the command line, but there's explicit indication that unittest_driver actually read or linked any of the lib*_ut.so files.
If I make individual unit test drivers in, say, liba, the driver works fine.
If I link everything into a single unittest_driver binary, I keep getting the dreaded empty test tree.
This implies that when you run the test driver, the constructors for global static objects in your shared objects haven't run and the test cases haven't been registered.
Any help (or a definitive, "no you idiot, you can't do that!") would be greatly appreciated. Thanks.
I don't think it's a case of "you can't do that", so much as orchestrating the machinery properly. For instance, if each shared library had an exported function that manually registered the test cases/suites in each shared library, and that exported function were called explicitly from the driver executable before the tests were run, then everything would probably work fine. (I haven't tried this.) However, this means writing a bunch of manual registration code. This code is boring to write and tedious to maintain. Otherwise you have to orchestrate the machinery in the right order for things to work with automatic registration. When all the tests are compiled into the test executable staticly, this works just fine. The dynamic linking support was so that you didn't need to relink against the test framework every time you relinked your test executable. The simplest thing that's going to get everything right is to leave production code in the shared objects (liba.so:foo.cpp, libb.so:bar.cpp, libd.so:baz.cpp) and leave all the test code staticly linked to the executable (libtesta.a: liba_unittests.cpp, etc.). You can still use dynamic linking for the unit test framework, but this way all your test case registration happens properly before main since all the static constructors will already have run. -- "The Direct3D Graphics Pipeline" free book http://tinyurl.com/d3d-pipeline The Computer Graphics Museum http://computergraphicsmuseum.org The Terminals Wiki http://terminals.classiccmp.org Legalize Adulthood! (my blog) http://legalizeadulthood.wordpress.com
participants (2)
-
legalize+jeeves@mail.xmission.com
-
Rob Harris