【问题标题】:Impact of setting CMAKE_CXX_FLAG in a C++ project在 C++ 项目中设置 CMAKE_CXX_FLAG 的影响
【发布时间】:2018-10-07 15:18:38
【问题描述】:

我有一个 C++ 项目,我想在项目中使用 CMake。我的项目有多个目录和子目录。

我有一个构建整个项目的顶级CMakeLists.txt。我在子目录中也有CMakeLists.txt。我想设置编译器标志,但这是我感到困惑的地方。 CMake中编译器flags的效果是只作用于对应的目录还是作用于整个项目?

例如,我的项目(我们称之为MyProject)有一个关联的CMakeLists.txt。该项目有两个子目录AB。每个都有自己的CMakeLists.txt。在A/CMakelist.txt 中,我将编译器标志设置如下:

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wno-narrowing")

B/CMakeLists.txt 如下:

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")

我不明白的是编译器是否也会对子目录B中的cpp文件使用标志-Wno-narrowing(通常它会适用于整个项目)?

CMakeList.txt 中设置编译器标志(通常是任何变量)的范围是仅适用于相应目录还是将在整个项目中全局应用?

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    CMake 的 set command 适用于函数和目录范围。也就是说,如果您像以前一样在 CMake 函数之外设置变量,则效果将在该目录及其所有子目录中可见。

    每当您定义一个新目标时(通过调用add_executableadd_library),CMAKE_CXX_FLAG 变量的值此时将用于确定目标的初始值编译标志的属性。

    所以-Wno-narrowing 选项不应该能够从一个子目录泄漏到同级子目录。

    关于现代 CMake 风格的快速说明:与直接设置 -std 选项相比,更喜欢使用 compile features functionalities。前者将是可移植的,适用于所有工具链和编译器版本。例如,要对项目中的所有目标全局要求 C++14,只需在顶级 CMakelists 中使用set(CMAKE_CXX_STANDARD 14)。同样,考虑使用target_compile_options 命令设置仅适用于项目特定目标的选项。使用该命令通常比到处摆弄全局变量更不容易出错。 对于像 -Wno-narrowing 这样的手动工具链特定标志,请考虑将它们包装在 generator expression 中,以确保它们仅用于支持该标志的工具链。

    【讨论】:

    • 感谢您的详细解答。只是重申以确保我理解正确。在顶级 Cmakelist 中为 CMAKE_CXX_FLAGS 设置的值将可用于 A/Cmakelist.txt。我可以从中添加甚至删除标志,但效果仅对 A 而言是本地的。当涉及到 B/Cmakelist.txt 时,添加目标的顶级 Cmakelist.txt 的 CMAKE_CXX_FLAGS 设置会出现(不是A) 处的最终 CMAKE_CXX_FLAGS 值。
    • 嗨,关于 CMAKE_CXX_STANDARD 的另一个后续问题。是否可以(也是一种好习惯)将顶级 Cmakelist 中的 C++ 版本设置为 'set(CMAKE_CXX_STANDARD 14)' 但是,在子目录 Cmakelist 中将其设置为 'set(CMAKE_CXX_STANDARD 98)'
    • @AnkurBose 否。在这种情况下,您不应该设置变量,而是使用target_compile_features 命令分别指定每个目标的版本。如果你可以在一个地方设置变量,那么在 CMake 中设置变量效果最好。如果您在整个项目中分散不同的值,则很难快速维护。在这种情况下,每个目标的方法更可取。
    • 感谢您的建议
    • 嗯,对我来说,这似乎并不完全是那时。如果我在同一个文件中在string(REPLACE "/EHsc" "/EHs-c-" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 之前执行add_library(...),我似乎在我的构建中替换了标志。
    猜你喜欢
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    相关资源
    最近更新 更多