在CMake中的调试与发布模式

20 浏览
0 Comments

在CMake中的调试与发布模式

在一个使用GCC编译的项目中,

  • 我如何为每个目标类型(debug/release)运行CMake?
  • 我如何使用CMake指定调试和发布的C/C++标志?
  • 我如何表示主可执行文件将使用g++编译,而一个嵌套的库将使用gcc编译?
admin 更改状态以发布 2023年5月20日
0
0 Comments

这里的很多答案已经过时/不好。因此,我将尝试更好地回答。 鉴于我在2020年回答这个问题,所以可以预料事物会改变。


如何为每个目标类型(调试/发布)运行CMake?

首先,Debug/Release在cmake中称为配置(吹毛求疵)。

如果您使用单个配置生成器(Ninja / Unix-Makefiles),则必须指定CMAKE_BUILD_TYPE

像这样:

# Configure the build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug
# Actually build the binaries
cmake --build build/
# Configure a release build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release
# Build release binaries
cmake --build build/

对于多配置生成器,情况略有不同(Ninja Multi-Config,Visual Studio)

# Configure the build
cmake -S . -B build
# Build debug binaries
cmake --build build --config Debug
# Build release binaries
cmake --build build --config Release

如果您想知道为什么需要这样做,那是因为cmake不是构建系统。它是一个元构建系统(即构建构建系统的构建系统)。这基本上是处理在一个构建中支持多个配置的构建系统的结果。如果您想更深入地了解,我建议阅读Craig Scott的书“Professional CMake:Practical Guide”。


如何使用CMake指定调试和发布的C/C++标志?

现代惯例是使用target和属性。

这是一个例子:

add_library(foobar)
# Add this compile definition for debug builds, this same logic works for
# target_compile_options, target_link_options, etc.
target_compile_definitions(foobar PRIVATE
    $<$:
        FOOBAR_DEBUG=1
    >
)

注意:我如何使用生成器表达式来指定配置!使用CMAKE_BUILD_TYPE将导致对于任何多配置生成器都造成糟糕的构建!

此外,有时您需要全局设置而不仅仅是为一个目标设置。
使用add_compile_definitions,add_compile_options等功能。这些函数支持生成器表达式。除非必须,否则不要使用旧的样式cmake(这条路是噩梦的土地)

如何表达主执行文件将使用g++编译,而一个嵌套的库将使用gcc编译?

您最后一次的问题真的没有意义。

0
0 Comments

使用CMake,通常建议进行“out of source”构建。在项目的根目录创建您的CMakeLists.txt。然后从项目的根目录执行以下操作:

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make

对于 Debug(同样是从项目的根目录):

mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make

Release / Debug 将为您的编译器添加适当的标志。还有 RelWithDebInfoMinSizeRel构建配置。


您可以通过在工具链文件中指定CMAKE__FLAGS__INIT变量来修改/添加标志,例如:

set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")

有关详细信息,请参见CMAKE_BUILD_TYPE


至于您的第三个问题,我不确定您确切地要问什么。 CMake应自动检测并使用适用于不同源文件的编译器。

0