在GCC编译的项目中,

如何为每个目标类型(调试/发布)运行CMake ? 我如何使用CMake指定调试和释放C/ c++标志? 我如何表达,主要可执行文件将编译与g++和一个嵌套库与gcc?


当前回答

这里的很多答案都过时了。所以我会试着更好地回答这个问题。当然,我是在2020年回答这个问题,所以预计情况会发生变化。


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

首先,调试/发布在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不是一个构建系统。它是一个元构建系统(即构建构建系统的构建系统)。这基本上是处理在一次构建中支持多个配置的构建系统的结果。如果你想更深入地了解cmake,我建议你阅读Craig Scott的书《Professional cmake: a Practical Guide》


我如何使用CMake指定调试和释放C/ c++标志?

现代的实践是利用目标的和属性。

这里有一个例子:

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
    $<$<CONFIG:Debug>:
        FOOBAR_DEBUG=1
    >
)

注意:我如何使用生成器表达式来指定配置! 使用CMAKE_BUILD_TYPE将导致任何多配置生成器的错误构建!

此外,有时你需要全局设置,而不仅仅是一个目标。 使用add_compile_definitions, add_compile_options等。这些函数支持生成器表达式。除非迫不得已,否则不要使用旧式的cmake(那是一个噩梦的土地)


我如何表达,主要可执行文件将编译与g++和一个嵌套库与gcc?

你最后一个问题真的没有意义。

其他回答

如果你想建立一个不同的配置而不重新生成如果使用,你也可以运行cmake——build {$PWD}——config <cfg>对于多配置工具,选择<cfg> ex. Debug, Release, MinSizeRel, RelWithDebInfo

https://cmake.org/cmake/help/v2.8.11/cmake.html#opt%3a--builddir

而不是直接操作CMAKE_CXX_FLAGS字符串(可以使用string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g3") btw),你可以使用add_compile_options:

add_compile_options(
  "-Wall" "-Wpedantic" "-Wextra" "-fexceptions"
  "$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
)

这将向所有构建类型添加指定的警告,但只向DEBUG构建添加给定的调试标志。请注意,编译选项存储为CMake列表,它只是一个用分号分隔元素的字符串。

// CMakeLists.txt:释放

set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)

// CMakeLists.txt:调试

set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE)

使用CMake,通常建议进行“源外”构建。在项目的根目录中创建CMakeLists.txt。然后从项目的根源开始:

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

对于调试(同样从项目的根目录):

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

发布/调试将为编译器添加适当的标志。还有RelWithDebInfo和MinSizeRel构建配置。


你可以通过指定一个工具链文件来修改/添加标记,你可以在其中添加CMAKE_<LANG>_FLAGS_<CONFIG>_INIT变量,例如:

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

有关更多细节,请参阅CMAKE_BUILD_TYPE。


关于你的第三个问题,我不太清楚你问的是什么问题。CMake应该自动检测并使用适合不同源文件的编译器。

这里的很多答案都过时了。所以我会试着更好地回答这个问题。当然,我是在2020年回答这个问题,所以预计情况会发生变化。


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

首先,调试/发布在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不是一个构建系统。它是一个元构建系统(即构建构建系统的构建系统)。这基本上是处理在一次构建中支持多个配置的构建系统的结果。如果你想更深入地了解cmake,我建议你阅读Craig Scott的书《Professional cmake: a Practical Guide》


我如何使用CMake指定调试和释放C/ c++标志?

现代的实践是利用目标的和属性。

这里有一个例子:

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
    $<$<CONFIG:Debug>:
        FOOBAR_DEBUG=1
    >
)

注意:我如何使用生成器表达式来指定配置! 使用CMAKE_BUILD_TYPE将导致任何多配置生成器的错误构建!

此外,有时你需要全局设置,而不仅仅是一个目标。 使用add_compile_definitions, add_compile_options等。这些函数支持生成器表达式。除非迫不得已,否则不要使用旧式的cmake(那是一个噩梦的土地)


我如何表达,主要可执行文件将编译与g++和一个嵌套库与gcc?

你最后一个问题真的没有意义。