tut-framework icon indicating copy to clipboard operation
tut-framework copied to clipboard

A group per source file

Open jbakosi opened this issue 6 years ago • 2 comments

I'd like to create one test group per source file, however, tests do not run when the runner is statically linked.

Minimal example:

m1.C

#include <iostream>
#include <tut/tut.hpp>

namespace tut 
{
    struct group1{};
    
    typedef test_group<group1> tg;
    tg test_group_1("module 1: group 1");
    typedef tg::object testobject;
    
    template<> template<>
    void testobject::test<1>()
    {
        set_test_name("module 1, group 1, test 1");
        std::cout << "module 1, group 1, test 1\n";
    }
}

m2.C

#include <iostream>
#include "tut/tut.hpp"

namespace tut 
{ 
    struct group2{};
    
    typedef test_group<group2> tg;
    tg test_group_2("module 2: group 2");
    typedef tg::object testobject;
    
    template<> template<>
    void testobject::test<1>()
    {
        set_test_name("module 2, group 2, test 1");
        std::cout << "module 2, group 2, test 1\n";
    }
}

main.C

#include <tut/tut.hpp>

namespace tut
{
    test_runner_singleton runner;
}

int main()
{
    tut::runner.get().run_tests();
    return 0;
}

Build shared works:

$ gcc -I. -c m1.C
$ gcc -I. -c m2.C
$ g++ -I. -c main.C
$ g++ -o test main.o m1.o m2.o
$ file ./test
./test: ELF 64-bit LSB pie executable x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d620007974a67f95c4b486b862718c9433670b06, not stripped
$ ./test
module 1, group 1, test 1
module 2, group 2, test 1

Build static runs no tests:

$ gcc -I. -c m1.C
$ gcc -I. -c m2.C
$ g++ -I. -c main.C
$ ar rcs libm1.a m1.o
$ ar rcs libm2.a m2.o
$ g++ -static main.C -I. -L. -lm1 -lm2 -o test-static
$ file ./test-static 
./test-static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=cf4782d823ae547ecdccd3ce39f20e5bc1a7edff, not stripped
$ ./test-static
$

As shown above, linking statically does not run the tests. This is probably not a TUT issue, and I'm probably not using this correctly. Does this have something to do with the static test_runner_singleton? I tried pulling in the runner from main.C into m1.C and m2.C as extern but without luck. How do I ensure that tests defined in different compilation units register with the same runner that's (potentially) defined in another file? (And why does it register with the correct runner linking dynamically, but not statically?)

jbakosi avatar Jul 24 '18 03:07 jbakosi

Here is a link line that works with static linking:

g++ -static main.o m1.o m2.o -I. -L. -o test-static

I guess when ALL objects, that reference the runner, are visible to the linker in a single command, instead of going through intermediate .a archives, it finds the correct global runner. If anyone finds this and interested in the change this entails in a larger code, see https://github.com/quinoacomputing/quinoa/pull/257.

jbakosi avatar Jul 24 '18 23:07 jbakosi

Try linking the .a using --whole-archive

mrzechonek avatar Feb 02 '19 18:02 mrzechonek