0x01 介绍
CMake 有许多内置的构建配置,可用于编译你的项目。它们指定优化级别以及调试信息是否包含在二进制文件中。CMAKE_BUILD_TYPE 是 CMake 中的一个变量,它指定了要使用的编译选项。
提供的级别包括:
Release - 将标志-O3 -DNDEBUG添加到编译器
Debug - 添加标志-g
MinSizeRel - 添加标志-Os -DNDEBUG
RelWithDebInfo - 添加标志-O2 -g -DNDEBUG
可以在 CMake 项目的根目录下的 文件中使用 set 命令来设置 CMAKE_BUILD_TYPE 变量:
set(CMAKE_BUILD_TYPE Debug)
也可以在命令行上使用 -DCMAKE_BUILD_TYPE=<type> 选项来设置 CMAKE_BUILD_TYPE 变量:
cmake -DCMAKE_BUILD_TYPE=Debug path/to/source
当 CMake 生成器生成构建脚本时,它会使用 CMAKE_BUILD_TYPE 的值来确定使用哪些编译选项。例如,如果 CMAKE_BUILD_TYPE 设置为 Debug,则 CMake 会启用调试信息和其他与调试有关的编译选项。
有关 CMAKE_BUILD_TYPE 变量的更多信息,请参阅 CMake 文档:
/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html
CMake 生成类型是指 CMake 生成器使用的编译器或构建工具的类型。CMake 支持多种不同的生成类型,如 Unix Makefiles、Ninja、Visual Studio、Xcode 等。
可以使用 -G 选项在命令行上指定 CMake 生成类型。例如,要使用 Unix Makefiles 生成类型,可以在命令行上运行:
cmake -G "Unix Makefiles" path/to/source
CMake 生成类型可以影响 CMake 生成器生成的文件和目录的结构,以及使用的编译器和构建工具的选择。因此,在选择 CMake 生成类型时应该考虑最终需要生成的目标平台和构建工具。
在使用 CMake 构建 C++ 项目时,常见的选择是 Unix Makefiles 或 Ninja 生成类型,或者使用 Visual Studio 生成类型在 Windows 上构建。如果要在 macOS 或 iOS 上构建,则可以使用 Xcode 生成类型。
有关 CMake 生成类型的更多信息,请参阅 CMake 文档:
/cmake/help/latest/manual/cmake-generators.
0x02 示例
本教程中的文件如下:
root@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_06# tree
.
├──
├── build
└──
1 directory, 2 files
[] - 包含你希望运行的 CMake 命令
# 指定CMake的最低版本要求。
cmake_minimum_required(VERSION 3.1)
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
# Set the project name
project (build_type)
# Add an executable
add_executable(cmake_examples_build_type )
[] - 主源文件
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Hello Build Type!" << std::endl;
return 0;
}
root@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_06/build# cmake .. -DCMAKE_BUILD_TYPE=Release && make -j24 VERBOSE=1
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/Project/Cmake_examples/cmake_basics_06/build
/usr/bin/cmake -S/mnt/d/Project/Cmake_examples/cmake_basics_06 -B/mnt/d/Project/Cmake_examples/cmake_basics_06/build --check-build-system CMakeFiles/ 0
/usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_06/build/CMakeFiles /mnt/d/Project/Cmake_examples/cmake_basics_06/build/CMakeFiles/
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
make -f CMakeFiles/cmake_examples_build_type.dir/ CMakeFiles/cmake_examples_build_type.dir/depend
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
cd /mnt/d/Project/Cmake_examples/cmake_basics_06/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/d/Project/Cmake_examples/cmake_basics_06 /mnt/d/Project/Cmake_examples/cmake_basics_06 /mnt/d/Project/Cmake_examples/cmake_basics_06/build /mnt/d/Project/Cmake_examples/cmake_basics_06/build /mnt/d/Project/Cmake_examples/cmake_basics_06/build/CMakeFiles/cmake_examples_build_type.dir/ --color=
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
make -f CMakeFiles/cmake_examples_build_type.dir/ CMakeFiles/cmake_examples_build_type.dir/build
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
[ 50%] Building CXX object CMakeFiles/cmake_examples_build_type.dir/
/usr/bin/c++ -O3 -DNDEBUG -o CMakeFiles/cmake_examples_build_type.dir/ -c /mnt/d/Project/Cmake_examples/cmake_basics_06/
[100%] Linking CXX executable cmake_examples_build_type
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_examples_build_type.dir/ --verbose=1
/usr/bin/c++ -O3 -DNDEBUG -rdynamic CMakeFiles/cmake_examples_build_type.dir/ -o cmake_examples_build_type
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
[100%] Built target cmake_examples_build_type
make[1]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
/usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_06/build/CMakeFiles 0
1.设置生成类型
可以使用以下方法设置生成类型。
使用 GUI 工具,如 ccmake/cmake-gui
通过命令行传递到 cmake:
cmake .. -DCMAKE_BUILD_TYPE=Release
2.设置默认生成类型
CMake 提供的默认构建类型是不包含用于优化的编译器标志。对于某些项目,你可能希望设置默认生成类型,以便不必记住设置它。为此,你可以将以下代码添加到* 中。
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
3.set_property
在指定域中设置一个命名属性
CMake 的 set_property 命令允许在 CMake 工程中设置属性。这些属性可以为特定目标(例如库或可执行文件)或特定源文件设置,也可以为整个工程设置。
set_property(<GLOBAL | DIRECTORY [dir] | TARGET target [APPEND] | SOURCE source
[APPEND]> PROPERTY <name> [value1 [value2 [...]]])
其中:
GLOBAL 表示将属性设置为整个工程的全局属性 , 唯一的,并且不接特殊的任何名字。
DIRECTORY 表示将属性设置为指定目录下的属性 , 默认为当前目录,但也可以用全路径或相对路径指定其他的目录(前提是该目录已经被 CMake 处理)。
TARGET 表示将属性设置为指定目标的属性 , 可命名零或多个已经存在的目标。
SOURCE 表示将属性设置为指定源文件的属性 , 可命名零或多个源文件。注意:源文件属性只对在相同目录下的目标是可见的 ()。
可以使用 APPEND 选项将值添加到已存在属性的值列表中,而不是覆盖它。
例如,可以使用以下命令将目标 my_target 的 PUBLIC_HEADER 属性设置为包含文件 my_header.h:
set_property(TARGET my_target PROPERTY PUBLIC_HEADER my_header.h)
可以使用以下命令将目录 src 的 INCLUDE_DIRECTORIES 属性设置为包含目录 include:
set_property(DIRECTORY src PROPERTY INCLUDE_DIRECTORIES include)
必选项 PROPERTY 后面紧跟着要设置的属性的名字。其他的参数用于构建以分号隔开的列表形式的属性值。如果指定了 APPEND 选项,则指定的列表将会追加到任何已存在的属性值当中。如果指定了 APPEND_STRING 选项,则会将值作为字符串追加到任何已存在的属性值。
以使用 set_property 命令来设置各种类型的属性,具体取决于选择的目标、源文件或目录。有关可用属性的完整列表,参阅 CMake 文档:
/cmake/help/latest/manual/cmake-properties.
这里是一些常见属性的例子:
INCLUDE_DIRECTORIES:设置包含目录列表。这些目录将用于编译器搜索头文件。
COMPILE_DEFINITIONS:设置编译器定义列表。这些定义将用于编译代码。
COMPILE_OPTIONS:设置编译器选项列表。这些选项将用于编译代码。
LINK_LIBRARIES:设置链接库列表。这些库将用于链接目标。
LINK_OPTIONS:设置链接器选项列表。这些选项将用于链接目标。
例如,可以使用以下命令将目录 src 的 INCLUDE_DIRECTORIES 属性设置为包含目录 include:
set_property(DIRECTORY src PROPERTY INCLUDE_DIRECTORIES include)
也可以使用以下命令将目标 my_target 的 LINK_LIBRARIES 属性设置为包含库 my_lib:
set_property(TARGET my_target PROPERTY LINK_LIBRARIES my_lib)
可以使用 set_property 命令来设置自定义属性。这些自定义属性可以在 CMake 脚本中使用,也可以在生成工具(如 make)中使用。
为了在 CMake 脚本中使用自定义属性,可以使用 get_property 命令来获取属性值。例如,假设使用以下命令设置了目标 my_target 的自定义属性 MY_CUSTOM_PROPERTY:
set_property(TARGET my_target PROPERTY MY_CUSTOM_PROPERTY value)
然后,可以使用以下命令获取该属性的值:
get_property(custom_property TARGET my_target PROPERTY MY_CUSTOM_PROPERTY)
在 CMake 脚本外,还可以在生成工具(如 make)中使用自定义属性。例如,假设使用以下命令设置了目标 my_target 的自定义属性 MY_CUSTOM_PROPERTY:
set_property(TARGET my_target PROPERTY MY_CUSTOM_PROPERTY value)
然后,可以在 make 命令中使用如下所示的环境变量来访问该属性:
make my_target MY_CUSTOM_PROPERTY=new_value
请注意,在使用自定义属性时,需要自行确保属性名称的唯一性。
有关使用自定义属性的更多信息,参阅 CMake 文档:
/cmake/help/latest/manual/cmake-properties.#custom
需要注意的是,set_property 命令仅在当前 CMake 脚本中有效。如果希望在多个 CMake 脚本之间共享属性值,则可以使用 set 命令将变量设置为全局变量。然后,可以在其他 CMake 脚本中使用 get_property 命令获取该变量的值。
例如,假设在 CMake 脚本 A 中使用以下命令设置了全局变量 MY_VAR:
set(MY_VAR value CACHE STRING "My variable")
然后,在 CMake 脚本 B 中,可以使用以下命令获取该变量的值:
get_property(my_var CACHE MY_VAR PROPERTY VALUE)
有关使用 set 命令设置全局变量的更多信息,参阅 CMake 文档:
/cmake/help/latest/command/
4.get_property
get_property 是 CMake 命令,用于获取指定对象的属性值。
用法:
get_property(<output variable> <scope> <property> [<variable>])
参数说明:
output variable:用于存储属性值的变量名。
scope:要查询属性的对象的作用域。可能的值有:
GLOBAL:全局作用域(整个 CMake 项目)
DIRECTORY:当前目录作用域(当前 文件所在目录)
TARGET:目标作用域(指定的目标)
SOURCE:源文件作用域(指定的源文件)
CACHE:缓存作用域(整个 CMake 项目的缓存)
TEST:测试作用域(指定的测试)
property:要查询的属性名称。
variable:可选参数,用于在查询属性时指定变量。
例如,要查询全局作用域中的 CMAKE_BUILD_TYPE 属性的值,可以使用以下命令:
get_property(build_type GLOBAL PROPERTY CMAKE_BUILD_TYPE)
这样,build_type 变量就会被设置为 CMAKE_BUILD_TYPE 属性的值。
注意:如果指定的属性不存在,get_property 命令将会失败。因此,在使用 get_property 命令时,应该先使用 set_property 命令设置属性值
你可能还想知道,get_property 命令还有一个重载版本,允许查询指定变量的值:
get_property(<output variable> <variable> [<property>])
参数说明:
output variable:用于存储变量值的变量名。
variable:要查询的变量名。
property:可选参数,用于在查询变量时指定属性。
例如,要查询全局作用域中的 CMAKE_BUILD_TYPE 变量的值,可以使用以下命令:
get_property(build_type VARIABLE CMAKE_BUILD_TYPE)
这样,build_type 变量就会被设置为 CMAKE_BUILD_TYPE 变量的值。
注意:如果指定的变量不存在,get_property 命令将会失败。因此,在使用 get_property 命令时,应该先使用 set 命令设置变量值。
相关域的说明与 set_property 意义相同。
有关使用 get_property 命令获取变量值的更多信息,参阅 CMake 文档:
/cmake/help/latest/command/get_property.html