【问题标题】:CMake: Setting correct compiler options for one platform onlyCMake:仅为一个平台设置正确的编译器选项
【发布时间】:2013-05-19 08:06:07
【问题描述】:

我使用 CMake 跨 Windows、OSX 和 Linux 生成构建文件(makefile 或项目文件),并使用这些平台的原生 C 和 C++ 编译器。在 Windows 上,我生成 VS 2010 项目,在发布配置中出现以下错误:

命令行错误 D8016:“/ZI”和“/Ob2”命令行选项不兼容

显然,CMake 会生成不兼容的优化和调试信息选项。这是默认的 CMake 配置,我没有设置任何特殊标志。

我通过在 Visual Studio 的项目选项中将 /ZI 更改为 /Z7 来解决此问题,但这使得设置连续集成系统很烦人 - 我需要添加脚本来修改项目文件。

我能否强制 CMake 生成 /Z7(C7 兼容调试信息)而不是 /ZI?

另外,我怎样才能让它只在发布配置而不是在调试中生成呢?

【问题讨论】:

    标签: cmake cross-compiling


    【解决方案1】:

    我认为 CMake 默认情况下不会将 /ZI 应用于 Release 标志 - 它可能已应用于 CMakeLists.txt 中的其他位置或其中包含的 CMake 文件之一。

    不过,您可以通过以下方式切换标志:

    if(MSVC)
      string(REGEX REPLACE "/Z[iI7]" ""
             CMAKE_CXX_FLAGS_RELEASE
             "${CMAKE_CXX_FLAGS_RELEASE}")
      set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Z7")
    endif()
    

    如果/Zi/ZI/Z7 标志已经存在于Release 标志中,第一行将去除它们。注意""${CMAKE_CXX_FLAGS_RELEASE}" 的使用。重要的是,此 CMake 变量保持为单个字符串。如果去掉引号,变量就会变成一个分号分隔的列表(即每个空格都被一个分号代替),这不适合传递给编译器。

    如果您愿意,可以在此处给出相互冲突的标志。因此,如果您删除了string(REGEX REPLACE ...) 命令并简单地留下了set 命令,${CMAKE_CXX_FLAGS_RELEASE} 可能包含... /ZI ... /Z7 ...",但只要/Z7 是最后一个调试信息标志,它就会“获胜”并且是终于被应用了。

    但是,对于首先清理变量的微小努力,我觉得剥离冲突标志是值得的。

    【讨论】:

    • +1 以获得很好的答案。您的解决方案确实有效,经过测试 - 但正如您所说,问题出在 CMakeLists.txt 文件中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    相关资源
    最近更新 更多