c++ - 默认在 CMake 中优化

标签 c++ cmake compiler-optimization

我有一个使用 CMake 作为其构建系统的 C++ 项目。我想要以下行为:

如果 cmake 被调用为 cmake ..,那么 CMAKE_CXX_FLAGS-O3 -Wall -Wextra

如果 cmake 被调用为 cmake .. -DCMAKE_BUILD_TYPE=Debug,那么 CMAKE_CXX_FLAGS-g -Wall -Wextra

我尝试了以下

message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

set(CMAKE_CXX_FLAGS "-O3 -Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra")

但这有一个大问题。首先,如果使用第二次调用,那么 -O3-g 标志都会传递给编译器。此外,如果我使用第二次调用和之后的第一次调用,CMAKE_BUILD_TYPE 保持 Debug 尽管没有明确订购 - 所以虽然我想要一个优化的构建,但我得到了一个 Debug 构建。

为什么?我该怎么做才能获得所需的行为?

最佳答案

首先:CMake 的推荐用法是始终在命令行上明确指定 CMAKE_BUILD_TYPE(当且仅当使用单一配置生成器时)。您的用例偏离了此最佳实践,因此请将此答案视为“您如何做”,而不一定是“您应该如何做”。

要解决第一个问题,您应该能够在 CMakeList 的早期执行此操作:

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

这将确保如果您根本不指定构建类型,它将默认为“发布”,因此将使用 CMAKE_CXX_FLAGS_RELEASE

第二个更难解决。从命令行传递的变量(例如 CMAKE_BUILD_TYPE=Debug)由 CMake 缓存,因此在后续调用中重复使用(这是必要的,因为 CMake 可以重新触发如果您在构建之间修改其输入,则它本身)。

唯一的解决方案是让用户再次显式切换构建类型,使用 cmake .. -DCMAKE_BUILD_TYPE=Release

考虑为什么这是必要的:正如我所说,如果自上次 CMake 运行以来 CMake 的输入(CMakeLists.txt 文件或其依赖项)发生了变化,CMake 可以重新触发自身作为构建的一部分。在这种情况下,它也将在没有命令行参数(例如 -DCMAKE_BUILD_TYPE=whatever)的情况下运行,并将依赖缓存提供与上次相同的值。这种情况与您手动运行 cmake .. 没有额外的参数没有区别。

如果没有在命令行上明确指定,我可以提供一个 hacky 解决方案来始终将 CMAKE_BUILD_TYPE 重置为 Release。但是,这也意味着如果发生自动重新生成,生成为 Debug 的构建系统将重新生成为 Release。我很确定这不是你想要的。

关于c++ - 默认在 CMake 中优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41361631/

相关文章:

c++ - 如何在 SimGrid 中创建带有 vector 的进程?

gcc - CMake 和编译器警告

linux - 为 CMake 中的build设置链接器搜索路径

c++ - header 包含导致代码执行变慢

c++ - 可以单独编译任何 .c 文件(也就是说,没有 main?)

c++ - 假设 STL vector 存储总是连续的是否安全?

c++ - 使用引用类型的比较函数失败

c - 模拟网格。对从 msg.h 导入的函数的 undefined reference

c++ - 未使用的功能会被优化吗?

c++ - 打开优化(O1 或 O2 或 O3)时程序卡在 pthread_spin_unlock 语句