代码之家  ›  专栏  ›  技术社区  ›  florestan

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

  •  2
  • florestan  · 技术社区  · 7 年前

    在具有多个目标的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 回复  |  直到 7 年前
        1
  •  3
  •   AlexDenisov    7 年前

    正如伯哈德所说,但在《迈克》)

    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
    )
    
        2
  •  2
  •   Bernhard    7 年前

    我会考虑创建一个 macro ,您可以为每个应用程序调用,它同时执行编译和链接

    你可能会发现你想用 cmake-parse-arguments

        3
  •  1
  •   fdk1342    7 年前

    像这样的… 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

    推荐文章