如何指定CMakeLists.txt文件以编译每个cpp文件的每个目标?

3

我有一堆cpp文件,每个文件都包含一个main函数。我只想以以下方式编译它们:

add_executable(algorithm1 algorithm1.cpp)
add_executable(algorithm2 algorithm2.cpp)
...
add_executable(findFile findFile.cpp)

我希望有更简单的方法来避免非常相似的行。我需要像这样的东西:

add_executable(EXTRACT_FROM_FILENAME xxx.cpp)

一行解决所有问题。

我的问题是:我们能否实现从源文件中获取可执行文件的名称并进行编译/链接吗?我知道Makefile有类似的功能,那CMake呢?这样下次如果我添加一个新的cpp文件,就不必修改CMakeLists.txt文件了,它会自动将新文件编译成目标可执行文件,并具有相应的文件名。

非常感谢。

2个回答

1
cmake_minimum_required(VERSION 3.4)

project(Troskyvs LANGUAGES CXX)

file(GLOB one_file_sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")

foreach(file_path ${one_file_sources})
  get_filename_component(filename "${file_path}" NAME)
  add_executable("${filename}" "${file_path}")
  set_target_properties("${filename}" PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED ON
    LINKER_LANGUAGE CXX)
endforeach()

它能工作,但我的意思是有没有一种方法可以在顶级CMakeLists.txt中编写像这样的函数?否则我必须在每个子文件夹内的CMakeLists.txt中编写此foreach循环,对吧? - Troskyvs
你的意思是递归地为所有子目录中的文件添加目标吗? - 273K
尝试使用file(GLOB_RECURSIVE ...)。我期望它能正常工作,但我目前不在我的电脑旁边,无法测试递归匹配。 - 273K

1

类似这样的方法可以解决CMake中通配符匹配的许多问题。

cmake_minimum_required(VERSION 3.20)
project(example)

function(MyProj_add_tool filename)
  cmake_path(GET filename STEM target)
  add_executable("${target}" "${filename}")
endfunction()

MyProj_add_tool(algorithm1.cpp)
MyProj_add_tool(algorithm2.cpp)

# ...

MyProj_add_tool(findFile.cpp)

请查看此处有关cmake_path的文档:https://cmake.org/cmake/help/latest/command/cmake_path.html#get-stem


我尝试了这个,但是我的Cmake不支持"cmake_path"命令。我使用的是Ubuntu20.04,Cmake版本为3.16,这应该是版本问题。 - Troskyvs
@Troskyvs - 你应该升级版本;这很容易,因为Kitware提供了一个apt repo。但是你可以用get_filename_component替换cmake_path并降低最低版本。 - Alex Reinking

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接