3

I'm currently attempting to use the Catch testing framework. I'm using cmake to build my project and currently I just glob all the .h and .c files together. For testing purposes I took out my actual "main" and replaced it with the Catch's sample factorial example. I have two files:

// testmain.cpp

#define CATCH_CONFIG_MAIN

#include <catch2/catch.hpp>

and

//test.cpp

#include "catch2/catch.hpp"


int Factorial( int number ) {
    return number <= 1 ? number : Factorial( number - 1 ) * number;  // fail
  // return number <= 1 ? 1      : Factorial( number - 1 ) * number;  // pass
}

TEST_CASE( "Factorial of 0 is 1 (fail)", "[single-file]" ) {
 REQUIRE( Factorial(0) == 1 );
}

TEST_CASE( "Factorials of 1 and higher are computed (pass)", "[single-file]" ) {
 REQUIRE( Factorial(1) == 1 );
 REQUIRE( Factorial(2) == 2 );
 REQUIRE( Factorial(3) == 6 );
 REQUIRE( Factorial(10) == 3628800 );
}

Now whats happening is that it spends 3 seconds building and 1 minute linking. After everything links (1+ minutes), i get the test results. I followed both tutorials below which mention to keep these two files separate.

I read the Catch tutorial: https://github.com/catchorg/Catch2/blob/master/docs/tutorial.md

and

the "slow compile" wiki page: https://github.com/catchorg/Catch2/blob/master/docs/slow-compiles.md

I'm not quite sure why the linking is taking so long. Has anyone run into issues like this?

update:

More info on my environment:

  • cmake 3.14.0-rc1

  • g++ 8.1.0

efel
  • 1,054
  • 3
  • 14
  • 29
  • No linking issues here. g++ 8.3.1 – Michael Surette Mar 12 '19 at 02:23
  • hmm i'm using g++ 8.1.0 mingw. I wonder if that is causing the slowness. – efel Mar 12 '19 at 02:40
  • The only speed issue I ever had was as described on the `slow compile` wiki page. I've been using Catch for at least a year with no other speed issues. I've had regular g++ upgrades (OpenSuse Tumbleweed rolling distro) – Michael Surette Mar 12 '19 at 02:59
  • It seems this maybe a cmake issue? Whenever i turn off debug and enable release, it links extremely fast... Need more investigation though. – efel Mar 12 '19 at 03:50
  • apparently this is a known issue for mingw and catch: https://github.com/catchorg/Catch2/issues/1205 – efel Mar 12 '19 at 10:58
  • There's another possibility.. Maybe you're building the catch main as a static library, not a shared one? Then the linkage time is indeed very long. – RL-S Jul 03 '20 at 08:38

2 Answers2

4

So judging by this known issue:

github.com/catchorg/Catch2/issues/1205

Mingw is really bad with link time optimization. However; I stumbled upon a solution that works for me. Setting the cmake build type to

RELWITHDEBINFO

seems to speed the linking up by a factor 10.

efel
  • 1,054
  • 3
  • 14
  • 29
  • 3
    Yeah, MinGW's linker is old and performs badly when there are many symbols to link -- Catch2 happens to generate _a lot_ of symbols that need linking. – Xarn Mar 28 '19 at 10:08
0

In addition to already proposed solution from efel I will add my solution, which helps me to improve link times by ~10x. Its almost the solution from efel, but since I'm not using cmake, I directly used the code optimization flag from the compiler. So you need just to do this:

-O1

I also tried -O3, but then some of my test variables were optimized out and lead to segfaults. Yes, I could add code that prevents the optimization, but for now this -O1 is ok for me.

buildhome.eu
  • 1,434
  • 1
  • 10
  • 4