vscode结合docker配置c++开发环境

工具链

构建工具:cmake

编译器:gcc/clang

调试器:lldb

LSP后端:clangd

可选:

代码格式化:clang-format

静态检查:clang-tidy

包管理:vcpkg/apt

环境管理:docker/vcpkg(manifest)
vscode有用插件:https://juejin.cn/post/7051434324565950501

基础环境

使用clang配置环境;

https://developer.baidu.com/article/detail.html?id=2820197

devcontainter.json

https://learnku.com/docs/learn-docker-together/1/devcontainerjson/13228

pull得到dokcer基础镜像

参考链接(1)**如何使用docker部署c/c++程序:**https://blog.csdn.net/len_yue_mo_fu/article/details/80189035

安装Cmake>=3.17:

参考链接:https://zhuanlan.zhihu.com/p/519732843
apt-get -y install libssl-dev

# 使用基础镜像
FROM ubuntu:18.04
#FROM ubuntu:18.04

# 安装必要的软件包
RUN apt-get update && \
    apt-get install -y cmake build-essential clang lldb git

# 复制程序源代码到容器中
COPY . /usr/src
# 创建 build 目录并进入
#WORKDIR /app/code
# 编译程序
#RUN cmake .. && make
# 设置容器启动时执行的命令
#CMD ["./my_program"]

#作者:MIKE
#链接:https://www.zhihu.com/question/589427102/answer/2939404336
#来源:知乎
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

开发套件(安装已写在dockerfile中)

apt install cmake build-essential clang lldb

vcpkg安装

git clone https://github.com/microsoft/vcpkg.git 17 cp -ar src/third_part/vcpkg/ ./ 18 ll 19 cd vcpkg/ 20 ll -a 21 ./bootstrap-vcpkg.sh 22 apt install curl 23 apt install zip unzip tar 24 ./bootstrap-vcpkg.sh

cmake编译过程:

cmake .. -DCMAKE_TOOLCHAIN_FILE=/usr/local/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt

外部构建

  1. 在当前目录下,创建build文件夹

mkdir build

  1. 进入到build文件夹

cd build

  1. 编译上级目录的CMakeLists.txt,生成Makefile和其他文件

cmake …

  1. 执行make命令,生成target

make

需要在途中安装的包

apt-get install libgmp-dev

apt-get install libmpfr-dev

apt-get install libboost-all-dev

安装 libboost-all-dev需要大于1.66以上版本:(离线编译)

官方源码位置:https://www.boost.org/users/download/

wget https://boostorg.jfrog.io/artifactory/main/release/1.84.0/source/boost_1_84_0.tar.gz **tar -xzvf boost_1_84_0.tar.gz**

cd boost_1_84_0

./bootstrap.sh

./b2

./b2 --toolset=gcc

./b2 install

克隆KSR项目代码:

git clone https://github.com/soesau/cgal.git
5 git clone -b Kinetic_surface_reconstruction-new_package-soesau https://github.com/soesau/cgal.git
6 git clone -b Kinetic_surface_reconstruction-new_package-soesau https://github.com/soesau/cgal.git --depth 1

https://cgal.github.io/7908/v0/Kinetic_surface_reconstruction/index.html#ksrParametersExample

https://hub.nuaa.cf/CGAL/cgal/pull/7908

编译官方发布的程序示例:

https://cgal.github.io/7908/v0/Kinetic_surface_reconstruction/Kinetic_surface_reconstruction_2building_8cpp-example.html

Get started with vcpkg

docker:

Ubuntu

vscode插件

  • twxs.cmake: cmake语法支持

  • ms-vscode.cmake-tools: cmake功能支持

  • llvm-vs-code-extensions.vscode-clangd: clangd LSP, 集成clang-tidy, clang-format, cpp语法支持, 代码补全、跳转、重构、错误检查、格式化

    需要安装clangd server:apt install clangd

  • vadimcn.vscode-lldb :lldb本地调试支持

可选:

  • cheshirekow.cmake-format: cmake格式化

    需要安装cmake-format:apt install cmake-format

  • vivaxy.vscode-conventional-commits: git提交信息规范

  • donjayamanne.githistory: git历史记录

  • eamodio.gitlens: git增强

  • codezombiech.gitignore: gitignore文件生成

  • github.vscode-pull-request-github: github PR和issue集成

  • cschlosser.doxdocgen: doxygen注释生成

  • yatki.vscode-surround: 代码块包围

  • guyutongxue.cpp-reference: cppreference跳转

Vscode编写C++项目:

https://www.zhihu.com/question/353722203

使用lldb

https://blog.csdn.net/itas109/article/details/122677006

lldb

launch.json

{
    // lldb for cmake buildsystem
    // vscode-cmake-tools & vscode-lldb required
    // template from https://vector-of-bool.github.io/docs/vscode-cmake-tools/debugging.html
    // template from https://github.com/vadimcn/vscode-lldb/blob/v1.7.4/MANUAL.md
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb) Launch",
            // Resolved by codeLLDB
            "type": "lldb",
            "request": "launch",
            // Resolved by CMake Tools:
            "program": "${command:cmake.launchTargetPath}",
            "args": [],
            // "stopAtEntry": false,
            "cwd": "${workspaceFolder}"
        }
    ]
}

clangd

https://clangd.llvm.org/installation#project-setup

按官方的说法,clangd需要build flags才能理解代码,cmake已经提供了这些信息,只需确保cmake的CMAKE_EXPORT_COMPILE_COMMANDS标志开启即可,可以配置cmake的build args,也可以直接在CMakeLists.txt中添加:

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

clangd同时提供了clang-tidy和clang-format的功能,参考配置如下

settings.json

{
    "clangd.arguments": [
        "--header-insertion=never",
        "--background-index",
        "--compile-commands-dir=build",
        "-j=12",
        "--query-driver=/usr/bin/clang++",
        "--clang-tidy",
        "--clang-tidy-checks=performance-*,bugprone-*",
        "--all-scopes-completion",
        "--completion-style=detailed",
        "--pch-storage=disk",
        "--header-insertion-decorators",
        "--pretty"
    ]
}

.clang-format

---
BasedOnStyle: LLVM
# AccessModifierOffset: -4AlignAfterOpenBracket: Align
AllowAllArgumentsOnNextLine: true
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AllowAllConstructorInitializersOnNextLine: true
AlignEscapedNewlines: Left
AlignOperands: true
# AlignTrailingComments: falseAllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: All
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
#AllowShortLambdasOnASingleLine: InlineAllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
  AfterCaseLabel: true
  AfterClass: true
  AfterControlStatement: true
  AfterEnum: true
  AfterFunction: true
  AfterNamespace: true
  AfterObjCDeclaration: true
  AfterStruct: true
  AfterUnion: true
  AfterExternBlock: false
  BeforeCatch: true
  BeforeElse: true
  IndentBraces: false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
# BreakBeforeTernaryOperators: falseBreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon
ColumnLimit: 0
CommentPragmas: "suppress"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
# ConstructorInitializerIndentWidth: 4# ContinuationIndentWidth: 4Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
# FixNamespaceComments: falseIncludeBlocks: Regroup
IncludeCategories:
    - Regex: '^.*(precomp|pch|stdafx)'
      Priority: -1
    - Regex: '^".*"'
      Priority: 1
    - Regex: '^<.*>'
      Priority: 2
    - Regex: '.*'
      Priority: 3
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: "BEGIN_TEST_METHOD_PROPERTIES|BEGIN_MODULE|BEGIN_TEST_CLASS|BEGIN_TEST_METHOD"
MacroBlockEnd: "END_TEST_METHOD_PROPERTIES|END_MODULE|END_TEST_CLASS|END_TEST_METHOD"
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
# ReflowComments: falseSortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
TabWidth: 2
UseTab: Never
# NamespaceIndentation: All# SpaceAfterTemplateKeyword: 'false'# SpaceBeforeCtorInitializerColon: 'true'# SpaceBeforeInheritanceColon: 'true'# SpaceBeforeParens: ControlStatements# SpaceBeforeRangeBasedForLoopColon: 'true'# SpaceInEmptyBlock: true

关于左花括号是否应该另起,llvm和google的规范都建议不另起新行,但是考虑某些特殊情况,另起对于写和读都有好处(参考以下),因此上述格式化配置采用左花括号另起新行的风格。

Should curly braces appear on their own line?

.clang-tidy (照搬blender的)

# The warnings below are disabled because they are too pedantic and not worth fixing.# Some of them will be enabled as part of the Clang-Tidy task, see T78535.# NOTE: No comments in the list below is allowed. Clang-tidy will ignore items after comments in the lists flag list.# This is because the comment is not a valid list item and it will stop parsing flags if a list item is a comment.Checks:  >
  -*,
  readability-*,
  -readability-uppercase-literal-suffix,
  -readability-magic-numbers,
  -readability-isolate-declaration,
  -readability-convert-member-functions-to-static,
  -readability-implicit-bool-conversion,
  -readability-avoid-const-params-in-decls,
  -readability-simplify-boolean-expr,
  -readability-make-member-function-const,
  -readability-suspicious-call-argument,
  -readability-redundant-member-init,
  -readability-misleading-indentation,
  -readability-use-anyofallof,
  -readability-identifier-length,

  -readability-function-cognitive-complexity,

  bugprone-*,
  -bugprone-narrowing-conversions,
  -bugprone-unhandled-self-assignment,
  -bugprone-branch-clone,
  -bugprone-macro-parentheses,
  -bugprone-reserved-identifier,
  -bugprone-easily-swappable-parameters,
  -bugprone-implicit-widening-of-multiplication-result,

  -bugprone-sizeof-expression,
  -bugprone-integer-division,

  -bugprone-redundant-branch-condition,

  -bugprone-suspicious-include,

  modernize-*,
  -modernize-use-auto,
  -modernize-use-trailing-return-type,
  -modernize-avoid-c-arrays,
  -modernize-use-nodiscard,
  -modernize-loop-convert,
  -modernize-pass-by-value,
  -modernize-raw-string-literal,
  -modernize-return-braced-init-list

CheckOptions:
  - key: modernize-use-default-member-init.UseAssignment
    value: 1

参考:

Clang-Format Style Options — Clang 18.0.0git documentation

clang-tidy - Clang-Tidy Checks — Extra Clang Tools 18.0.0git documentation

cmake-format

.cmake-format

format:
  tab_size: 2
  line_width: 80
  dangle_parens: true

parse:
  additional_commands:
    cpmaddpackage:
      pargs:
        nargs: '*'
        flags: []
      spelling: CPMAddPackage
      kwargs: &cpmaddpackagekwargs
        NAME: 1
        FORCE: 1
        VERSION: 1
        GIT_TAG: 1
        DOWNLOAD_ONLY: 1
        GITHUB_REPOSITORY: 1
        GITLAB_REPOSITORY: 1
        GIT_REPOSITORY: 1
        SVN_REPOSITORY: 1
        SVN_REVISION: 1
        SOURCE_DIR: 1
        DOWNLOAD_COMMAND: 1
        FIND_PACKAGE_ARGUMENTS: 1
        NO_CACHE: 1
        GIT_SHALLOW: 1
        URL: 1
        URL_HASH: 1
        URL_MD5: 1
        DOWNLOAD_NAME: 1
        DOWNLOAD_NO_EXTRACT: 1
        HTTP_USERNAME: 1
        HTTP_PASSWORD: 1
        OPTIONS: +
    cpmfindpackage:
      pargs:
        nargs: '*'
        flags: []
      spelling: CPMFindPackage
      kwargs: *cpmaddpackagekwargs
    packageproject:
      pargs:
        nargs: '*'
        flags: []
      spelling: packageProject
      kwargs:
        NAME: 1
        VERSION: 1
        NAMESPACE: 1
        INCLUDE_DIR: 1
        INCLUDE_DESTINATION: 1
        BINARY_DIR: 1
        COMPATIBILITY: 1
        VERSION_HEADER: 1
        DEPENDENCIES: +

Tips

环境隔离:

  • 可以使用vcpkg的manifest功能,将依赖的包列表写入vcpkg.json,然后使用vcpkg的cmake集成自动安装依赖,这样可以保证每个项目的依赖环境隔离。

    参考:

    Get started with vcpkg

    vcpkg.json Reference

  • 可以使用docker + dev container的方式,将开发环境隔离,每个项目使用不同的docker镜像,使用vscode自动连接到docker容器。

    参考:

你可能感兴趣的:(vscode,docker,c++)