我有一个C ++项目,它使用CMake作为其构建系统。我想要以下行为:
如果以cmake ..
方式调用cmake,则CMAKE_CXX_FLAGS
为-O3 -Wall -Wextra
如果以cmake .. -DCMAKE_BUILD_TYPE=Debug
方式调用cmake,则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构建,尽管我想要一个优化的构建。
为什么呢?我该怎么做才能获得理想的行为?
答案 0 :(得分:40)
首先:建议使用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")
这将确保如果您根本没有指定构建类型,它将默认为" Release"因此将使用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
。我很确定这不是你想要的。
答案 1 :(得分:8)
对于特定于Release目标的CXX标志,您应该设置
CMAKE_CXX_FLAGS_RELEASE
而不是
CMAKE_CXX_FLAGS
在您的情况下,您可以使用:
设置(CMAKE_CXX_FLAGS" -Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG" -g")
设置(CMAKE_CXX_FLAGS_RELEASE" -O3")
更现代的CMake方法(我建议,如果您使用的是CMake版本2.8.12或更新版本),在this StackOverflow answer中有详细描述,并且涉及target_compile_options的使用。
答案 2 :(得分:0)
各种发行模式的默认优化级别是O3,often isn't the best choice。在import React, { Fragment, useContext } from 'react';
import ShoppingCart from '../components/ShoppingCart';
import { CartContext } from '../contexts/CartContext';
const cart = () => {
const { cart } = useContext(CartContext);
return (
<Fragment>
{cart.length !== 0 ? (
<ShoppingCart />
) : (
<div>
<h1>Your cart is empty</h1>
</div>
)}
</Fragment>
);
};
export default cart;
文件中,可以将其修改为O2:
CMakeLists.txt
这些正则表达式将被修改(例如):
# Modify compile flags to change optimization level from O3 to O2
string(REGEX REPLACE "([\\/\\-]O)3" "\\12"
CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "([\\/\\-]O)3" "\\12"
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REGEX REPLACE "([\\/\\-]O)3" "\\12"
CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
string(REGEX REPLACE "([\\/\\-]O)3" "\\12"
CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
至-O3
,通常用于基于Linux的编译器-O2
至/O3
通常用于基于Windows的编译器