CMake:配置期间不同的编译器标志?

Posted

技术标签:

【中文标题】CMake:配置期间不同的编译器标志?【英文标题】:CMake: different compiler flags during configuration? 【发布时间】:2019-01-18 03:22:56 【问题描述】:

CMake 3.9、arm-gcc 5.4.1、Linux/OSX:

我通过将-fstack-protector-strong 添加到我的编译器标志来启用stack smashing protection。这指示 gcc 在硬编码库 libssp.alibssp_nonshared.a 中查找特殊命名的符号。

这些库作为构建的一部分存在于我的应用程序中,但当 CMake 在配置阶段询问我的编译器时它们还不存在。

这会导致 CMake 失败,这是有道理的:

[2/2] Linking CXX executable cmTC_0f43d

FAILED: cmTC_0f43d

/path/to/arm-none-eabi-g++ -fstack-protector-strong
CMakeFiles/cmTC_0f43d.dir/testCXXCompiler.cxx.obj -o cmTC_0f43d

/path/to/arm-none-eabi/bin/ld: cannot find -lssp_nonshared
/path/to/arm-none-eabi/bin/ld: cannot find -lssp

有什么办法:

    告诉 CMake 在编译器询问期间不要使用 -fstack-protector-strong? 在审讯期间提供libssplibssp_nonshared 的空“虚拟”版本? 完全跳过编译器询问? (这是一个自定义工具链。)

或者有什么其他方法可以解决这个问题?

【问题讨论】:

你是如何添加开关的。听起来您将其添加到默认 CFLAGS 而不是您在 CMakeLists.txt 中创建的目标。 没错,我将它们添加到 CFLAGS 中,因为我希望在我编译的每个文件中都启用它们。如果可能的话,我宁愿不必手动将它们添加到我创建的每个库和可执行文件中:很容易忘记,很难验证是否已添加,等等。 【参考方案1】:

告诉 CMake 在编译器询问期间不要使用-fstack-protector-strong

当 CMake 检查编译器时,只需在project() 调用之后添加此编译器标志

project(MyProject)
# ...
set(CMAKE_C_FLAGS "$CMAKE_C_FLAGS -fstack-protector-strong")
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -fstack-protector-strong")

除了将标志附加到CMAKE_*_FLAGS 变量之外,您还可以通过add_compile_options 命令添加它:

project(MyProject)
# ...
add_compile_options("-fstack-protector-strong")

【讨论】:

我们有大约 40 个项目,但它们都在一个根级项目之下。 CMake是否只在根级项目之后检查编译器?还是我需要在每个叶子项目之后附加标志?我只假设一次,因为那时编译器是已知的;我只是想确保我理解你的主张:) CMake 只检查编译器一次:它不会在下一个project() 上检查编译器。此外,CMake 不会在同一项目的下一次 cmake 调用中检查编译器。 我相信将其添加到 FLAGS 将使其传递给任何其他 try_compile() 命令,因此 add_compile_options() 可能更好。 @Fred:据我了解,try_compile 使用单独的 CMake 项目。该项目自动派生的唯一东西是工具链文件。所有其他参数都明确指定。 @Tsyvarev 我应该先检查一下。它是一个单独的 CMake 项目,但一些设置被转发到新项目。它是被转发的链接器标志之一,而不是编译器标志。【参考方案2】:

就我而言,选项 3 很简单。在我的工具链 CMake 文件中,我简单地添加了:

set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)

现在 CMake 不会浪费任何时间来询问我的编译器的功能。

这适用于我的特定情况(嵌入式系统固件),但如果让 CMake 和 -fstack-protector-strong 也能在非嵌入式程序上工作会很好。

【讨论】:

以上是关于CMake:配置期间不同的编译器标志?的主要内容,如果未能解决你的问题,请参考以下文章

使用 CMAKE 编译具有不同标志的相同文件

使用 CMake 编译 openCV:设置架构和优化标志

CMAKE如何编译具有不同标志的静态/对象库

在 CMake 项目中动态更改编译器标志

CMake 编译标志

我应该为我的库和应用程序使用哪些编译器标志以获得最佳性能 NDK (CMake)