Reputation: 279
I would like to set up cmake to run on a project with unit testing. The project structure is as follows:
|---CMakeLists.txt
|---build
|---source
| |---CMakeLists.txt
| |---many .cpp and .h files
|---tests
| |---CMakeLists.txt
| |---many .cpp files
The source files in tests
use Boost unit_test.h
library.
My outer CMakeLists.txt
is as follows:
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_CXX_FLAGS "-std=c++11")
project(MyProject CXX)
add_subdirectory(source)
add_subdirectory(tests)
enable_testing()
The CMakeLists.txt
in the source
folder is:
file( GLOB LIB_SOURCES *.cpp )
file( GLOB LIB_HEADERS *.h )
add_library( MyProject_lib ${LIB_SOURCES} ${LIB_HEADERS} )
And the CMakeLists.txt
in the tests
folder is:
# require old policy to allow for source files containing the name "test"
cmake_policy(SET CMP0037 OLD)
# Locate Boost libraries: unit_test_framework, date_time and regex
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.59 REQUIRED COMPONENTS unit_test_framework date_time regex)
include_directories("${CMAKE_SOURCE_DIR}/source" ${Boost_INCLUDE_DIRS})
file(GLOB APP_SOURCES *.cpp)
foreach(testsourcefile ${APP_SOURCES})
string(REPLACE ".cpp" "" testname ${testsourcefile})
add_executable(${testname} ${testsourcefile})
target_link_libraries(${testname} LINK_PUBLIC ${Boost_LIBRARIES} MyProject_lib)
add_custom_target(targetname)
add_custom_command(TARGET targetname POST_BUILD COMMAND ${testname})
endforeach(testsourcefile ${APP_SOURCES})
If I comment the lines with add_custom_target
and add_custom_command
, the result of this configuration is that the library is correctly built and linked, but none of the tests is compiled.
If I do not comment the two lines with add_custom_target
and add_custom_command
, The error I get by running cmake
is:
CMake Error at tests/CMakeLists.txt:25 (add_custom_target):
add_custom_target cannot create target "targetname" because another target
with the same name already exists. The existing target is a custom target
created in source directory "/tests". See
documentation for policy CMP0002 for more details.
Since I have a large number of tests, listing them one by one is not practical. I would like to have cmake to find all the .cpp files, as done for the library in the source folder, compile and run them.
Upvotes: 1
Views: 1965
Reputation: 2466
This is the solution I use in my library:
FILE( GLOB log_testprograms *.cpp )
FOREACH( testsource ${log_testprograms} )
GET_FILENAME_COMPONENT( filename ${testsource} NAME_WE )
celma_add_celma_boost_testprogram( ${filename} )
ENDFOREACH()
celma_add_celma_boost_testprogram
is a macro like this:
macro( celma_add_celma_boost_testprogram filename )
add_executable( ${filename} ${filename}.cpp )
target_link_libraries( ${filename} celma ${Boost_Test_Link_Libs} )
add_test( ${filename} ${CMAKE_CURRENT_BINARY_DIR}/${filename} )
endmacro( celma_add_celma_boost_testprogram )
Celma is the name of my library, the variable Boost_Test_Link_Libs
contains the list of Boost libraries to link against, including the Boost.Test library.
Upvotes: 1