c++ - cmake Xcode 生成器在发布模式下使用 -O0 代替 -O3 或 -O2
问题描述
背景
我有一些大型多平台 C++ 项目,它在 Windows/MacOS/Linux (msvc/clang/clang) 上运行。由于项目很大,我无法提供 [mcve]。-O3
我正在尝试,这样的示例使用标志构建。
对于 MacOS 项目以这种方式构建:
mkdir build_release
cd build_release
cmake -G Xcode -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release -j 8
制作
$ cmake --version
cmake version 3.19.6
CMake suite maintained and supported by Kitware (kitware.com/cmake).
铛
$ clang++ --version
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Xcode 12.4 (12D4e)
问题
在构建日志中,我注意到它-O0
被用来代替-O3
或-O2
!!!
所以我检查了我的 CMakeLists.txt 文件以找到解释:
$ git grep -E "CMAKE_C(XX)?_FLAGS"
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_CXX_FLAGS_DEBUG "/MDd" "/MTd")
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_CXX_FLAGS_RELEASE "/MD" "/MT")
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_CXX_FLAGS "/MD" "/MT")
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_C_FLAGS_DEBUG "/MDd" "/MTd")
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_C_FLAGS_RELEASE "/MD" "/MT")
CMake/build_flags_override.cmake: init_and_replace_flags(CMAKE_C_FLAGS "/MD" "/MT")
CMake/macostools.cmake: set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-arc" PARENT_SCOPE)
CMake/macostools.cmake: set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc" PARENT_SCOPE)
CMakeLists.txt: set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -g -DNDEBUG")
CMakeLists.txt: set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -DNDEBUG")
CMakeLists.txt: set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
所以优化级别没有调整。
所有目标(除了一个)都是常规的 cmake 目标(不使用空间配置默认设置)。唯一不同的配置如下:
add_executable(MyTarget)
set_target_properties(MyTarget PROPERTIES
OUTPUT_NAME "Product name"
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_BUNDLE_NAME "Product name"
MACOSX_BUNDLE_INFO_PLIST ${PRODUCT_CONFIGURATION_DIR}/Info.plist
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.0"
MACOSX_BUNDLE_LONG_VERSION_STRING "Product name v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.0"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.0"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.product.identifier"
MACOSX_BUNDLE_COPYRIGHT "(C) ${EI_CURRENT_YEAR} Company name"
MACOSX_RPATH TRUE
MACOSX_FRAMEWORK_IDENTIFIER com.product.identifier
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@loader_path/Libraries"
RESOURCE "${RESOURCE_FILES}"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
XCODE_ATTRIBUTE_EXECUTABLE_NAME "exe_name"
XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] dwarf-with-dsym
)
更烦人的是明确添加-O3
并且CMAKE_C_FLAGS_RELEASE
不会CMAKE_CXX_FLAGS_RELEASE
改变情况。
我不知道发生了什么。我敢肯定几个月前它很好,现在优化被禁用了。我不知道问题是由软件更新或CMakeList.txt
.
我想避免 git 二进制搜索,因为配置过程非常耗时(涉及 git 子模块)。
问题
有谁知道这个问题的根源和/或如何克服它?
线索
在 Windows 和 Linux 上都很好。
当我在 MacOS ( make
)上使用默认生成器时,使用了-G Xcode
适当的优化标志 ( -O3
)。我会很高兴,但在这种情况下cmake
,无法利用XCODE_ATTRIBUTE_*
在最终目标上设置的属性,这不符合我的要求。
解决方案
问题原来是订单。
我刚刚移动了这部分:
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -g -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -DNDEBUG")
归根结底,CMakeLists.txt
一切都按预期进行。
我注意到在它最初(更改之前)的位置$CMAKE_CXX_FLAGS_RELEASE
是空的。当我将语句移动到(更改之前)的底部原始值时,$CMAKE_CXX_FLAGS_RELEASE
包含-O3
.
我不知道这两个位置之间可能会产生这种影响。这两个地方之间没有任何东西显式地改变了这个变量。
推荐阅读
- angular - Angular 前端(使用代理)请求错误的后端 url
- excel - VBA:IF THEN ELSE 函数中 ComboBox 的值
- vuejs2 - 支持模式和非模式路线
- sequelize.js - 在多对多关联中设置不同的键
- amazon-web-services - 无法将 RDS Postgres 迁移到 AWS Aurora
- microsoft-graph-api - Microsoft Graph API - /drive/root/children 始终为空,我不明白我做错了什么
- mysql - 无法弄清楚sql查询
- html - 为什么 vs code extension prettier 不起作用?
- javascript - 如何使一个通用功能仅在反应中对单击的事件起作用?
- c++ - 你能解释一下这行线性搜索算法吗?