a.wise
a.wise

Reputation: 194

CMake split target_sources in CMakeLists.txt into different targets

I have a test project called test_containers. Inside directory there are only cpp files and CMakeLists.txt which looks like this:

cmake_minimum_required(VERSION 3.0.0)
project(test_containers)

add_executable(${PROJECT_NAME})

target_sources(${PROJECT_NAME} PRIVATE
    test_linear_hash_table.cpp
    test_list.cpp
    test_stack.cpp
    test_string.cpp
    test_vector.cpp
    test_set.cpp
    test_array.cpp
    test_span.cpp
)

target_link_libraries(${PROJECT_NAME} PRIVATE
    gtest_main
)

add_test(
    NAME ${PROJECT_NAME}
    COMMAND ${PROJECT_NAME}
)

Now the problem is that after build I get only 1 executable bin file called test_containers and it contains all the tests from directory. I want to split this CMakeLists.txt into different targets so that these are different tests. How to do it right?

Upvotes: 0

Views: 623

Answers (1)

Bitwize
Bitwize

Reputation: 11220

For your question, as described, you will need to create 1 target per file -- each building the individual source, linking the correct dependencies, and being added as a test.

You might be able to do something like (untested):

set(source_files
    test_linear_hash_table.cpp
    test_list.cpp
    test_stack.cpp
    test_string.cpp
    test_vector.cpp
    test_set.cpp
    test_array.cpp
    test_span.cpp
)

# Iterate each source
foreach(source IN LISTS source_files)
  
  # Add the executable + source + dependencies
  add_executable(${PROJECT_NAME}.${source})
  target_sources(${PROJECT_NAME}.${source} PRIVATE ${source})
  target_link_libraries(${PROJECT_NAME}.${source} PRIVATE gtest_main)

  # Add a test
  add_test(
    NAME ${PROJECT_NAME}.${source}
    COMMAND ${PROJECT_NAME}.${source}
  )
endforeach() 

(This assumes ${source} doesn't use any special or invalid characters for target names)

However, generally when people ask this question, it's because they would actually like 1 CTest test-case per test in a GTest executable. This would allow the CTest dashboard to show each of the different tests independently, which makes scanning for failures quite easy.

If this is what you are looking for, then there's already a module/function that can provide this for you with little effort. You can use the GoogleTest module with the gtest_discover_tests function, which will produce 1 CTest test-case per GTest test-case:

include(GoogleTest)

gtest_discover_tests(${PROJECT_NAME})

Upvotes: 2

Related Questions