【问题标题】:cmake: how to iterate all source files in a directory and build each into an executable?cmake:如何迭代目录中的所有源文件并将每个源文件构建成可执行文件?
【发布时间】:2019-07-11 09:15:26
【问题描述】:

我有一个 cpp 文件目录,其中包含以下文件:

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

每个 cpp 文件都有一个 main 函数,所以我希望将每个文件构建成可执行文件。那么如何使用 cmake 来查找和循环所有这些源文件并构建它们呢?

非常感谢。

【问题讨论】:

标签: c++ loops cmake directory executable


【解决方案1】:

我的建议是创建一个函数来执行文件的逻辑:

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

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

然后手动添加每个文件:

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)

这样,当你添加一个新文件时,它会正确触发 CMake 重新运行。

【讨论】:

  • 谢谢,我也希望有类似 Scons 的“env.Glob("*.cpp")” 来检索所有“.cpp”文件名,以避免写入所有“add_test_file”行,特别是当我有很多 .cpp 文件时。 cmake 语法如何支持这一点?
  • 有点,但由于 CMake 是一个元构建系统,globbing is considered bad practice.
  • 简而言之,如果您使用 globbing 添加测试文件,您的测试可能会通过,不是因为它会通过,而是因为构建系统不知道新文件。
【解决方案2】:

这个问题不那么受欢迎,虽然值得:)

按照 Guillaume Racicot 的回答,我构建了这两个(对我而言)非常有用的最小函数。如果您赞成我的回答,请考虑也赞成他的投票,否则我将无法写出我的答案!

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 文件如下所示:

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})

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多