默认情况下在CMake中进行优化 [英] Optimize in CMake by default
问题描述
我有一个使用CMake作为其构建系统的C ++项目。我想要以下行为:
I have a C++ project which uses CMake as its build system. I'd like the following behavior:
如果cmake作为 cmake ..
调用,则 CMAKE_CXX_FLAGS
是 -O3 -Wall -Wextra
If cmake is invoked as cmake ..
, then CMAKE_CXX_FLAGS
is -O3 -Wall -Wextra
如果调用cmake作为 cmake .. -DCMAKE_BUILD_TYPE = Debug
,然后 CMAKE_CXX_FLAGS
是 -g -Wall -Wextra
If cmake is invoked as cmake .. -DCMAKE_BUILD_TYPE=Debug
, then CMAKE_CXX_FLAGS
is -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
的作用,尽管未明确指定,所以-获得调试版本,尽管我想要优化版本。
But this has a big problem. First of all, if the second invocation is used, then both -O3
and -g
flags are passed to the compiler. Besides, if I use the second invocation and the first thereafter, CMAKE_BUILD_TYPE
stays Debug
although not explicitly ordered so - so I get a Debug build although I want an optimized build.
为什么?我该怎么做才能获得所需的行为?
Why? What can I do to get the desired behavior?
推荐答案
首先,建议:CMake的建议用法是始终指定 CMAKE_BUILD_TYPE
在命令行上显式显示(如果且仅当使用单配置生成器时)。您的用例偏离了此最佳实践,因此请将此答案视为您如何做,而不必视为您应该如何做。
First off: recommended usage of CMake is to always specify CMAKE_BUILD_TYPE
explicitly on the command line (if and only if using a single-configuration generator). Your use case deviates from this best practice, so treat this answer as "how you can do it," not necessarily as "how you should do it."
要解决第一个问题,您应该可以在CMakeList的早期完成此操作:
To address the first issue, you should be able to do this early in your 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
。
This will make sure that if you do not specify a build type at all, it will default to "Release" and thus CMAKE_CXX_FLAGS_RELEASE
will be used.
第二个难度较大。从命令行传递的变量(例如 CMAKE_BUILD_TYPE = Debug
)由CMake 缓存,因此可在后续调用中重新使用(这是必需的,因为如果在构建之间修改其输入,CMake可以重新触发自身。)
The second one is harder to tackle. Variables passed from the command line (such as CMAKE_BUILD_TYPE=Debug
) are cached by CMake and thus re-used in subsequent invocations (that is necessary, since CMake can re-trigger itself if you modify its inputs between builds).
唯一的解决方案是使用户再次使用<$ c显式切换构建类型。 $ c> cmake .. -DCMAKE_BUILD_TYPE =发布。
The only solution is to make the user switch the build type explicitly again, using cmake .. -DCMAKE_BUILD_TYPE=Release
.
考虑为什么这样做是必要的:正如我说的,CMake可以重新触发如果自上一次CMake运行以来CMake的输入( CMakeLists.txt
文件或其依赖项)已更改,则为构建的一部分。在这种情况下,它也将在没有命令行参数(例如 -DCMAKE_BUILD_TYPE =任何东西
)的情况下运行,并且将依靠缓存提供与上次相同的值。这种情况与您手动运行 cmake ..
时没有区别,而没有其他参数。
Consider why this is necessary: as I said, CMake can re-trigger itself as part of a build if CMake's input (CMakeLists.txt
files or their dependencies) has changed since last CMake ran. In such case, it will also be run without command-line arguments such as -DCMAKE_BUILD_TYPE=whatever
, and will rely on the cache to supply the same value as last time. This scenario is indistinguishable from you manually running cmake ..
without additional arguments.
我可以提供一个解决方案如果未在命令行上明确指定,请始终将 CMAKE_BUILD_TYPE
重置为发布
。但是,这也意味着以 Debug
生成的构建系统将以 Release
重新生成。 em>如果发生自动重新生成。我很确定那不是您想要的。
I could provide a hacky solution to always reset CMAKE_BUILD_TYPE
to Release
if not specified explicitly on the command line. However, it would also mean that a buildsystem generated as Debug
would get re-generated as Release
if automatic re-generation happened. I am pretty sure that's not what you want.
这篇关于默认情况下在CMake中进行优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!