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)
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.
Most helpful comment
As I read your question, I realized my problem.
Both the main _and_ the test cases need
#define CATCH_CONFIG_ENABLE_BENCHMARKINGin them. The main needs to know about the macros and associated function as well.Thanks.