doctest: Doctest is not able to compile on OSX

Description

I am trying to get my Travis CI build working with doctest (I’m switching from Catch to this for performance), but my build is not working on OSX (It is for Linux). In my Travis CI logs, I see the following error:

Undefined symbols for architecture x86_64:
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      doctest::String doctest::detail::stringifyBinaryExpr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char [6]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*, char const (&) [6]) in hello_world_test.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [test/test_runner] Error 1
make[1]: *** [test/CMakeFiles/test_runner.dir/all] Error 2
make: *** [all] Error 2

Steps to reproduce

I’m using CMake, and my invocation command is:

cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=$COMPILER -DBUILD_TESTS=ON ..

(COMPILER is set to clang++ and BUILD_TYPE is set to Debug and Release, both of which fail)

The CMake configuration I am using is (for flags):

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    # ...
endif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

And the test configuration:

set(TEST_SOURCES
    factorial_test.cpp
    hello_world_test.cpp
)

add_library(doctest INTERFACE)
target_include_directories(doctest INTERFACE 
    "${CMAKE_SOURCE_DIR}/third_party/doctest" # Contains single header
)

add_executable(test_runner test_runner.cpp ${TEST_SOURCES})
target_link_libraries(test_runner Project-Name-lib doctest)

add_test(all_tests test_runner)

Extra information

  • doctest version: v1.2.8
  • Operating System: Travis CI OSX XCode image 9.2
  • Compiler+version: AppleClang 9.0.0.9000039

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 23 (10 by maintainers)

Commits related to this issue

Most upvoted comments

@arnavb finally resolved “properly” - turns out the problem is this: when using clang from xcode - that means libc++. in that case I include <iosfwd> instead of forward-declaring std::ostream myself. Then if the user includes somewhere only the doctest header and <string> and then does a comparison - then and only then will there be some linker issue which we resolved by including <iostream> in the tests. This is a toolchain issue when using the <iosfwd> header - the details are still not clear to me but I managed to get the linker to pull in what is necessary by adding a dummy unused global function in the implementation of doctest that uses operator<< of std::string to print to std::cout.

the <iostream> header should no longer be necessary - try the version of the header from the dev branch (soon to be released in master as version 2.0!)

Gosh… I’ll find a way to “fix” it - perhaps either with some magic attribute to that function or by calling it somewhere within doctest (after making it noinline so it doesn’t get inlined and optimized out)

@onqtam You’re right. I added <iostream> and it works! (Finally). However, this solution is ugly on more than one level. <string> is supposed to have a complete version of std::string since that’s what the header is for! Why is <iostream>, which only probably including <string> itself, solving a LINKING PROBLEM while the header that implements std::string isn’t? 😶

😖

On a side note…

I really want to thank you for all of your help with this issue! I know it must be hard to take time out of your busy schedule as you mentioned before to help a problem that as we found out isn’t even caused by doctest! Many others would just reject people with such problems and I appreciate your help as such. Thanks again!

I’m going to enjoy using doctest (especially the performance boost 😛) and will definitely recommend it to others.

@onqtam Ok Update. I’ve created another repository in which I’m trying to use doctest on OSX, and … it works fine! Now I have to figure out the difference between it and my repository. The repository is here: https://github.com/arnavb/osx-doctest

@onqtam Thanks for the quick reply. I’ll keep trying to fix this … somehow. For now, I’m going to isolate this issue by remove all extraneous details and then see if the build works. Thanks for that note about the REQUIRE asserts. Turns out, I actually needed CHECK asserts all along (I just found out the difference recently).