痛苦

本地开发需要输入参数太多

刚开始做纯 C++ 跨端的项目时,为了考虑项目的统一工程化管理选择使用 CMake + Conan,因为各平台下使用的工具链、 IDE 都不一样。如 Windows 更多人习惯使用 Visual Studio IDE、针对 iOS 和 macOS 的开发更多人喜欢使用 Xcode,而 Linux 开发往往是 VSCode 配套。针对不通平台的 CMake 初始化命令都不太一样,主流的配置有如下几种:

Arguments/Platform Windows macOS iOS Android Linux
-G Visual Studio Unix Makefiles/Xcode Xcode Unix Makefiles Unix Makefiles
-A Win32/x64 - - -
CMAKE_OSX_ARCHITECTURES x86_64/arm64 armv7 arm64/x86_64 -
TOOLSETS e.g. v140/v141 - - - -
CMAKE_OSX_SYSROOT - - iphoneos/iphonesimulator - -
CMAKE_OSX_DEPLOYMENT_TARGET - e.g. 10.14/10.15 e.g. 9.0/10.0 -
CMAKE_SYSTEM_NAME Windows Darwin iOS Android Linux
CMAKE_SYSTEM_VERSION - - - API Level e.g. 21 22 23 -
CMAKE_ANDROID_STL_TYPE - - - e.g. c++_static/c++_shared -
CMAKE_ANDROID_ARCH_ABI - - - armeabi-v7/arm64-v8a/x86_64/x86 -
CMAKE_ANDROID_NDK - - - ~/Library/Android/sdk/ndk/21.4.7075529 -

以上还只是 CMake 自己的初始化指令,如果配合上 Conan 指定 profile 的参数,想生成一份 iOS 的工程命令将是这样的:

1
2
3
4
5
6
7
8
9
10
cmake -Bbuild_arm64_iphones -GXcode -DCMAKE_BUILD_TYPE=Release \
-DCONAN_PROFILE_BUILD=default \
-DCONAN_PROFILE_HOST=$(pwd)/.profiles/ios-arm64-iphoneos \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_DEPLOYMENT_TARGET=9.0 \
-DCMAKE_OSX_ARCHITECTURES=arm64 \
-DCMAKE_CXX_STANDARD=14 \
-DBUILD_LANGUAGE_BRIDGE=OFF \
-DCMAKE_C_FLAGS=-fembed-bitcode \
-DCMAKE_CXX_FLAGS=-fembed-bitcode

可以看到这个命令非常长,而且 CONAN_PROFILE_BUILD 指定的参数 default 依赖本地 conan 环境的初始化 profile 的配置,里面的配置可能不同开发机器上都不一样,对工程在不同设备上编译带来很大的挑战,非常容易编译出错。

而且在版本迭代过程中,工程的配置是不断在更新的,很容易忘记去修改 README 或者项目文档导致一些历史的编译脚本缺少一些关键指令丢失内容,这不符合 GitOps 思想。

与本地编译有些不同,虽然 CI 脚本一般是与工程放到同一个目录或者分开管理的,但即使是这样,如果按上面的指令一个一个去配置每个平台不同架构的编译脚本,CI 的脚本会非常冗长。要针对某个平台加一个配置时需要改多处位置,同样非常容易出错不易维护。

目标

经过多个项目跨平台编译构建的洗礼,很难忍受在切换项目过程中频繁的敲入命令去初始化 CMake 工程。虽然不同的 IDE 或代码编辑器工具有提供一些自己的 CMake 初始化配置能力(如 Visual Studio Code 可通过 .vscode/settings.json 来配置一些默认值)但这都不是通用方案。每个人使用的开发工具都各要求。特别是开源项目,如果没有提供一套全平台对各类工具都支持的配置文件,这会让开发者在工程配置上就被劝退。所以我们期望对项目工程化改造的目标不仅仅是解决上面的痛苦问题,更期望能让开发人员在接手项目时不需要在编译工具链、工程配置上花费太多的心思,让主流的开发工具打开工程开箱即用。

为了实现这个目标,我们在工程中引入了 CMakePresset.json,CMake 从 3.19 版本就开始支持了 CMakePresets.json 配置。如果你的版本还低于 3.19 请尽快升级来体验下 C/C++ 生态工具链的魅力。

方案

在工程根目录下创建 CMakePresets.json 文件,CMakePresets 支持配置 workflow 决定你的工程有多少个配置阶段,向 GitLab CI 中的 steps 一样。CMakePresets 支持 configure、build、test、package 几个阶段,如果你不需要使用 CTest 和 CPack,那后面两个阶段可以不做配置。一个完整的 配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0
},
"configurePresets": [
{
"name": "macos",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"generator": "Xcode",
"warnings": {"dev": true, "deprecated": true},
"cacheVariables": {
"BUILD_TESTING": "OFF"
}
},
{
"name": "darwin-debug",
"inherits": "macos",
"displayName": "Darwin 10.14+ (Debug)",
"description": "NetEase MSS C wrapper for macOS - Debug Configuration",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"BUILD_TESTING": "ON",
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/darwin-debug"
}
},
{
"name": "darwin-release-arm64",
"inherits": "macos",
"displayName": "Darwin arm64 10.14+ (Release)",
"description": "NetEase MSS C wrapper for macOS arm64 - Release Configuration",
"binaryDir": "${sourceDir}/build-darwin-arm64-realese",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_OSX_ARCHITECTURES": "arm64",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/darwin-arm64",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/darwin-release-arm64"
}
},
{
"name": "darwin-release-x86_64",
"inherits": "macos",
"displayName": "Darwin x86_64 10.14+ (Release)",
"description": "NetEase MSS C wrapper for macOS x86_64 - Release Configuration",
"binaryDir": "${sourceDir}/build-darwin-x86_64-realese",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/darwin-x86_64",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/darwin-release-x86_64"
}
},
{
"name": "ios-release-arm64",
"inherits": "macos",
"displayName": "iOS arm64 9.0+ (Release)",
"description": "NetEase MSS C wrapper for iOS arm64 - Release Configuration",
"binaryDir": "${sourceDir}/build-ios-arm64-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "iOS",
"CMAKE_OSX_DEPLOYMENT_TARGET": "9.0",
"CMAKE_OSX_ARCHITECTURES": "arm64",
"CMAKE_OSX_SYSROOT": "iphoneos",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/ios-arm64-iphoneos",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/ios-release-arm64"
}
},
{
"name": "ios-release-armv7",
"inherits": "macos",
"displayName": "iOS armv7 9.0+ (Release)",
"description": "NetEase MSS C wrapper for iOS armv7 - Release Configuration",
"binaryDir": "${sourceDir}/build-ios-armv7-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "iOS",
"CMAKE_OSX_DEPLOYMENT_TARGET": "9.0",
"CMAKE_OSX_ARCHITECTURES": "armv7",
"CMAKE_OSX_SYSROOT": "iphoneos",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/ios-armv7-iphoneos",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/ios-release-armv7"
}
},
{
"name": "ios-release-x86_64",
"inherits": "macos",
"displayName": "iOS x86_64 9.0+ (Release)",
"description": "NetEase MSS C wrapper for iOS x86_64 - Release Configuration",
"binaryDir": "${sourceDir}/build-ios-x86_64-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "iOS",
"CMAKE_OSX_DEPLOYMENT_TARGET": "9.0",
"CMAKE_OSX_ARCHITECTURES": "x86_64",
"CMAKE_OSX_SYSROOT": "iphonesimulator",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/ios-x86_64-iphonesimulator",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/ios-release-x86_64"
}
},
{
"name": "macos-android",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"warnings": {"dev": true, "deprecated": true},
"cacheVariables": {
"BUILD_TESTING": "OFF"
}
},
{
"name": "android-release-x86_64",
"inherits": "macos-android",
"displayName": "Android x86_64 abi21 (Release)",
"description": "NetEase MSS C wrapper for Android x86_64 - Release Configuration",
"binaryDir": "${sourceDir}/build-android-x86_64-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "Android",
"CMAKE_SYSTEM_VERSION": "21",
"CMAKE_ANDROID_STL_TYPE": "c++_static",
"CMAKE_ANDROID_ARCH_ABI": "x86_64",
"CMAKE_ANDROID_NDK": "$env{HOME}/Library/Android/sdk/ndk/21.4.7075529",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/android-x86_64-abi21",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/android-release-x86_64"
}
},
{
"name": "android-release-x86",
"inherits": "macos-android",
"displayName": "Android x86 abi21 (Release)",
"description": "NetEase MSS C wrapper for Android x86 - Release Configuration",
"binaryDir": "${sourceDir}/build-android-x86-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "Android",
"CMAKE_SYSTEM_VERSION": "21",
"CMAKE_ANDROID_STL_TYPE": "c++_static",
"CMAKE_ANDROID_ARCH_ABI": "x86",
"CMAKE_ANDROID_NDK": "$env{HOME}/Library/Android/sdk/ndk/21.4.7075529",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/android-x86-abi21",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/android-release-x86"
}
},
{
"name": "android-release-armeabi-v7a",
"inherits": "macos-android",
"displayName": "Android armeabi-v7a abi21 (Release)",
"description": "NetEase MSS C wrapper for Android armeabi-v7a - Release Configuration",
"binaryDir": "${sourceDir}/build-android-armeabi-v7a-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "Android",
"CMAKE_SYSTEM_VERSION": "21",
"CMAKE_ANDROID_STL_TYPE": "c++_static",
"CMAKE_ANDROID_ARCH_ABI": "armeabi-v7a",
"CMAKE_ANDROID_NDK": "$env{HOME}/Library/Android/sdk/ndk/21.4.7075529",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/android-armeabi-v7a-abi21",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/android-release-armeabi-v7a"
}
},
{
"name": "android-release-arm64-v8a",
"inherits": "macos-android",
"displayName": "Android arm64-v8a abi21 (Release)",
"description": "NetEase MSS C wrapper for Android arm64-v8a - Release Configuration",
"binaryDir": "${sourceDir}/build-android-arm64-v8a-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_SYSTEM_NAME": "Android",
"CMAKE_SYSTEM_VERSION": "21",
"CMAKE_ANDROID_STL_TYPE": "c++_static",
"CMAKE_ANDROID_ARCH_ABI": "arm64-v8a",
"CMAKE_ANDROID_NDK": "$env{HOME}/Library/Android/sdk/ndk/21.4.7075529",
"CONAN_PROFILE_BUILD": "${sourceDir}/.profiles/darwin-x86_64",
"CONAN_PROFILE_HOST": "${sourceDir}/.profiles/android-arm64-v8a-abi21",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/android-release-arm64-v8a"
}
},
{
"name": "windows",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"generator": "Visual Studio 15 2017",
"warnings": {"dev": true, "deprecated": true},
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/exports",
"BUILD_TESTING": "OFF"
}
},
{
"name": "windows-debug",
"inherits": "windows",
"displayName": "Windows x64 (Debug)",
"description": "NetEase MSS C wrapper for Windows - Debug Configuration",
"binaryDir": "${sourceDir}/build",
"architecture": {
"value": "x64",
"strategy": "set"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_DEBUG_POSTFIX": "d"
}
},
{
"name": "win32-release-x64",
"inherits": "windows",
"displayName": "Windows x64 (Release)",
"description": "NetEase MSS C wrapper for Windows - Release Configuration",
"binaryDir": "${sourceDir}/build-win32-x64",
"architecture": {
"value": "x64",
"strategy": "set"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/win32-release-x64"
}
},
{
"name": "win32-release-ia32",
"inherits": "windows",
"displayName": "Windows ia32 (Release)",
"description": "NetEase MSS C wrapper for Windows - Release Configuration",
"binaryDir": "${sourceDir}/build-win32-ia32",
"architecture": {
"value": "Win32",
"strategy": "set"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/win32-release-ia32"
}
}
],
"buildPresets": [
{
"name": "darwin-debug",
"configurePreset": "darwin-debug",
"displayName": "Darwin Local Compilation (Debug)",
"description": "NetEase MSS C wrapper for macOS - Debug Configuration",
"configuration": "Debug"
},
{
"name": "darwin-release-x86_64",
"configurePreset": "darwin-release-x86_64",
"displayName": "Darwin x86_64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for macOS x86_64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "darwin-release-arm64",
"configurePreset": "darwin-release-arm64",
"displayName": "Darwin x86_64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for macOS arm64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "ios-release-arm64",
"configurePreset": "ios-release-arm64",
"displayName": "iOS arm64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for iOS arm64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "ios-release-armv7",
"configurePreset": "ios-release-armv7",
"displayName": "iOS armv7 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for iOS armv7 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "ios-release-x86_64",
"configurePreset": "ios-release-x86_64",
"displayName": "iOS x86_64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for iOS x86_64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "android-release-x86_64",
"configurePreset": "android-release-x86_64",
"displayName": "Android x86_64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android x86_64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "android-release-x86_64-strip",
"configurePreset": "android-release-x86_64",
"displayName": "Android x86_64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android x86_64 - Release Configuration",
"configuration": "Release",
"targets": ["install/strip"]
},
{
"name": "android-release-x86",
"configurePreset": "android-release-x86",
"displayName": "Android x86 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android x86 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "android-release-x86-strip",
"configurePreset": "android-release-x86",
"displayName": "Android x86 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android x86 - Release Configuration",
"configuration": "Release",
"targets": ["install/strip"]
},
{
"name": "android-release-armeabi-v7a",
"configurePreset": "android-release-armeabi-v7a",
"displayName": "Android armeabi-v7a Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android armeabi-v7a - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "android-release-armeabi-v7a-strip",
"configurePreset": "android-release-armeabi-v7a",
"displayName": "Android armeabi-v7a Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android armeabi-v7a - Release Configuration",
"configuration": "Release",
"targets": ["install/strip"]
},
{
"name": "android-release-arm64-v8a",
"configurePreset": "android-release-arm64-v8a",
"displayName": "Android arm64-v8a Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Android arm64-v8a - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "windows-debug",
"configurePreset": "windows-debug",
"displayName": "Windows Local Compilation (Debug)",
"description": "NetEase MSS C wrapper for Windows - Debug Configuration",
"configuration": "Debug"
},
{
"name": "win32-release-x64",
"configurePreset": "win32-release-x64",
"displayName": "Windows x64 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Windows x64 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
},
{
"name": "win32-release-ia32",
"configurePreset": "win32-release-ia32",
"displayName": "Windows ia32 Local Compilation (Release)",
"description": "NetEase MSS C wrapper for Windows ia32 - Release Configuration",
"configuration": "Release",
"targets": ["install"]
}
],
"testPresets": [
{
"name": "darwin-debug",
"configurePreset": "darwin-debug",
"output": {"outputOnFailure": true},
"execution": {"noTestsAction": "error", "stopOnFailure": true}
},
{
"name": "darwin-release-arm64",
"configurePreset": "darwin-release-arm64",
"output": {"outputOnFailure": true},
"execution": {"noTestsAction": "error", "stopOnFailure": true}
}
]
}

CMakePreset 中可以针对某个平台一些通用的配置生成一个隐藏配置,其他的配置项可以继承自它,如上面示例中 macOS 平台基础配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "macos",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"generator": "Xcode",
"warnings": {"dev": true, "deprecated": true},
"cacheVariables": {
"BUILD_TESTING": "OFF"
}
}

通过 hidden 参数告诉 CMake 这是一个隐藏配置,你不需要展示它,并且通过 condition 配置来决定哪个平台可以使用此配置,其他是一些基础信息配置,具体配置参数我们这里不多介绍,参考 CMake 官方文档即可。当其他配置需要依赖此基础配置时,通过指定 inherits 参数就可以,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
{
"name": "darwin-debug",
"inherits": "macos",
"displayName": "Darwin 10.14+ (Debug)",
"description": "NetEase MSS C wrapper for macOS - Debug Configuration",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"BUILD_TESTING": "ON",
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/darwin-debug"
}
}

在配置好 CMakePressets.json 后,你的 README 再也不需要写又臭又长的编译指令了,几句话即可表达清楚所有内容,如果想了解工程有哪些支持的配置,使用如下命令查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
➜  ne-mss-c git:(main) ✗ cmake --list-presets
Available configure presets:

"darwin-debug" - Darwin 10.14+ (Debug)
"darwin-release-arm64" - Darwin arm64 10.14+ (Release)
"darwin-release-x86_64" - Darwin x86_64 10.14+ (Release)
"ios-release-arm64" - iOS arm64 9.0+ (Release)
"ios-release-armv7" - iOS armv7 9.0+ (Release)
"ios-release-x86_64" - iOS x86_64 9.0+ (Release)
"android-release-x86_64" - Android x86_64 abi21 (Release)
"android-release-x86" - Android x86 abi21 (Release)
"android-release-armeabi-v7a" - Android armeabi-v7a abi21 (Release)
"android-release-arm64-v8a" - Android arm64-v8a abi21 (Release)

使用 cmake 指令携带 –preset 参数即可编译指定平台、架构的产物,如:

1
2
cmake --preset=ios-release-arm64
cmake --build --preset=ios-release-arm64

使用 –preset 命令生成工程项目文件的时候,会先打印出当前配置指定的所有参数:

1
2
3
4
5
6
7
8
9
10
11
12
➜  ne-mss-c git:(main) ✗ cmake --preset=ios-release-arm64
Preset CMake variables:

BUILD_TESTING="OFF"
CMAKE_BUILD_TYPE="Release"
CMAKE_INSTALL_PREFIX="/Users/jj.deng/Documents/yunxin/ne-mss-c/ios-release-arm64"
CMAKE_OSX_ARCHITECTURES="arm64"
CMAKE_OSX_DEPLOYMENT_TARGET="9.0"
CMAKE_OSX_SYSROOT="iphoneos"
CMAKE_SYSTEM_NAME="iOS"
CONAN_PROFILE_BUILD="/Users/jj.deng/Documents/yunxin/ne-mss-c/.profiles/darwin-x86_64"
CONAN_PROFILE_HOST="/Users/jj.deng/Documents/yunxin/ne-mss-c/.profiles/ios-arm64-iphoneos"

更重要的是,主流的 IDE 、代码编辑器在打开工程时会自动识别 CMakePresets.json 配置文件,以下是 VSCode 和 CLion 打开工程时的提示:

VSCode

CLion

使用 CLion 打开工程后,右下角会提示发现了新的 presets 文件:

点击 View 按钮后即可看到所有支持的配置:

总结

通过在工程根目录下添加 CMakePresets.json,我们不仅实现了主流开发工具的自动初始化工程编译,而且所有配置是固化在配置文件中的并且与日常开发、MR 流程息息相关,我们不会因为代码提交后忘记更新文档等内容导致后来者很难介入到项目的开发中。

跨平台工程管理只是整个 DevOps 流程中非常小的一块内容,但我个人认为也是除了分支管理、版本管理以外最重要的一块内容,它与开发人员的日常息息相关,直接影响到工作效率。一个好的工程管理不是文档写的多么详细,而是不需要文档、不需要口口相传就可以让新人和久经沙场的开发人员快速进入状态。希望能给那些想提高研发流程优化、提效的团队一些启发。