Search code examples
c++cmakelinker-errorsdoctest

Linker error when using cmake and doctest.h (it's working without cmake)


I have 3 files in my directory "project": doctest.h - the testing library, doctest_main.cpp - a file needed for the library, and tests.cpp - the file with tests.

project/doctest_main.cpp:

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

project/tests.cpp:

#include "doctest.h"

TEST_CASE("Some test_case") {
    CHECK(2 + 2 == 4);
}

When I compile everything by hand, it works:

project> g++ -std=c++17 -Wall -Wextra -Werror doctest_main.cpp tests.cpp -o a
project> ./a

I tried to add CMake this way:

project/CmakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(project)

set(CMAKE_CXX_STANDARD 17)

add_compile_options(-Wall -Wextra -Werror)

add_executable(
    doctest_main.cpp tests.cpp)

Now I need to build CMake. Let's follow the official tutorial:

project> mkdir build
project/build> cd build
project/build> cmake ..  # Ok!
project/build> cmake --build .  # Linker error

The error is as follows:

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
/usr/bin/ld: CMakeFiles/doctest_main.cpp.dir/tests.cpp.o: in function `_DOCTEST_ANON_FUNC_2()':
tests.cpp:(.text+0x55): undefined reference to `doctest::detail::ResultBuilder::ResultBuilder(doctest::assertType::Enum, char const*, int, char const*, char const*, char const*)'

And a lot of undefined references after that. What should I do?


Solution

  • You've created an executable with the target name doctest_main.cpp and only a single source file.

    The add_executable should be changed to the following to create a target with the name a which by default results in the executable built being named a (or a.exe on windows):

    # extra whitespaces/newlines not needed below, but a personal style preference.
    add_executable(a
    
        doctest_main.cpp
        tests.cpp
    )
    

    Furthermore I recommend adding header files as sources too, since IDEs like Visual Studio wouldn't list them under the header files belonging to the a target.