CMake官网文档
CMake官网文档-用户交互指南
版本:
git-master(3.25.20221205-g2243bba)
git-master(3.27.20230822-g2491226)
git-master (3.31.20241227-gbf65f81)
文档翻译目录
以下为本文目录
文章目录
以下为本文正文
引言
当一个软件源提供基于CMake的构建系统时,使用者需要使用CMake用户交互工具来构建他。
一个设计良好的基于CMake的构建系统是不会在源码目录下进行任何输出的,所以一般地,用户会进行源码外构建。CMake会先生成一个合适的、适配于运行构建操作的机器的构建系统,然后由用户调用构建工具来运行此构建系统。该生成操作不可逆。
生成的构建系统通常被置为“只读”。CMake文件是最基础的输出物,可以特异性适配(specify)构建系统,并且在使用IDE时会自动填充属性(比如在生成构建系统后会进行此操作)。CMake会定期覆写构建系统,所以用户的修改可能会被覆盖。
通过共享CMake文件,本指南中提到的功能与用户交互操作对于所有基于CMake的构建系统适用。
CMake工具在处理CMakewe文件时,可能会报错,如:
the compiler is not supported(不支持该编译器)
the compiler does not support a required compile option(该编译器不支持的编译选项)
a dependency can not be found(依赖未找到)
这些报错需要用户手工解决,解决方法如:
choosing a different compiler(选择不同的编译器)
installing dependencies(安装依赖)
instructing CMake where to find them(告诉CMake包含目录)
1、命令行cmake工具
准备一份新的代码拷贝,cmake(1)通常的用法是,创建一个build目录,在此目录调用cmake:
cd some_software-1.4.2
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix
cmake --build .
cmake --build . --target install
如此在不同于源码目录的新目录下进行构建,有如下好处:保持代码目录不被误修改,可以用不同工具构建同一份代码,可以简单地删掉构建目录来进行清理。
CMake工具可能报一些供源码作者使用的警告,这些警告通常以This warning is for project developers
结尾。用户可以通过cmake(1)的命令选项-Wno-dev
来屏蔽这些警告。
2、cmake-gui工具
更习惯于可视化交互界面的用户可以使用cmake-gui(1)工具来调用CMake生成构建系统。
源码目录地址与构建目录地址需要手工填入。在此还是建议这两个目录区分开来。
生成一个构建系统
ccmake(1)和cmake-gui(1)工具可以引导用户设置不同的必填选项。cmake(1)工具可以在命令行中设置选项。此手册会对使用不同工具时都需要使用到的选项进行解释(相同选项在不同工具中的设置方法可能不同)。
1、命令行环境
在命令行中调用cmake(1)生成诸如Makefiles
、Ninja
的构建系统时,需要确保构建环境配置正确,否则一些必须的构建工具无法找到,如:构建工具、编译器、链接器和其他必要工具。
在Linux系统中,适用的工具通常可以在系统目录中找到、或通过系统包管理器来安装。其他由用户提供的、或安装在非默认路径的工具链也可以使用。
交叉编译(cross-compiling)时,一些平台使用环境变量或脚本来设置环境。
Visual Studio提供了多样的命令行提示与vcvarsall.bat
脚本,用于设置构建系统的命令行环境。使用Visual Studio生成构建系统时,并不需要严格地使用相应的命令行环境。
使用Xcode时,需要注意其版本。如下是一些常用的指定Xcode版本的方法:在Xcode的IDE界面设置;适用命令行工具xcode-select
设置;设置CMake的环境变量DEVELOPER_DIR
(这个会覆盖其他方法的设置)。
为了方便,cmake-gui(1)提供了一个环境变量编辑器。
2、命令行参数:-G
CMake会基于所在平台选择默认的生成器。通常,默认生成器足以用户进行软件构建。
用户可以使用命令行参数-G
来指定生成器:
cmake .. -G Ninja
cmake --help
命令可以显示可用用户选择的生成器(generators)列表。
在类Unix系统中(包括Mac OS X),默认使用Unix Makefiles
生成器。这个生成器改改也能用在Windows的各种环境,比如NMake Makefiles
和MinGW Makefiles
生成器。这些生成器会生成一个修改后的Makefile
,其可被make
、gmake
、nmake
或类似的工具执行。有关目标环境和工具的更多信息,请参阅对应生成器的文档。
Ninja
生成器适用于所有主流平台。ninja
是一个关注于性能与效率的构建工具,与make
的用例类似(similar in use-cases to make
)。
在Windows,cmake(1)
可以生成Visual Studio的解决方案。Visual Studio的版本就是产品名字里的四位数年份。别名是为了指定Visual Studio的其他版本,比如与VisualC++编译器对应的两位数版本,或者两者结合:
cmake .. -G "Visual Studio 2019"
cmake .. -G "Visual Studio 16"
cmake .. -G "Visual Studio 16 2019"
Visual Studio生成器能指定不同的架构。需要用到参数-A
:
cmake .. -G "Visual Studio 2019" -A x64
cmake .. -G "Visual Studio 16" -A ARM
cmake .. -G "Visual Studio 16 2019" -A ARM64
在苹果系统,Xcode
生成器用来生成集成开发环境Xcode使用的项目文件。
在诸如KDevelop4、QtCreator和CLion的集成开发环境中,对基于CMake的构建系统有原生支持。这些集成开发环境可以在用户界面选择底层的生成器,通常为Makefiles
和Ninja
二选一。
注意,一旦调用过CMake,便无法使用命令行参数-G
来改变生成器。只能删除构建目录从头再来。
当生成Visual Studio项目和解决方案文件时,有几个参数供最初运行cmake(1)时使用。
可以使用参数cmake -T
指定Visual Studio工具集:
# 使用clang-cl工具集
cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T ClangCL
# 指定构建目标为Windows XP
cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp
参数-A
可以指定目标的架构,参数-T
可以指定使用的工具链的详细信息。例如,参数项-Tost=x64
来指定64位的主机工具。以下展示了如何使用64位工具、以及如何以64位架构作为目标进行构建:
cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64
3、在cmake图形界面中选择生成器
点击"Configure"按钮,会弹出选择cmake生成器的弹窗。
命令行中可选的cmake生成器,在图形界面中皆有供选择。
当选择Visual Studio生成器时,需要进一步指定架构。
设置构建变量
调用CMake时,需要在命令行中设置变量。最常使用的见下表:
变量名 | 含义 |
---|---|
CMAKE_PREFIX_PATH | 查找依赖包的路径 |
CMAKE_MODULE_PATH | 查找CMake附加模块包的路径 |
CMAKE_BUILD_TYPE | 构建参数,譬如Debug 、Release ,是控制调试/优化的标志。这个变量仅在Makefile和Ninja等单配置构建系统生效。Visual Studio和Xcode等多配置构建系统会忽略此变量 |
CMAKE_INSTALL_PREFIX | 使用install 构建目标时安装软件的位置 |
CMAKE_TOOLCHAIN_FILE | 包含交叉编译数据的文件,例如工具链和系统根 |
BUILD_SHARED_LIBS | 调用命令add_library()未指定类型时,是否构建为共享库(非静态库) |
CMAKE_EXPORT_COMPILE_COMMANDS | 生成一个供基于clang的工具使用的compile_commands.json 文件 |
可能还有一些其他的用于特定项目的变量,例如控制项目组件启停等。
CMake除了规定变量前缀CMAKE_
仅能用于CMake原生提供的变量、第三方提供的变量不允许使用外,没有约定在不同构建系统中变量的命名规则。cmake-gui(1)工具可以根据变量的前缀来分组展示,所以第三方提供的变量保持独有的、一致的变量前缀是很有意义的。
1、在命令行中设置变量
首次构建时,可以直接在命令中设置变量:
mkdir build
cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug
或者后续再行使用cmake(1)设置:
cd build
cmake . -DCMAKE_BUILD_TYPE=Debug
在命令行中可以使用-u
命令入参来取消变量设置:
cd build
cmake . -UMyPackage_DIR
首次在命令行中创建的CMake构建系统,可以在cmake用户界面中修改参数,反之亦然。
cmake(1)命令可以使用-c
命令入参来指定用来初始化内存数据的文件,此之可以用来简化重复请求相同缓存条目的命令/脚本。
2、在cmake图形界面中设置参数
cmake在cmake图形界面中点击“Add Entry”按钮,会弹出一个设置变量的弹窗。
cmake图形界面的用户主界面可以修改已有变量。
3、CMake缓存
CMake工作时,需要获取编译器/工具/依赖的地址。相应的,使用相同的编译/链接参数和依赖地址,需要保证重复生成的编译系统的一致性。由于这些参数取决于用户使用的操作系统,所以需要保证实时配置、实时更新。
CMake第一次运行时,会在编译目录生成一个CMakeCache.txt
文件,其中数据的存储形式是键值对。用户在cmake图形界面、或使用cmake(1)命令可以修改这个缓存文件。cmake图形界面与cmake(1)命令也同样提供了可交互的操作方式,供用户在修改缓存数据后重新配置/生成构建系统。每一个缓存条目都会有一个相关联的简介,可在用户主界面查看。
不同类型的缓存条目在用户主界面的展示方式不同。栗子:BOOL
类型的缓存条目使用勾选框来展示/修改,STRING
类型的缓存条目使用文本框来展示/修改,FILEPATH
类型的缓存条目既可以类似于STRING
使用文本框、也可以通过文件选择弹窗来展示/修改。在cmake图形界面用户主界面中,STRING
类型的缓存条目的值域可以限定为一个下拉框中的参数类表(详见STRING
缓存属性)。
软件包附带的CMake文件可以使用option()命令来定义布尔类型的选项。这个命令可以创建一个带有帮助文本与默认值的缓存条目。显而易见,这些缓存条目仅针对于提供的软件的一些构建选项生效,比如是否编译测试与示例、是否启用异常等。
缺省设置
CMake使用文件CMakePresets.json
和CMakeUserPresets.json
来保存常用设置的缺省值,后者是针对用户设置的。我们可以在其中设置命令行选项的缺省值,比如:构建地址、生成器选择、缓存变量、环境变量等。这些设置都可以被用户覆写。关于文件CMakePresets.json
格式的完整信息请参见cmake-presets(7)手册。
1、在命令行中使用缺省设置
可以使用--preset
选项在cmake(1)命令行中引用缺省值设置。如果使用了--preset
选项,生成器和构建目录则不需要显式指定了,但是仍可以显式指定来覆盖缺省值。
栗子,如果你有一个如下的CMakePresets.json
文件:
{
"version": 1,
"configurePresets": [
{
"name": "ninja-release",
"binaryDir": "${sourceDir}/build/${presetName}",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}
你运行如下命令:
cmake -S /path/to/source --preset=ninja-release
如此就会按照构建目录/path/to/source/build/ninja-release
、Ninja生成器、CMAKE_BUILD_TYPE
为Release
的设置进行构建。
如果你想要查看可用的缺省值列表,可以运行如下命令:
cmake -S /path/to/source --list-presets
这样就可以展示出/path/to/source/CMakePresets.json
和/path/to/source/CMakeUsersPresets.json
中可用的缺省值、而无需生成构建树。
2、在cmake_gui中使用缺省设置
如果一个项目有在CMakePresets.json
或CMakeUserPresets.json
中设置可用的缺省值,那么就会以下拉菜单的形式显示在cnake图形界面的源目录与二进制目录之间。可以选择二进制目录、生成器、环境变量和缓存变量等的缺省值,同样也可以在设置了缺省值后重新覆盖之。
调用构建系统
生成构建系统以后,软件就可以使用特定构建工具构建了。当使用IDF生成器时,此步骤则是将生成的项目文件加载到IDE中进行构建。
CMake清楚构建时需要一些特定的工具,所以在命令行中构建一个构建系统或项目时,需要在构建目录下执行以下命令:
cmake --build .
--build
标志可以开启cmake(1)工具的特定操作模式:调用与生成器和用户配置的构建工具相关联的CMAKE_MAKE_PROGRAM
命令。
--build
模式可以使用--target
参数来指定特定的构建目标,比如一个特定的库、可执行文件或自定义目标、或者类似install
的特定的特殊目标:
cmake --build . --target myexe
--build
模式可以使用--config
参数,他可以在使用多配制生成器时指定要构建的那组配置:
cmake --build . --target myexe --config Release
在生成构建系统时,如果调用cmake时指定了CMAKE_BUILD_TYPE变量,--config
选项将失效。
一些构建系统在运行时,会省略一些命令行中调用的详细信息。--verbose
标志可以用于展示这些省略的信息:
cmake --build . --target myexe --verbose
--build
模式可以传递特定命令行选项到底层构建工具、只需要在--
之后列示。这将有助于自定义构建工具,比如使用CMake非高级用户界面时、设置其在某项作业失败后继续构建。
对于所有生成器,都可以在包含CMake后运行底层构建工具。举个栗子,Unix Makefiles生成器生成后可以执行make
来构建、Ninja生成器生成后可以执行ninja
来构建。IDE构建系统通常提供命令行工具来构建项目,命令行工具也可以被调用。(最后半句话不知如何翻译)
1、选择一个目标
每个可执行文件和库都在Cmake文件中视为一个目标。同时可以自定义目标,以供内部或用户使用,比如创建文档。
CMake为所有提供CMake文件的构建系统提供了很多内置目标。
all
Makefile
和Ninja
生成器的默认目标。生成构建系统中的所有目标,除了使用属性EXCLUDE_FROM_ALL排除的目标与文件夹。Xcode和Visual Studio生成器中写作ALL_BUILD
。
help
列示出可构建的目标。此目标可用于Unix Makefiles与Ninja生成器,并且只有特定工具可以展示确切的输出。
clean
删除已构建的项目文件与输出文件。构建器的Makefiles
文件会为每个文件夹创建一个clean目标,以便清理单个文件夹。Ninja
工具提供了自有的粒度-tclean
系统。
test
运行测试。仅当CMake文件提供基于CTest的测试时,此目标才自动可用。请参见运行测试。
install
安装软件。仅当软件使用install()命令定义安装规则时,此目标才自动可用。请参见软件安装。
package
创建二进制包。仅当CMake文件提供基于CPack的包时,此目标才自动可用。
package_source
创建源包。仅当CMake文件提供基于CPack的包时,此目标才自动可用。
对于基于Makefile
的系统,针对二进制构建目标提供了/fast
变体。可以用来构建制定目标而忽略其依赖。即使依赖过期也不会检查或更新之。Ninja生成器不提供类似目标,因为其检查依赖足够快。
基于Makefile
的系统还提供构建目标来预处理、组装和编译特定目录中的单个文件。
make foo.cpp.i
make foo.cpp.s
make foo.cpp.o
目标名中写明了文件扩展名,因为可能存在同名不同扩展名的文件。若非如此的话可以不写扩展名。
make foo.i
make foo.s
make foo.o
在包含foo.c
和foo.cpp
的构建系统中,构建foo.i
目标将预处理这两个文件。
2、指定构建程序
--build
模式调用的程序由CMAKE_MAKE_PROGRAM变量决定。对于大多数生成器,不需要专门设置。
Generator | Default make program | Alternatives |
---|---|---|
XCode | xcodebuild | |
Unix Makefiles | make | |
NMake Makefiles | nmake | jom |
NMake Makefiles JOM | jom | nmake |
MinGW Makefiles | mingw32-make | |
MSYS Makefiles | make | |
Ninja | ninja | |
Visual Studio | msbuild | |
Watcom WMake | wmake |
jom
工具能够读取NMake
风格的makefile来并行构建,而NMake
则是串行构建。使用NMake Makefiles生成器生成后,用户可以运行jom
而不是NMake
。即使使用NMake Makefiles,CMAKE_MAKE_PROGRAM设置jom
后--build
模式即会调用jom
。更方便的是,提供有NMake Makefiles JOM生成器,会直接将jom
作为默认调用程序,与使用CMAKE_MAKE_PROGRAM设置的效果一样。进一步说,NMake Makefiles JOM生成器也可以设置调用nmake
程序,但是会低效。
软件安装
可以设置CMAKE_INSTALL_PREFIX变量来指定软件安装位置。如软件指定了安装规则(特指使用install()命令设置的),那么会安装到此设置的路径。Windows系统中,默认安装路径为系统目录ProgramFiles
(Windows特有的)。在Unix主机上,默认安装路径为/usr/local
。
CMAKE_INSTALL_PREFIX变量是目标文件系统中的安装路径前缀。
在交叉编译或打包场景中,如果sysroot是只读的、或者sysroot为默认状态,则可以将CMAKE_INSTALL_PREFIX变量设置为实际安装文件的位置。
以下命令将安装文件到主机的路径/tmp/package/lib/libfoo.so
。
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_SYSROOT=$HOME/root \
-DCMAKE_STAGING_PREFIX=/tmp/package
cmake --build .
cmake --build . --target install
主机的路径/usr/local
不受影响。
某些软件可能指定了uninstall
规则,但是CMake在默认情况下不会生成此规则。
运行测试
CMake发行版附带了ctest(1)工具,用于执行提供的测试和反馈结果。构建目标test
用于执行所有可用的测试,而ctest(1)工具用于更细致的控制、比如执行哪些测试、如何执行、如何反馈结果。在构建目录中执行ctest(1)相当于运行test
目标:
ctest
可以传入正则表达式、以仅运行与表达式匹配的测试。比如,以下命令仅运行名称中包含Qt
的测试:
ctest -R Qt
也可以使用正则表达式来排除测试。比如,以下命令仅运行名称中不包含Qt
的测试:
ctest -E Qt
ctest -R Qt -j8
也可以设置环境变量CTEST_PARALLEL_LEVEL来实现并行执行测试,无需传入-j参数。
默认情况下,ctest(1)不打印测试的输出。命令行参数-V(或作--verbose
)可以开启详细模式来打印所有测试的输出。选项–output-on-failure仅打印失败的测试的输出。环境变量CTEST_OUTPUT_ON_FAILURE可以设置为1
默认开启详细模式,无需传入参数–output-on-failure。
完
2024.12.28 16:42