避免具有多个目标的重复CMake代码

时间:2018-12-20 11:42:55

标签: c++ cmake

在具有多个目标的CMake项目中,我经常发现自己一遍又一遍地重复一些代码。参见以下示例:

cmake_minimum_required(VERSION 3.12)
project(rapid_benchmark)

set(CMAKE_CXX_STANDARD 17)

add_executable(benchmark main.cpp)
add_executable(benchmark_parallel main.cpp) # enable parallel processing
add_executable(benchmark_openmp main.cpp) # enable openmp
add_executable(benchmark_static main.cpp) # enable static optimizations
# ... more targets

# Adding basic dependecies
find_package(abc)
if(abc_FOUND)
    target_link_libraries(benchmark abc::abc)
    target_link_libraries(benchmark_parallel abc::abc)
    target_link_libraries(benchmark_openmp abc::abc)
    # ... all other targets ...
    # The same for the includes etc.

find_package(xyz)
if(xyz_FOUND)
    target_link_libraries(benchmark xyz::xyz)
    # ... all other targets ...

这很烦人并且容易出错,尤其是在添加新目标时。

如何避免CMake项目中具有多个目标的重复代码? 例如,是否可以将目标放入一种列表中并在该列表上调用target_link_libraries

3 个答案:

答案 0 :(得分:3)

与Bernhard所说的一样,但在CMake中:)

let chartHtml = chart.GetHtml()
System.IO.File.WriteAllText("C:/temp/chart.html", chartHtml)

然后,您可以像其他任何CMake命令一样简单地调用它:

macro(add_benchmark)
  set(singleValue NAME)
  set(multipleValues SOURCES)
  cmake_parse_arguments(local "" "${singleValue}" "${multipleValues}" ${ARGN})

  set (libraries)
  if (abc_FOUND)
    set (libraries ${libraries} abc::abc)
  endif()
  if (xyz_FOUND)
    set (libraries ${libraries} xyz::xyz)
  endif()

  add_executable(${local_NAME} ${local_SOURCES})
  target_link_libraries(${local_NAME} ${libraries})
endmacro()

答案 1 :(得分:2)

我会考虑创建一个macro,您可以为每个应用程序调用,该应用程序既可以进行编译,也可以进行链接

您可能会发现您想使用cmake-parse-arguments

答案 2 :(得分:1)

类似这样的事情... https://cmake.org/cmake/help/latest/command/foreach.html

set(targets a b c d e)
foreach(loop_var IN targets)
    add_executable($loop_var main.cpp)
endforeach(loop_var)

与执行大量操作的宏结合在一起将使它易于管理。

更多详细信息: Looping over a string list