vscode+cmake构建接近完美的C++跨平台开发环境

309 阅读3分钟

开发环境

linux

# 安装 python3
sudo apt install python3-pip
# 安装 cmake (比用 apt 安装的版本更高)
sudo pip3 install cmake
# 安装 cmake_format 
sudo pip3 install cmake_format 
# 安装 llvm clangd-15
sudo apt install llvm-15 clangd-15

sudo apt install git build-essential gdb
# bear 可以从 makefile 生成 compile_commands.json
# 使用方法 bear -- make -j$(nproc)
sudo apt install bear

windows

# 需要管理员权限的powershell
# 安装choco
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

# 安装 python3
choco install python
# 安装 cmake_format 
pip install --force-reinstall cmakelang
# 安装 cmake
choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"'
# 安装 llvm
choco install llvm
# 安装 git
choco install -y git
# 安装 ninja
choco install -y ninja

安装vs2017

新建文件C:\vs2107.vsconfig

{
  "version": "1.0",
  "components": [
    "Microsoft.VisualStudio.Component.Roslyn.Compiler",
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Component.CoreBuildTools",
    "Microsoft.VisualStudio.Workload.MSBuildTools",
    "Microsoft.VisualStudio.Component.Windows10SDK",
    "Microsoft.VisualStudio.Component.VC.CoreBuildTools",
    "Microsoft.VisualStudio.Component.Static.Analysis.Tools",
    "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
    "Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
    "Microsoft.VisualStudio.Component.Windows10SDK.17763",
    "Microsoft.VisualStudio.Component.VC.CMake.Project",
    "Microsoft.VisualStudio.Component.TestTools.BuildTools",
    "Microsoft.Component.VC.Runtime.UCRTSDK",
    "Microsoft.VisualStudio.Component.VC.ATL",
    "Microsoft.VisualStudio.Component.WinXP",
    "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.WinXP",
    "Microsoft.VisualStudio.Workload.VCTools",
     "microsoft.visualstudio.component.vc.runtimes.x86.x64.spectre"
  ]
}
# 需要管理员权限的powershell
# 安装 vs2017
choco install -y visualstudio2017buildtools --package-parameters "--config C:\vs2017.vsconfig"

Macos

# 安装 xcode
xcode-select --install

# 安装brew使用中科大的镜像加速
# 添加到 ~/.bashrc 或 ~/.zshrc
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.ustc.edu.cn/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.ustc.edu.cn/homebrew-core.git"
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.ustc.edu.cn/homebrew-bottles"
export HOMEBREW_API_DOMAIN="https://mirrors.ustc.edu.cn/homebrew-bottles/api"

# 安装brew
/bin/bash -c "$(curl -fsSL https://mirrors.ustc.edu.cn/misc/brew-install.sh)"

# 安装 python3
brew install python
# 安装 cmake_format 
pip install cmake_format 
# 安装 cmake
brew install cmake
# 安装 llvm (apple-clang使用起来有很多限制)
brew install llvm@14 

vscode 插件

微软官方的 C/C++ 插件, 提供智能提示和 debug 等功能

为 vscode 提供 CMake 支持

提供单元测试(gtest)支持

clangd能提供更好的补全和提示,速度比vscode c/c++插件更快

和vscode c/c++同时使用会有冲突, 需要在 settings.json 中配置禁用vscode c/c++智能提示

"C_Cpp.intelliSenseEngine": "disabled",

  • GitHub.copilot 和 GitHub Copilot Chat

AI代码生成工具,真的很好用

macos 自带的 lldb 使用起来卡, 使用CodeLLDB 这个插件提供的 debug 功能

git 提交记录查询

其它一些好用的插件

Generating implementation for c++ declarations.

Generating header guard for headers.

文件自动注释, 函数注释生成

工程配置

{
    "C_Cpp.intelliSenseEngine": "disabled",
    // git 禁用以下功能提升性能
    "git.enableSmartCommit": false,
    "git.autofetch": false,
    "git.confirmSync": false,
    // cmake 
    "cmake.saveBeforeBuild": true,
    // clangd
    "cmake.copyCompileCommands": "${workspaceFolder}/.vscode/compile_commands.json",
    // 编辑器设置
    "editor.insertSpaces": true,
    "editor.tabSize": 4,
    "editor.formatOnSave": true,
    "editor.rulers": [
        120
    ],
    "files.autoSave": "onFocusChange", /** 自动保存关闭,提升性能;cmake编译前会自动保存 **/
    "files.exclude": {
        "**/.git": true,
        "**/.DS_Store": true
    },
    "editor.tokenColorCustomizations": {
        "textMateRules": [
            {
                "scope": "googletest.failed",
                "settings": {
                    "foreground": "#f00"
                }
            },
            {
                "scope": "googletest.passed",
                "settings": {
                    "foreground": "#0f0"
                }
            },
            {
                "scope": "googletest.run",
                "settings": {
                    "foreground": "#0f0"
                }
            }
        ]
    },
    // 头文件注释自动生成
    "fileheader.customMade": {
        // 自动提取当前git config中的: 用户名、邮箱
        "Author": "git config user.name && git config user.email", // 同时获取用户名与邮箱
        "LastEditors": "git config user.name && git config user.email", // 文件最后编辑者 与Author字段一致
        "LastEditTime": "Do not edit", // 文件最后编辑时间
        "custom_string_obkoro1_copyright": ""
    },
    // 单元测试插件配置
    "testMate.cpp.test.advancedExecutables": [
        {
            "pattern": "${command:cmake.buildDirectory}/**/*{test,Test,TEST}*"
        }
    ],
    "testMate.cpp.debug.configTemplate": {
        "type": "${assert:testMate.cpp.debug.configTemplate doesn't support this platform.}",
        "linux": {
            "type": "cppdbg",
            "MIMode": "gdb"
        },
        "darwin": {
            "type": "lldb",
            "env": {
                "ASAN_OPTIONS": "detect_leaks=1",
                "LSAN_OPTIONS": "suppressions=leaksanitizer.supp",
                "DYLD_LIBRARY_PATH": "${command:cmake.buildDirectory}/lib"
            },
        },
        "win32": {
            "type": "cppvsdbg"
        },
        "preLaunchTask": "CMake: build",
        "program": "${exec}",
        "args": "${argsArray}",
        "cwd": "${command:cmake.launchTargetDirectory}",
        "sourceFileMap": "${sourceFileMapObj}",
        "externalConsole": false
    },
    "testMate.cpp.debug.noThrow": false,
}

提供调试或运行前编译 cmake 项目的 task

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cmake",
            "label": "CMake: build",
            "command": "build",
            "targets": [
                "all"
            ],
            "preset": "${command:cmake.activeBuildPresetName}",
            "group": "build",
            "problemMatcher": [],
            "detail": "CMake build task"
        }
    ]
}

调试配置

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "(lldb) Launch",
            "sourceLanguages": [
                "cpp"
            ],
            "program": "${command:cmake.launchTargetPath}",
            "args": [],
            "cwd": "${command:cmake.launchTargetDirectory}",
            "env": {
                "ASAN_OPTIONS": "detect_leaks=1",
                "LSAN_OPTIONS": "suppressions=leaksanitizer.supp",
                "DYLD_LIBRARY_PATH": "${command:cmake.buildDirectory}/lib"
            },
            "preLaunchTask": "CMake: build"
        },
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "MIMode": "gdb",
            "request": "launch",
            "program": "${command:cmake.launchTargetPath}",
            "environment": [],
            "args": [],
            "cwd": "${command:cmake.launchTargetDirectory}",
            "preLaunchTask": "CMake: build"
        },
        {
            "name": "(msvc) Launch",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "${command:cmake.launchTargetPath}",
            "args": [],
            "cwd": "${command:cmake.launchTargetDirectory}",
            "console": "externalTerminal",
            "preLaunchTask": "CMake: build"
        },
    ]
}

.gitignore

cmake-build-*/

.vscode/.cache/
.vscode/compile_commands.json

.clangd 配置

CompileFlags:
    CompilationDatabase: ./.vscode

.clang-format 代码风格设置(文件保存时自动格式化)

BasedOnStyle: Chromium
ColumnLimit: 120
BreakBeforeBraces: Attach
IndentWidth: 4
SortIncludes: false
BreakConstructorInitializers: BeforeComma
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
AccessModifierOffset: -4

.clang-tidy 基于clang的C++静态分析工具

---
# NOTE there must be no spaces before the '-', so put the comma last.
# The check bugprone-unchecked-optional-access is also turned off atm
# because it causes clang-tidy to hang randomly. The tracking issue
# can be found at https://github.com/llvm/llvm-project/issues/69369.
InheritParentConfig: true
Checks: '
bugprone-*,
-bugprone-easily-swappable-parameters,
-bugprone-forward-declaration-namespace,
-bugprone-macro-parentheses,
-bugprone-lambda-function-name,
-bugprone-reserved-identifier,
-bugprone-swapped-arguments,
-bugprone-unchecked-optional-access,
clang-diagnostic-missing-prototypes,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-interfaces-global-init,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-cstyle-cast,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-static-cast-downcast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-vararg,
-cppcoreguidelines-special-member-functions,
-cppcoreguidelines-non-private-member-variables-in-classes,
-facebook-hte-RelativeInclude,
hicpp-exception-baseclass,
hicpp-avoid-goto,
misc-*,
-misc-const-correctness,
-misc-include-cleaner,
-misc-use-anonymous-namespace,
-misc-unused-parameters,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
-misc-confusable-identifiers,
modernize-*,
-modernize-macro-to-enum,
-modernize-return-braced-init-list,
-modernize-use-auto,
-modernize-use-default-member-init,
-modernize-use-using,
-modernize-use-trailing-return-type,
-modernize-use-nodiscard,
performance-*,
readability-container-size-empty,
readability-delete-null-pointer,
readability-duplicate-include
readability-misplaced-array-index,
readability-redundant-function-ptr-dereference,
readability-redundant-smartptr-get,
readability-simplify-subscript-expr,
readability-string-compare,
'
HeaderFilterRegex: '^(aten/|c10/|torch/).*$'
WarningsAsErrors: '*'
...

CMakePresets.json

{
    "version": 3,
    "configurePresets": [
        {
            "name": "windows-base",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/cmake-build-${presetName}",
            "toolset": {
                "value": "v141",
                "strategy": "external"
            },
            "cacheVariables": {
                "CMAKE_C_COMPILER": "cl.exe",
                "CMAKE_CXX_COMPILER": "cl.exe",
                "CMAKE_SYSTEM_VERSION": "10.0",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            },
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Windows"
            }
        },
        {
            "name": "linux-base",
            "hidden": true,
            "displayName": "Linux base",
            "generator": "Unix Makefiles",
            "binaryDir": "${sourceDir}/cmake-build-${presetName}",
            "cacheVariables": {
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            },
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Linux"
            }
        },
        {
            "name": "macos-base",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/cmake-build-${presetName}",
            "cacheVariables": {
                "CMAKE_C_COMPILER": "/usr/local/opt/llvm@14/bin/clang",
                "CMAKE_CXX_COMPILER": "/usr/local/opt/llvm@14/bin/clang++",
                "CMAKE_OSX_DEPLOYMENT_TARGET": "10.9",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            },
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Darwin"
            }
        },
        {
            "name": "x64-debug",
            "displayName": "x64 Debug",
            "inherits": "windows-base",
            "architecture": {
                "value": "x64",
                "strategy": "external"
            },
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        },
        {
            "name": "x64-release",
            "displayName": "x64 Release",
            "inherits": "x64-debug",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"
            }
        },
        {
            "name": "x86-debug",
            "displayName": "x86 Debug",
            "inherits": "windows-base",
            "architecture": {
                "value": "x86",
                "strategy": "external"
            },
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        },
        {
            "name": "x86-release",
            "displayName": "x86 Release",
            "inherits": "x86-debug",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"
            }
        },
        {
            "name": "linux-debug",
            "displayName": "Linux x64 Debug",
            "inherits": "linux-base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        },
        {
            "name": "linux-release",
            "displayName": "Linux x64 Release",
            "inherits": "linux-base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "RelWithDebInfo"
            }
        },
        {
            "name": "macos-debug",
            "displayName": "macos x64 Debug",
            "inherits": "macos-base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug"
            }
        },
        {
            "name": "macos-release",
            "displayName": "macos x64 Release",
            "inherits": "macos-base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"
            }
        }
    ]
}