默认在 CMake 中优化

新手上路,请多包涵

我有一个使用 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 构建。

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

原文由 marmistrz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 890
1 个回答

首先: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 的输入( CMakeLists.txt 文件或其依赖项)自上次 CMake 运行以来发生了变化,则 CMake 可以重新触发自身作为构建的一部分。在这种情况下,它也将在没有命令行参数的情况下运行,例如 -DCMAKE_BUILD_TYPE=whatever ,并将依赖缓存提供与上次相同的值。这种情况与您手动运行 cmake .. 没有其他参数没有区别。

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

原文由 Angew is no longer proud of SO 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题