CMake 虽然本来就是一个纯命令操作程序,但以往动辄十几项还需要来回调试的命令行实际上并不适合人类使用。直到 CMakePresets 机制成熟,这东西才成为一个适合人类交互式操控的东西。
下面以 vtk 的为例,演示不需要滚瓜烂熟的情况下,如何一步一步修改编译配置直到最后安装完毕。
vtk 几乎是知名开源库中最容易编译的了,我一直让学生们入门时用这个练手。
首先,新建一个初始的CMakePresets.json
文件,放在CMakeLists.txt
的旁边:
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default: Ninja Multi-Config",
"description": "Ninja Multi-Config",
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
}
],
"buildPresets": [
{
"name": "rls",
"configurePreset": "default",
"configuration": "Release"
}
]
}
我用的是 Ninja Multi-Config
,与 msvc 的配合可以参考在Windows+VSCode+CMake+Ninja环境下设定MSVC工具集版本,但一般人是不用这么麻烦的,就用默认的就好。总之,现在的文件是通用的,虽然不包含配置,但随便哪个项目都可以用。
简单一点的话,generator
可以写Ninja
,那就应该需要把CMAKE_BUILD_TYPE
写在cacheVariables
中,buildPresets
里面的configuration
字段就用不着了。
如果是用 Visual Studio,那就得区分Visual Studio 17 2022
或者是其他版本 —— 但你都用 Visual Studio 了,干嘛不去直接用 Visual Studio 里面提供的 preset 功能呢?我记得起码 2022 是有的。
Visual Studio其实是个挺好的东西,但就是 Intelli Sense 实在是又笨又慢,依赖 Visual Assistant 又很贵,但使用 Ninja 就可以生成
compile_commands.json
文件,进而使用clangd
来做辅助。
此处不负责讲解 CMakePresets 的基本知识
新手用 CMake 往往离不开 GUI 的重要原因是,不知道这个项目有那些参数可以配置。实际上用命令行也是可以得到这些信息的。
首先,执行一遍初始的configure
:
mkdir build
cd build
cmake.exe --preset default ..
能不能走到最后没关系,关键是建立一些初始的项目结构。接下来就可以这样查看可配置项:
cmake.exe -LAH ..
L
:列出可配置选项
A
:包含高级选项
H
:包含注释信息
如果太多了,就把A
去掉,这时候你就可以看到类似这样的信息:
-- Configuring done (3.8s)
-- Generating done (4.4s)
-- Build files have been written to: C:/devlibs/libs-src/vtk-git/build
-- Cache values
// Build VTK with shared libraries.
BUILD_SHARED_LIBS:BOOL=ON
// Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.
CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;RelWithDebInfo
// Build with /MP flag enabled
CMAKE_CXX_MP_FLAG:BOOL=OFF
// The maximum number of processes for the /MP flag
CMAKE_CXX_MP_NUM_PROCESSORS:STRING=32
// Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=C:/devlibs/libs-src/vtk-git-9.3.1.install
// Path to a program.
NSIS_EXECUTABLE:FILEPATH=NSIS_EXECUTABLE-NOTFOUND
// The directory containing a CMake configuration file for Qt5Core.
Qt5Core_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Core
// The directory containing a CMake configuration file for Qt5Gui.
Qt5Gui_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Gui
// The directory containing a CMake configuration file for Qt5Network.
Qt5Network_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Network
// The directory containing a CMake configuration file for Qt5OpenGL.
Qt5OpenGL_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5OpenGL
// The directory containing a CMake configuration file for Qt5QmlModels.
Qt5QmlModels_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5QmlModels
// The directory containing a CMake configuration file for Qt5Qml.
Qt5Qml_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Qml
// The directory containing a CMake configuration file for Qt5Quick.
Qt5Quick_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Quick
// The directory containing a CMake configuration file for Qt5Sql.
Qt5Sql_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Sql
// The directory containing a CMake configuration file for Qt5Widgets.
Qt5Widgets_DIR:PATH=C:/devlibs/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Widgets
// The directory containing a CMake configuration file for Qt6.
Qt6_DIR:PATH=Qt6_DIR-NOTFOUND
// Build the Doxygen VTK documentation
VTK_BUILD_DOCUMENTATION:BOOL=OFF
// Build VTK examples.
VTK_BUILD_EXAMPLES:BOOL=OFF
// Include struct-of-arrays with scaled vtkDataArray implementation.
VTK_BUILD_SCALED_SOA_ARRAYS:BOOL=OFF
// Build the Sphinx documentation for VTK
VTK_BUILD_SPHINX_DOCUMENTATION:BOOL=OFF
// Build module testing directories
VTK_BUILD_TESTING:STRING=OFF
// Enable the Imaging group modules.
VTK_GROUP_ENABLE_Imaging:STRING=DEFAULT
// Enable the MPI group modules.
VTK_GROUP_ENABLE_MPI:STRING=DONT_WANT
// Enable the Rendering group modules.
VTK_GROUP_ENABLE_Rendering:STRING=WANT
// Enable the StandAlone group modules.
VTK_GROUP_ENABLE_StandAlone:STRING=WANT
// Enable the Views group modules.
VTK_GROUP_ENABLE_Views:STRING=DEFAULT
// Enable the Web group modules.
VTK_GROUP_ENABLE_Web:STRING=DEFAULT
// Expected Qt major version. Valid values are Auto, 5, 6.
VTK_QT_VERSION:STRING=Auto
// Which multi-threaded parallelism implementation to use. Options are Sequential, STDThread, OpenMP or TBB
VTK_SMP_IMPLEMENTATION_TYPE:STRING=Sequential
// Support CUDA compilation
VTK_USE_CUDA:BOOL=OFF
// Enable tests requiring "large" data
VTK_USE_LARGE_DATA:BOOL=OFF
// Support MPI
VTK_USE_MPI:BOOL=OFF
// Should VTK Java wrapping be built?
VTK_WRAP_JAVA:BOOL=OFF
// Should VTK Python wrapping be built?
VTK_WRAP_PYTHON:BOOL=OFF
// Path to a program.
WIX_EXECUTABLE:FILEPATH=WIX_EXECUTABLE-NOTFOUND
这是我已经配置好之后的样子,默认的不会有Qt
信息,但你会看到一条关于VTK_GROUP_ENABLE_Qt
的信息,提示你如果要Qt
就设置为YES
,于是就可以去CMakePresets.json
文件加上"VTK_GROUP_ENABLE_Qt": "YES"
,再来一遍:
cmake.exe --preset default ..
就会提示你需要设置Qt5_DIR
,设置上再来一遍,就成了。不要忘记CMAKE_INSTALL_PREFIX
。过程中,随时可以再来一遍cmake.exe -LAH ..
,因为不同的变量组合会改变这条命令的输出。
总之,这样一来,不再需要从十几行命令中如履薄冰地寻找需要更改的部分,而将复杂度转移到了对CMakePresets.json
文件的渐进式编辑中。
接下来都是公众版了,一切确认后,首先cd ..
回到CMakePresets.json
文件所在的目录,然后执行编译:
cmake.exe --build --preset rls
理论上,在build
目录里面ninja/make/nmake
效果是一样的。
然后,如果需要安装,或者更精细地只build
某个对象:
cmake.exe --build --preset rls --target install
基本的模式就是这样了。