3

I've a cpp file directory having files like:

a.cpp b.cpp c.cpp xy.cpp ....

Each cpp file has a main function, so I wish to build each file into an executable. So how do I use cmake to find and loop all these source files and build them each?

Thanks a lot.

Hind Forsum
  • 9,717
  • 13
  • 63
  • 119
  • Now there's the CONFIGURE_DEPENDS flag for file(GLOB): https://cmake.org/cmake/help/v3.12/command/file.html#glob – Trass3r Feb 18 '19 at 03:22

2 Answers2

1

My advice would be to make a function to do the logic for a file:

function(add_test_file TEST_NAME TEST_FILE)
    add_emecutable(${TEST_NAME} ${TEST_FILE})

    target_link_library(${TEST_NAME} PUBLIC test_deps)
endfunction()

Then add each file manually:

add_test_file(a_test a.cpp)
add_test_file(b_test b.cpp)
add_test_file(c_test c.cpp)
add_test_file(xy_test xy.cpp)

That way, when you add a new file, it will trigger a CMake re-run correctly.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • 1
    Thanks, I also wish to have something like Scons that "env.Glob("*.cpp")" to retrieve all ".cpp" files names, to avoid writing all "add_test_file" lines, especially when I have many .cpp files. How does cmake syntax support this? – Hind Forsum Feb 18 '19 at 02:51
  • Sort of, but since CMake is a meta build system, [globbing is considered bad practice](https://stackoverflow.com/q/32411963/2104697). – Guillaume Racicot Feb 18 '19 at 02:53
  • In short, if you use globbing to add tests file, your tests may pass not because it would pass, but because the build system is unaware of new files. – Guillaume Racicot Feb 18 '19 at 02:54
0

The question is not so popular though deserve to be :)

Following Guillaume Racicot's answer, I constructed these two minimals functions that are very useful (to me). If you upvote my answer, consider up-voting his too without which I would not have been able to write my answer!

function(add_exe_linked_to_lib TEST_NAME TEST_FILE CLASS_SET)
    add_executable(${TEST_NAME} ${TEST_FILE})
    target_link_libraries(${TEST_NAME} PUBLIC ${CLASS_SET})
endfunction()

function(add_test_linked_to_lib TEST_NAME TEST_FILE CLASS_SET)
    add_exe_linked_to_lib(${TEST_NAME} ${TEST_FILE} ${CLASS_SET})
    add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endfunction()

a cmake file would look like:

function(add_exe_linked_to_lib TEST_NAME TEST_FILE CLASS_SET)
    add_executable(${TEST_NAME} ${TEST_FILE})
    target_link_libraries(${TEST_NAME} PUBLIC ${CLASS_SET})
endfunction()

function(add_test_linked_to_lib TEST_NAME TEST_FILE CLASS_SET)
    add_exe_linked_to_lib(${TEST_NAME} ${TEST_FILE} ${CLASS_SET})
    add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endfunction()


cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 11)
project("SUM-UP-TESTING")

#libraries
add_library(My_Class STATIC My_Class.cpp)
add_library(Another_Lib STATIC My_Class.cpp)
set(MY_LIBS My_Class Another_Lib)

#compile options
add_compile_options(-D DEBUG)

#main
add_exe_linked_to_lib(MAIN-TESTING main.cpp ${MY_LIBS})

# TEST
enable_testing()

add_test_linked_to_lib(Test_In_Code tests/testing1.cpp ${MY_LIBS})
Marine Galantin
  • 1,634
  • 1
  • 17
  • 28