首页 > 解决方案 > 避免具有多个目标的重复 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该列表?

标签: c++cmake

解决方案


和 Bernhard 说的一样,但是在 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()

然后你可以简单地调用它作为任何其他 CMake 命令:

add_benchmark(
  NAME benchmark
  SOURCES main.cpp
)

add_benchmark(
  NAME benchmark_other
  SOURCES main.cpp other.cpp
)

推荐阅读