CMake基础(6)生成类型

简介: CMake基础(6)生成类型

0x01 介绍

CMake 有许多内置的构建配置,可用于编译你的项目。它们指定优化级别以及调试信息是否包含在二进制文件中。CMAKE_BUILD_TYPE 是 CMake 中的一个变量,它指定了要使用的编译选项。

提供的级别包括:

  • Release - 将标志-O3 -DNDEBUG添加到编译器
  • Debug - 添加标志-g
  • MinSizeRel - 添加标志-Os -DNDEBUG
  • RelWithDebInfo - 添加标志-O2 -g -DNDEBUG

可以在 CMake 项目的根目录下的 CMakeLists.txt 文件中使用 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 文档:

https://cmake.org/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 文档:

https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html

0x02 示例

本教程中的文件如下:

root@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_06# tree
.
├── CMakeLists.txt
├── build
└── main.cpp
 
1 directory, 2 files
 
[CMakeLists.txt] - 包含你希望运行的 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 main.cpp)

[main.cpp] - 主源文件

#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/Makefile.cmake 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/progress.marks
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/build.make 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/DependInfo.cmake --color=
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_06/build'
make -f CMakeFiles/cmake_examples_build_type.dir/build.make 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/main.cpp.o
/usr/bin/c++    -O3 -DNDEBUG   -o CMakeFiles/cmake_examples_build_type.dir/main.cpp.o -c /mnt/d/Project/Cmake_examples/cmake_basics_06/main.cpp
[100%] Linking CXX executable cmake_examples_build_type
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_examples_build_type.dir/link.txt --verbose=1
/usr/bin/c++  -O3 -DNDEBUG  -rdynamic CMakeFiles/cmake_examples_build_type.dir/main.cpp.o  -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 提供的默认构建类型是不包含用于优化的编译器标志。对于某些项目,你可能希望设置默认生成类型,以便不必记住设置它。为此,你可以将以下代码添加到顶级 CMakeLists.txt 中。

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 表示将属性设置为指定源文件的属性 , 可命名零或多个源文件。注意:源文件属性只对在相同目录下的目标是可见的 (CMakeLists.txt)。

可以使用 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 文档:

https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html

这里是一些常见属性的例子:

  • 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 文档:

https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#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 文档:

https://cmake.org/cmake/help/latest/command/set.html

4.get_property

get_property 是 CMake 命令,用于获取指定对象的属性值。

用法:

get_property(<output variable> <scope> <property> [<variable>])

参数说明:

  • output variable:用于存储属性值的变量名。
  • scope:要查询属性的对象的作用域。可能的值有:
  • GLOBAL:全局作用域(整个 CMake 项目)
  • DIRECTORY:当前目录作用域(当前 CMakeLists.txt 文件所在目录)
  • 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 文档:

https://cmake.org/cmake/help/latest/command/get_property.html


相关文章
|
13天前
|
Windows
CMake基础(5)安装项目
CMake基础(5)安装项目
29 3
|
2月前
|
存储 缓存 算法
【CMake 基础教程 】深入理解CMake变量:类型、原理及最佳实践
【CMake 基础教程 】深入理解CMake变量:类型、原理及最佳实践
67 0
|
6月前
|
存储 Cloud Native Linux
CMake学习之内部变量
CMake学习之内部变量
|
13天前
|
存储 C++ Python
CMake基础(2)分离编译
CMake基础(2)分离编译
17 0
|
13天前
|
存储 缓存 Unix
CMake基础(8)包含第三方库
CMake基础(8)包含第三方库
8 1
|
13天前
|
编译器 C语言 C++
CMake基础(7)编译标志
CMake基础(7)编译标志
18 0
|
2月前
|
算法 IDE Linux
【CMake 小知识】CMake中的库目标命名和查找策略解析
【CMake 小知识】CMake中的库目标命名和查找策略解析
113 1
|
2月前
|
缓存 算法 开发者
【cmake 基础小知识】如何在CMake项目中使用add_dependencies命令管理目标依赖关系
【cmake 基础小知识】如何在CMake项目中使用add_dependencies命令管理目标依赖关系
63 0
|
iOS开发 MacOS
CMake基础:CMake中的常用变量的命令
CMake基础:CMake中的常用变量的命令
23 0
|
缓存 Unix 编译器
Cmake 的构建结构:理解 Cmake 的构建过程和依赖管理
Cmake 的构建结构:理解 Cmake 的构建过程和依赖管理
61 0