[Boost.Test] duplicate symbol '_main' (manual test registration)
Hi all,
As the subject line suggests, I am attempting to manually employ a master
test suite that registers several sub test suites.
- Each subtest suite has its own header and translation unit.
- Each header has a public "init_test_suite()" method and several private
"test_case<number>()" methods, all of which are declared static. The public
method creates a test suite, adds all the test cases for that translation
unit, and adds the suite to the master test suite. This method is intended
to be called from main.cpp.
Here is a simplified version of my main.cpp:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_NO_MAIN
#include
Sorry, quick edit. The code snippet above has a typo: { #include "A.h" } should be { #include "A_T.h" } *- AJ* On Fri, Feb 28, 2020 at 10:44 PM Andrew McFarlane < andrew.mcfarlane52@gmail.com> wrote:
Hi all,
As the subject line suggests, I am attempting to manually employ a master test suite that registers several sub test suites.
- Each subtest suite has its own header and translation unit.
- Each header has a public "init_test_suite()" method and several private "test_case<number>()" methods, all of which are declared static. The public method creates a test suite, adds all the test cases for that translation unit, and adds the suite to the master test suite. This method is intended to be called from main.cpp.
Here is a simplified version of my main.cpp:
#define BOOST_TEST_DYN_LINK #define BOOST_TEST_NO_MAIN #include
#include "A.h" #include "B_T.h" #include "C_T.h"
bool register_test_suites() { A_T::init_test_suite(); B_T::init_test_suite(); C_T::init_test_suite(); return 0; }
int main(int argc, char *argv[], char *envp[]) { return boost::unit_test::unit_test_main(®ister_test_suites, argc, argv); }
Here's the issue. Despite the fact that I have defined BOOST_TEST_NO_MAIN, it appears that my compiler is still generating 2 objects files for the main executable entry:
duplicate symbol 'register_test_suites()' in:
/var/folders/bc/v2yqpsf96kn31tx8ybvy9gyw0000gn/T/main-58c6b3.o
bin/main.o
duplicate symbol '_main' in:
/var/folders/bc/v2yqpsf96kn31tx8ybvy9gyw0000gn/T/main-58c6b3.o
bin/main.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [execs/main] Error 1
As you might be wondering, all of my test translation units define BOOST_TEST_DYN_LINK, and none of them define BOOST_TEST_MODULE, as the documentation suggests.
I tried removing BOOST_TEST_NO_MAIN from main.cpp but that did not appear to do anything.
I also tried removing the static and shared Boost.Unit lib files from my stage/lib directory and rebuilding only the shared version, and that did not work either.
Also not that my g++ command does have the expected -L and -l flags for linking with Boost.Test:
-L/usr/local/boost_1_72_0/stage/lib -lboost_unit_test_framework
I am lost here. No idea why main() is being defined twice.
Thanks in advance.
- AJ
On 29.02.20 07:44, Andrew McFarlane via Boost-users wrote:
Hi all,
[snip]
Here's the issue. Despite the fact that I have defined BOOST_TEST_NO_MAIN, it appears that my compiler is still generating 2 objects files for the main executable entry:
Sorry for the late reply, I am not often on this list.
As you might be wondering, all of my test translation units define BOOST_TEST_DYN_LINK, and none of them define BOOST_TEST_MODULE, as the documentation suggests.
The documentation does not exactly say that: * BOOST_TEST_MODULE should be defined in one translation unit only * BOOST_TEST_DYN_LINK should be defined in all translation units See here: https://www.boost.org/doc/libs/1_72_0/libs/test/doc/html/boost_test/adv_scen...
I tried removing BOOST_TEST_NO_MAIN from main.cpp but that did not appear to do anything.
BOOST_TEST_NO_MAIN has effect only together with BOOST_TEST_MAIN (or BOOST_TEST_MODULE) and BOOST_TEST_DYN_LINK. The static version of boost.test has already a "main" defined. The duplicate "main" can come from a wrong linking ("-lboost_unit_test_framework" on the link line may choose the static version) or a duplicate "main" in your translation units. Since compilation is always an issue in the C++ world, I wrote this some time ago: https://www.boost.org/doc/libs/1_72_0/libs/test/doc/html/boost_test/section_... Using a tool like CMake may make your life easier.
I also tried removing the static and shared Boost.Unit lib files from my stage/lib directory and rebuilding only the shared version, and that did not work either.
Also not that my g++ command does have the expected -L and -l flags for linking with Boost.Test:
-L/usr/local/boost_1_72_0/stage/lib -lboost_unit_test_framework
I would rather help you out using the automatic registration. It should support all the scenarios that you mentioned in another thread on this list. It should be only a matter of doing this: https://www.boost.org/doc/libs/1_72_0/libs/test/doc/html/boost_test/usage_va... Raffi
participants (2)
-
Andrew McFarlane
-
Raffi Enficiaud