Catch2: Adding benchmarking code linker fails

Created on 11 Aug 2019  路  4Comments  路  Source: catchorg/Catch2

I have a set of tests written that are working well. When I add benchmarking to these test cases I am no longer able to link my compiled test executable.

Undefined symbols for architecture x86_64:
  "Catch::Benchmark::Detail::analyse_samples(double, int, std::__1::__wrap_iter<double*>, std::__1::__wrap_iter<double*>)", referenced from:
      Catch::Benchmark::SampleAnalysis<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> > > Catch::Benchmark::Detail::analyse<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> >, std::__1::__wrap_iter<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> >*> >(Catch::IConfig const&, Catch::Benchmark::Environment<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> > >, std::__1::__wrap_iter<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> >*>, std::__1::__wrap_iter<std::__1::chrono::duration<double, std::__1::ratio<1l, 1000000000l> >*>) in test-jaccard.o
  "Catch::Benchmark::Detail::weighted_average_quantile(int, int, std::__1::__wrap_iter<double*>, std::__1::__wrap_iter<double*>)", referenced from:
      Catch::Benchmark::OutlierClassification Catch::Benchmark::Detail::classify_outliers<std::__1::__wrap_iter<double*> >(std::__1::__wrap_iter<double*>, std::__1::__wrap_iter<double*>) in test-jaccard.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
  • OS: MacOS 10.14.5
  • Compiler: GCC 4.2.1
  • Catch version: 2.9.1
Query

Most helpful comment

As I read your question, I realized my problem.

Both the main _and_ the test cases need #define CATCH_CONFIG_ENABLE_BENCHMARKING in them. The main needs to know about the macros and associated function as well.

Thanks.

All 4 comments

Are you building the whole library with that define?

I'm not sure what you mean.

I'm build a library, and I'm building a test executable with catch2.

I have a test_main.cpp that looks like this:

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

I then have my test cases that look like this:

#define CATCH_CONFIG_ENABLE_BENCHMARKING
#include "catch.hpp"
#include "text_algorithm.h"

using namespace text_algorithm;

SCENARIO ( "ngram will return a vector of tokens the size you request", "[ngram]") {
    GIVEN ( "a string") {
        string str = "aspirin";
        std::vector<string> sv;
        size_t sz, rtn_sz;

        WHEN ( "the requested size of the n-gram is 2") {
            sz = 2;
            rtn_sz = ngram(str, &sv, sz);

            THEN ( "the size of each token will be 2") {

                for (const string &c : sv) {
                    REQUIRE (c.size() == 2);
                }
            }
        }

        WHEN ("the requested size of the n-gram is larger than the string" ) {
            sz = str.size() + 1;
            rtn_sz = ngram(str, &sv, sz);

            THEN ("there will be no n-grams returned") {
                REQUIRE( rtn_sz == 0 );
                REQUIRE( sv.size() == 0 );
            }
        }
    }

    BENCHMARK("ngram size 2, string size 10") {
       string str = "0123456789";
       std::vector<string> sv;

       return ngram(str,&sv,2);
    };
};

SCENARIO ( "jaccard bi token will calculate a jaccard coefficient on two strings", "[jaccard]" ) {
    GIVEN ("two strings") {
        string source = "joshua";
        string cible = "josh";
        float score;

        WHEN ( "the coefficient is calculated" ) {
            score = jaccardBiTokens(source, cible);
            THEN ( "the score will be accurate") {
                REQUIRE ( score == (float)0.6 );
            }
        }
    }

    /*
    BENCHMARK("Jaccard BiToken") {

        string s1 = "Aspirin";
        string s2 = "Aspirina";

        return jaccardBiTokens(s1, s2);
    };
    */
};

The above code compiles, but doesn't link. When I comment out the benchmark code, it compiles and links.

As I read your question, I realized my problem.

Both the main _and_ the test cases need #define CATCH_CONFIG_ENABLE_BENCHMARKING in them. The main needs to know about the macros and associated function as well.

Thanks.

Yes. I also strongly recommend to add that define to _all_ TUs that include catch.hpp through your build system, to avoid potentials for ODR violations.

Was this page helpful?
0 / 5 - 0 ratings