CMakePresets.json
CMake 用户经常面临的一个问题如何其他人共享配置(可能需要写run.sh run.ps1 run.bat)。
自CMake 3.19起支持用json配置并运行项目,CMake 主要支持两个文件CMakePresets.json和CMakeUserPresets.json(要求位于项目根目录,使用preset构建则必须至少存在一个preset)。
两个preset.json没有内容差异。CMakePresets.json是面向所有用户的(理应提交到git),CMakeUserPresets.json应添加到.gitignore
具体案例
准备源代码与配置文件
目录结构如下:
$ tree
.
├── CMakeLists.txt
├── CMakePresets.json
└── main.cpp
主要看CMakePresets.json(example/step4)大概如下:
{
"version": 9,
"configurePresets": [
{
"name": "config-default",
"description": "Default configuration",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install"
}
},
{
"name": "config-release",
"description": "Release configuration",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/release-install"
}
}
],
"buildPresets": [
{
"name": "build-default",
"configurePreset": "config-default",
"jobs": 8
},
{
"name": "build-release",
"configurePreset": "config-release",
"jobs": 8
}
]
}
运行:
按照通常的cmake项目构建步骤,先配置,后构建。
$ cmake --list-presets # 输出看是否cmakeprest格式无误
Available configure presets:
"config-default"
"config-release"
$ cmake --preset config-default # 选择配置`config-default`,生成"binaryDir"中指定的目录build/default
$ cmake --build --list-presets # 输出可用的build presets(可选)
Available build presets:
"build-default"
"build-release"
$ cmake --build --preset build-default # 执行构建,生成build/default/cmake_preset可执行程序
CMakePresets.json 具体参数:
这里的CMakePresets.json参数非常简单,是完全可以对应到具体的cmake命令上。
配置阶段参数:
generator对应-G Ninja
binaryDir对应-B ./build/default
CMAKE_BUILD_TYPE对应 -D CMAKE_BUILD_TYPE=Debug
CMAKE_INSTALL_PREFIX对应 -D CMAKE_INSTALL_PREFIX=./install
构建阶段参数:
jobs对应 -j/--parallel 8
cmakepreset复用
CMakeUserPresets.json可以使用文件的include字段包含其他文件。这些文件所包含的文件还可以包含其他文件。如果CMakePresets.json和 CMakeUserPresets.json都存在, CMakeUserPresets.json 在格式的所有版本中隐式包含CMakePresets.json ,即使没有include字段。
具体例子:
例子根据上面的案例,新增一个CMakeUserPresets.json
{
"version": 9,
"configurePresets": [
{
"inherits": "config-default",
"name": "myconfig",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/myinstall"
}
}
]
}
$ cmake --list-presets # CMakeUserPresets.json隐式包含CMakePresets.json
Available configure presets:
"myconfig"
"config-default"
"config-release"
$ cmake --build --list-presets
Available build presets:
"build-default"
"build-release"
完整的 CMakeLists.txt 和 main.cpp 示例代码(examples/step4)
cmake_minimum_required(VERSION 3.20)
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
# 创建可执行文件
add_executable(find_lib_demo main.cpp)
# 查找 SDL2 库
find_package(SDL2)
# 给find_lib_demo这个目标链接 SDL2 库
target_link_libraries(find_lib_demo SDL2::SDL2)
#include <SDL.h>
#include <iostream>
int main(int argc, char* args[]) {
// 初始化SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
return -1;
}
// 创建窗口
SDL_Window* window = SDL_CreateWindow("SDL Demo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if (window == nullptr) {
std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}
// 创建渲染器
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == nullptr) {
std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return -1;
}
// 设置绘制颜色为蓝色
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
// 清除屏幕
SDL_RenderClear(renderer);
// 绘制一个矩形
SDL_Rect rect = {100, 100, 200, 150};
SDL_RenderFillRect(renderer, &rect);
// 更新屏幕显示
SDL_RenderPresent(renderer);
// 事件处理
bool quit = false;
SDL_Event e;
while (!quit) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
}
}
}
// 释放资源并退出
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}