[Boost.Test] duplicate symbol '_main' (manual test registration)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Boost.Test] duplicate symbol '_main' (manual test registration)

Boost - Users mailing list
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 <boost/test/unit_test.hpp>

#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(&register_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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [Boost.Test] duplicate symbol '_main' (manual test registration)

Boost - Users mailing list
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 <[hidden email]> 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 <boost/test/unit_test.hpp>

#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(&register_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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [Boost.Test] duplicate symbol '_main' (manual test registration)

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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_scenarios/shared_lib_customizations/entry_point.html

> 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_faq.html#boost_test.section_faq.how_to_set_up_a_cmake_project_us

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_variants.html#boost_test.usage_variants.shared_lib

Raffi

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users