简介
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake, 只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows [Visual C++](https://baike.baidu.com/item/Visual C%2B%2B/1811800) 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件.
使用
CMake的所有的语句都写在一个叫:CMakeLists.txt的文件中。当CMakeLists.txt文件确定后,可以用ccmake命令对相关 的变量值进行配置。这个命令必须指向CMakeLists.txt所在的目录。配置完成之后,应用cmake命令生成相应的makefile(在Unix like系统下)或者 project文件(指定用window下的相应编程工具编译时)。
具体的操作流程:
- $> ccmake directory
- $> cmake directory
- $> make
其中directory为CMakeList.txt所在目录;
- 第一条语句用于配置编译选项,如VTK_DIR目录 ,一般这一步不需要配置,直接执行第二条语句即可,但当出现错误时,这里就需要认为配置了,这一步才真正派上用场;
- 第二条命令用于根据CMakeLists.txt生成Makefile文件;
- 第三条命令用于执行Makefile文件,编译程序,生成可执行文件;
生成Buildsytem
Cmake是一个生成 生成项目文件
的工具, Cmakelists就是生成 生成项目文件
的文件, 这个生成项目文件
就是Build System.
不同的系统的build tool是不一样的, Cmake会根据平台的不同选择默认的build tool,也可以自己设置,
命令行为
$ cmake .. -G Ninja
GUI设置过程为官网上说
The “Configure” button triggers a new dialog to select the CMake generator to use
但是我试了一下有点奇怪, 直接生成了, 没有弹出对话框.
设置Build Variables
常见内部变量
Variable | Meaning |
---|---|
CMAKE_PREFIX_PATH |
Path to search for [dependent packages ](https://cmake.org/cmake/help/v3.22/guide/using-dependencies/index.html#guide:Using Dependencies Guide) |
CMAKE_MODULE_PATH |
Path to search for additional CMake modules |
CMAKE_BUILD_TYPE |
Build configuration, such as Debug or Release , determining debug/optimization flags. This is only relevant for single-configuration buildsystems such as Makefile and Ninja . Multi-configuration buildsystems such as those for Visual Studio and Xcode ignore this setting. |
CMAKE_INSTALL_PREFIX |
Location to install the software to with the install build target |
CMAKE_TOOLCHAIN_FILE |
File containing cross-compiling data such as toolchains and sysroots . |
BUILD_SHARED_LIBS |
Whether to build shared instead of static libraries for add_library() commands used without a type |
CMAKE_EXPORT_COMPILE_COMMANDS |
Generate a compile_commands.json file for use with clang-based tools |
其它的特殊变量也许是用于构建系统, 通常禁止或者允许项目的组件.
CMAKE_
开头的是 Cmake 自己提供的变量, 其它人应该使用自己的前缀, cmake-gui 可以识别出这些变量,比如 biogears:
内置变量的使用
- 在CMakeLists.txt中指定,使用set
- cmake命令中使用,如cmake -DBUILD_SHARED_LIBS=OFF
命令行参数
-G
可以重写 Cmake 默认的 generater , 使用cmake --help
可以本机支持的 generator:
$ cmake .. -G Ninja
-A
是可以选择目标平台的体系结构,比如:
cmake .. -G "Visual Studio 2019" -A x64
cmake .. -G "Visual Studio 16" -A ARM
cmake .. -G "Visual Studio 16 2019" -A ARM64
-T
可以选择Visual Studio的工具集:
$ # Build with the clang-cl toolset
$ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T ClangCL
$ # Build targeting Windows XP
$ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp
-D
可以设置变量值
$ mkdir build
$ cd build
$ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug
-U
重置变量的值,比如
$ cd build
$ cmake . -UMyPackage_DIR
Cmake Cache
当首次执行时,CMake在包含键值对的构建目录中生成CMAKECACHE.TXT文件。可以通过运行cmake-gui(1)
or ccmake(1)
工具来查看或编辑缓存文件。该工具提供了一个交互式界面,用于重新配置提供的软件并重新生成构建系统,如在编辑缓存值后所需的那样。每个缓存条目都可以具有关联的简短帮助文本,该文本显示在用户界面工具中。
Presets(预设参数)
Cmake识别CMakePresets.json
和用户自定义的CMakeUserPresets.json
来定义预定义参数,预定义参数列表, 这些都可以被用户自定义的参数覆盖,比如一个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
生成一个build
目录。
用下面这条语句可以列出所有的可用presets:
cmake -S /path/to/source --list-presets
这条语句会列出可以哦那个prests在/path/to/source/CMakePresets.json
and /path/to/source/CMakeUsersPresets.json
without generating a build tree.
Invoking the Buildsystem
在生成buildsystem后,软件可以通过调用特殊的build tool的方法被构建。在IDE生成器的情况下,这可能涉及将生成的项目文件加载到IDE中以调用构建。
而cmake也知道用命令行构建是常用的, 下面的命令可以在build目录调用用于生成buildsystem或者project.
$ cmake --build .
--build
打开一个cmake tool的特殊模式, 它调用了generator
的 CMAKE_MAKE_PROGRAM
命令.或者是用户自定义配置指定的build tool.
--build
也接收--target
参数来指定特殊的目标来构建, 例如一个库, 执行文件或者自定义的目标就像install
:
$ cmake --build . --target myexe
--build
也接收--config
参数用来在multi-config generators中指定某个配置来build:
$ cmake --build . --target myexe --config Release
--config
参数在cmake时使用CMAKE_BUILD_TYPE
时没有任何作用.
--verbose
可以忽略提示信息:
$ cmake --build . --target myexe --verbose
--build
还可以通过--
提供更多的参数比如让cmake在失败时继续运行.
对于所有生成器,可以在调用CMake后运行底层构建工具。例如,可以在使用unix makefiles生成器生成之后执行,以在使用ninja生成器等生成后调用构建或ninja等。IDE构建系统通常提供用于构建也可以调用的项目的命令行工具。
Selecting a Target
每一个可执行文件
和库文件
在Cmake files都是一个 build taget, buildsystem也可以描述根据用户需求自定义的目标,比如生成一个文档.
Cmake提供了一些内置的build targets:
all
The default target used by
Makefile
andNinja
generators. Builds all targets in the buildsystem, except those which are excluded by theirEXCLUDE_FROM_ALL
target property orEXCLUDE_FROM_ALL
directory property. The nameALL_BUILD
is used for this purpose for the Xcode and Visual Studio generators.help
Lists the targets available for build. This target is available when using the [
Unix Makefiles
](https://cmake.org/cmake/help/v3.22/generator/Unix Makefiles.html#generator:Unix Makefiles) orNinja
generator, and the exact output is tool-specific.clean
Delete built object files and other output files. The
Makefile
based generators create aclean
target per directory, so that an individual directory can be cleaned. TheNinja
tool provides its own granular-t clean
system.test
Runs tests. This target is only automatically available if the CMake files provide CTest-based tests. See also Running Tests.
install
Installs the software. This target is only automatically available if the software defines install rules with the
install()
command. See also Software Installation.package
Creates a binary package. This target is only automatically available if the CMake files provide CPack-based packages.
package_source
Creates a source package. This target is only automatically available if the CMake files provide CPack-based packages.
基于Makefile
的系统也同样提供了build-targets来预处理, 汇编, 编译文件:
$ make foo.cpp.i
$ make foo.cpp.s
$ make foo.cpp.o
也提供了这种
$ make foo.i
$ make foo.s
$ make foo.o
Specifying a Build Program
CMAKE_MAKE_PROGRAM
设置的模式可以用--build
来被调用, 对于更多的generator, 特殊的程序不需要被配置,一些常见的Generator对应的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 |
Software Installation
CMAKE_INSTALL_PREFIX
可以在Cmake cache中设置为在哪里安装软件,如果软件有特殊的安装目录需求, 用install()
命令可以用上面那个参数的安装路径, Windows默认的安装路径是ProgramFiles
, Unix是/usr/local
.
The CMAKE_INSTALL_PREFIX
变量永远指向target filesystem 的installation prefix.
下面的命令:
$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_SYSROOT=$HOME/root \
-DCMAKE_STAGING_PREFIX=/tmp/package
$ cmake --build .
$ cmake --build . --target install
会在目标机器安装 /tmp/package/lib/libfoo.so
,目标机器的/usr/local
不会被影响.
一些软件会提供uninstall
规则, 但是Cmake默认不提供.
Running Tests
Cmake自带的ctest(1)
工具可以提供测试和报告结果,虽然test
的build-target可以运行所有可用的tests,但是ctest
允许granular控制哪个tests可以运行, 如何运行, 如何报告结果.执行ctest
命令在build directory里面是这样的:
$ ctest
使用正则表达式可以用来告诉运行哪些tests, 比如运行Qt的 tests 就可以这样:
$ctest -R Qt
也可以指定名字:
$ ctest -E Qt
也可以用-j
参数指定并行线程数
$ ctest -R Qt -j8
环境变量中的CTEST_PARALLEL_LEVEL
就可以用-j
来代替.
默认的ctest
不打印tests的输出, -v
或者--verbose
打印所有输出,--output-on-failure
打印只报错的信息.设置CTEST_OUTPUT_ON_FAILURE
为1
可以用来代替--output-on-failure
这个参数.
欢迎在评论区中进行批评指正,转载请注明来源,如涉及侵权,请联系作者删除。