痛苦
本地开发需要输入参数太多
刚开始做纯 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 的工程命令将是这样的:
代码语言:javascript复制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,那后面两个阶段可以不做配置。一个完整的 配置文件如下:
代码语言:javascript复制{
"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 平台基础配置:
代码语言:javascript复制{
"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 参数就可以,如下所示:
代码语言:javascript复制{
"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 再也不需要写又臭又长的编译指令了,几句话即可表达清楚所有内容,如果想了解工程有哪些支持的配置,使用如下命令查看:
代码语言:javascript复制➜ 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 参数即可编译指定平台、架构的产物,如:
代码语言:javascript复制cmake --preset=ios-release-arm64
cmake --build --preset=ios-release-arm64
使用 –preset 命令生成工程项目文件的时候,会先打印出当前配置指定的所有参数:
代码语言:javascript复制➜ 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 流程中非常小的一块内容,但我个人认为也是除了分支管理、版本管理以外最重要的一块内容,它与开发人员的日常息息相关,直接影响到工作效率。一个好的工程管理不是文档写的多么详细,而是不需要文档、不需要口口相传就可以让新人和久经沙场的开发人员快速进入状态。希望能给那些想提高研发流程优化、提效的团队一些启发。