【问题标题】:CMake: propagate compile options project-wideCMake:在项目范围内传播编译选项
【发布时间】:2018-12-14 09:48:13
【问题描述】:

假设我想为具有三个库/targets 的项目使用 /W4 编译所有代码。

A -> B -> C

在项目范围内应用标志的最佳做法是什么?

我可以想到两种方法:

  1. C 的 CMake(这是整个项目的核心库)中设置 TARGET_COMPILE_OPTIONS(C PUBLIC "\W4") 和依赖于 C 的所有其他库将通过以下方式继承标志:TARGET_LINK_LIBRARIES(B C)
    赞成:新库将自动继承该标志。
    缺点:项目的编译标志是隐式的。

  2. 分别为每个目标/lib 指定编译选项。
    专业人士:为每个 lib 单独指定和管理标志。
    缺点: em> 需要(不要忘记)为新库设置标志。

【问题讨论】:

  • TARGET_LINK_LIBRARIES 真的会传播使用TARGET_COMPILE_OPTIONS 设置的选项吗?
  • @VTT 它传播所有公共和接口(我认为),包括目录,但不知道编译器标志......对我来说似乎很脆弱。
  • 我认为它以另一种方式工作。 A需要某个选项,另一个不需要。您必须将 A 的选项传播到 B 和 C 才能链接。

标签: c++ cmake


【解决方案1】:

第三个选项,更改编译器标志。

例如,当我想在整个项目上激活地址清理程序时,我会这样做:

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address -static-libasan")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address -static-libasan")

当前为当前文件夹和子文件夹设置标志的惯用方式是使用

add_compile_options(-fsanitize=address) 

【讨论】:

  • 但这与通过targets 和properties 构建所有内容的现代 CMake 方法相矛盾
  • 是和不是。您始终可以使用编译器标志的全局属性而不是每个目标。我会查找新的等价物。我同意我应该尽可能使用新样式。
  • 添加了新政策
  • add_compile_options 仍然在目录而不是目标级别上运行,基本上它只是在标志上调用单独的SETs 的更简洁的语法。
  • 是的,我同意,仍然适用于目录而不是目标。但是在这种情况下,对于全局设置,您不想设置目标,而是全局设置。而且它不会直接修改标志并处理生成器,所以我会说它与设置变量相比是现代方式(另见stackoverflow.com/questions/39501481/…)。
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 2021-06-24
相关资源
最近更新 更多