My project directory looks like this:
build
CMakeLists.txt
header_1.h
main.cpp
test
CMakeLists.txt
main.cpp
tests.cpp
I have this CMakeLists.txt to generate my executable (excluding test):
cmake_minimum_required (VERSION 3.1)
project (my_project)
set (CMAKE_CXX_STANDARD 23)
set (CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF)
add_executable(my_app main.cpp)
target_include_directories(my_app PUBLIC)
I am trying to add a sub-folder test
to build unit tests with Google test, but I am struggling.
I know I need to add add_subdirectory(test)
in my outer CMakeLists.txt
and then I need test/CMakeList.txt, which I currently have:
set(BINARY ${CMAKE_PROJECT_NAME}_test)
file(GLOB_RECURSE TEST_SOURCES LIST_DIRECTORIES false *.h *.cpp)
set(SOURCES ${TEST_SOURCES})
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(${BINARY} ${TEST_SOURCES})
add_test(NAME ${BINARY} COMMAND ${BINARY})
target_link_libraries(${BINARY} PUBLIC ${CMAKE_PROJECT_NAME} ${GTEST_LIBRARIES} pthread)
but I keep getting linker errors because the second CMake is looking for my application as a library, not an executable:
[100%] Linking CXX executable my_project_test
/usr/bin/ld: cannot find -lmy_project: No such file or directory
I Googled for help but I could not find a simple example. There is a Google page example but it only shows the second CMake, not the first.
Could somebody please help with this?
The problem stems from the fact that you can’t link one executable to another executable (in this case my_app
to ${CMAKE_PROJECT_NAME}_test
) using target_link_libraries
.
As the name implies, this command is meant for linking libraries, not executables. That’s exactly what the linker is telling you: it’s trying to find a library called my_project
, but it doesn’t exist (Since you have only built an executable with that name)
If you still want to test code that lives in your executable, a common solution is to move the actual application code into a separate library via add_library(...)
.
That way both targets use the same code, without trying to link two executables together.