@chengzhao-dev/dsh-cpp-workflow 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.en.md +107 -0
- package/README.md +106 -2
- package/cordis.patch.yml +14 -0
- package/icon.svg +7 -0
- package/lib/index.js +203 -0
- package/lib/workspace.js +168 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +81 -4
- package/skills/building-cpp/SKILL.md +44 -0
- package/skills/building-cpp/assets/cmake/applying-warnings.cmake +10 -0
- package/skills/building-cpp/assets/cmake/fetching-googletest.cmake +15 -0
- package/skills/building-cpp/assets/cmake/setting-rpath.cmake +8 -0
- package/skills/building-cpp/assets/config/.clang-format +40 -0
- package/skills/building-cpp/assets/config/.clang-tidy +92 -0
- package/skills/building-cpp/assets/config/.clangd +12 -0
- package/skills/building-cpp/assets/config/.vscode/extensions.json +6 -0
- package/skills/building-cpp/assets/config/.vscode/settings.json +34 -0
- package/skills/building-cpp/assets/templates/projects/common/running-build.sh +152 -0
- package/skills/building-cpp/assets/templates/projects/multi/CMakeLists.txt +18 -0
- package/skills/building-cpp/assets/templates/projects/multi/include/greeting.h +10 -0
- package/skills/building-cpp/assets/templates/projects/multi/src/greeting.cpp +13 -0
- package/skills/building-cpp/assets/templates/projects/multi/src/main.cpp +8 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/CMakeLists.txt +24 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/CMakeLists.txt +5 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/include/greeting.h +10 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/src/greeting.cpp +13 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/src/main.cpp +8 -0
- package/skills/building-cpp/assets/templates/projects/single/CMakeLists.txt +14 -0
- package/skills/building-cpp/assets/templates/projects/single/src/main.cpp +9 -0
- package/skills/building-cpp/assets/templates/projects/static-library/CMakeLists.txt +18 -0
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/CMakeLists.txt +5 -0
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/include/greeting.h +10 -0
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/src/greeting.cpp +13 -0
- package/skills/building-cpp/assets/templates/projects/static-library/src/main.cpp +8 -0
- package/skills/building-cpp/examples/cmake.md +150 -0
- package/skills/building-cpp/examples/environment.md +125 -0
- package/skills/building-cpp/examples/tooling.md +155 -0
- package/skills/building-cpp/references/build-script.md +63 -0
- package/skills/building-cpp/references/cmake.md +168 -0
- package/skills/building-cpp/references/environment.md +104 -0
- package/skills/building-cpp/references/linking.md +101 -0
- package/skills/building-cpp/references/static-analysis.md +136 -0
- package/skills/building-cpp/scripts/checking-environment.mjs +498 -0
- package/skills/building-cpp/steps/01-build.md +76 -0
- package/skills/building-cpp/steps/02-tooling.md +41 -0
- package/skills/building-cpp/steps/03-check.md +60 -0
- package/skills/developing-cpp/SKILL.md +42 -0
- package/skills/developing-cpp/examples/comments.md +231 -0
- package/skills/developing-cpp/examples/exceptions.md +134 -0
- package/skills/developing-cpp/examples/naming.md +157 -0
- package/skills/developing-cpp/examples/structure.md +79 -0
- package/skills/developing-cpp/references/comments.md +123 -0
- package/skills/developing-cpp/references/declaration-order.md +97 -0
- package/skills/developing-cpp/references/exceptions.md +79 -0
- package/skills/developing-cpp/references/glossary.md +88 -0
- package/skills/developing-cpp/references/google-cpp-style.md +109 -0
- package/skills/developing-cpp/references/language.md +119 -0
- package/skills/developing-cpp/references/layout.md +73 -0
- package/skills/developing-cpp/references/naming.md +62 -0
- package/skills/developing-cpp/references/performance.md +82 -0
- package/skills/developing-cpp/references/project-design.md +79 -0
- package/skills/developing-cpp/references/standard-library.md +100 -0
- package/skills/developing-cpp/references/types.md +147 -0
- package/skills/developing-cpp/steps/01-behavior.md +36 -0
- package/skills/developing-cpp/steps/02-boundary.md +40 -0
- package/skills/developing-cpp/steps/03-declaration.md +32 -0
- package/skills/developing-cpp/steps/04-implementation.md +33 -0
- package/templates/cpp-workflow-project/SKILL.md +49 -0
- package/templates/cpp-workflow-project/environment.json +5 -0
- package/templates/cpp-workflow-project/stages/stage-table.md +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,83 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chengzhao-dev/dsh-cpp-workflow",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "C++20 工程流程技能包:源码四步与构建三步,按项目声明的环境组合校验 · C++20 workflow skills for DeepSeek Harness",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./lib/index.js",
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
"./cordis.patch.yml": "./cordis.patch.yml"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"lib",
|
|
14
|
+
"skills",
|
|
15
|
+
"cordis.patch.yml",
|
|
16
|
+
"locale",
|
|
17
|
+
"icon.svg",
|
|
18
|
+
"README.md",
|
|
19
|
+
"README.en.md",
|
|
20
|
+
"LICENSE",
|
|
21
|
+
"templates"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=22",
|
|
25
|
+
"dsh": ">=0.2.0-rc.1 <0.3.0-0"
|
|
26
|
+
},
|
|
27
|
+
"dsh": {
|
|
28
|
+
"bundle": {
|
|
29
|
+
"patch": "./cordis.patch.yml"
|
|
30
|
+
},
|
|
31
|
+
"catalog": {
|
|
32
|
+
"category": "skill",
|
|
33
|
+
"summary": {
|
|
34
|
+
"zh": "按项目声明的环境组合,推进 C++20 源码与构建流程",
|
|
35
|
+
"en": "Advance C++20 source and build work with a project-declared environment"
|
|
36
|
+
},
|
|
37
|
+
"capabilities": [
|
|
38
|
+
"skills"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"icon": "./icon.svg",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.json",
|
|
45
|
+
"test": "npm run build && node scripts/checking-skill-links.mjs && node --test tests/*.test.mjs",
|
|
46
|
+
"check": "npm test",
|
|
47
|
+
"pack:check": "npm pack --dry-run"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"dsh",
|
|
51
|
+
"dsh-plugin",
|
|
52
|
+
"deepseek-harness",
|
|
53
|
+
"cpp",
|
|
54
|
+
"c++",
|
|
55
|
+
"cplusplus",
|
|
56
|
+
"cmake",
|
|
57
|
+
"ninja",
|
|
58
|
+
"clang",
|
|
59
|
+
"gcc",
|
|
60
|
+
"skills"
|
|
61
|
+
],
|
|
62
|
+
"license": "MIT",
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "git+https://github.com/chengzhao-dev/dsh-cpp-workflow.git"
|
|
66
|
+
},
|
|
67
|
+
"homepage": "https://github.com/chengzhao-dev/dsh-cpp-workflow#readme",
|
|
68
|
+
"bugs": {
|
|
69
|
+
"url": "https://github.com/chengzhao-dev/dsh-cpp-workflow/issues"
|
|
70
|
+
},
|
|
71
|
+
"publishConfig": {
|
|
72
|
+
"access": "public",
|
|
73
|
+
"provenance": true
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@deepseek-ai/dsh-skill": ">=0.2.0-rc.1 <0.3.0-0"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@deepseek-ai/dsh-skill": ">=0.2.0-rc.1 <0.3.0-0",
|
|
80
|
+
"@types/node": "^22.20.5",
|
|
81
|
+
"typescript": "^5.9.3"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: building-cpp
|
|
3
|
+
description: 用 CMake、Ninja、clang-format、clang-tidy、clangd 配置、构建和检查 C++20 工程时使用;按定构建、定工具配置、通过检查三步推进。不用于只改源码语义、文档、Python 或与 C++ 无关的文件。
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: C++20 构建三步
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# building-cpp
|
|
9
|
+
|
|
10
|
+
## 适用场景
|
|
11
|
+
|
|
12
|
+
管 `CMakeLists.txt`、`cmake/`、`running-build.sh`、`.clang-format`、`.clang-tidy`、`.clangd`、`.vscode/` 和 `environment.json`。函数体、类型、命名、异常和源码注释只开 `developing-cpp`;一次改动同时越过库与程序的边界时,先做完 `developing-cpp` 的第 2 步,再开本技能。`.qmd`、仓库 README、Python 和非 C++ 文档不打开本技能。
|
|
13
|
+
|
|
14
|
+
编译失败先分因:诊断指向函数体,回 `developing-cpp` 的定实现;诊断指向声明或类型,回定声明;诊断是找不到头、链接失败、没有编译数据库或工具不在 PATH,留在本技能的定构建或定工具配置。
|
|
15
|
+
|
|
16
|
+
存在项目技能 `cpp-workflow-project` 时先读它的 `SKILL.md`、`environment.json` 和 `stages/stage-table.md`。三个轴为空或组合非法时停在定构建,不猜 WSL、Clang 或构建目录;环境组合空着时源码四步仍可做,只是不能构建。
|
|
17
|
+
|
|
18
|
+
## 两种走法
|
|
19
|
+
|
|
20
|
+
| 走法 | 什么时候用 | 怎么做 |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| 增量修正 | 用户点了一条链接错误、一个工具配置或一条诊断 | 先判断属于定构建还是定工具配置,只改那一处,不动无关 target 和配置 |
|
|
23
|
+
| 整段重构 | 新工程、新阶段、换环境组合,或第一次接构建 | 同样三步;先定 target 和目录,再改工具文件,最后跑完整检查 |
|
|
24
|
+
|
|
25
|
+
共同不变量:不发明项目没有声明的环境轴、命令和 target;只改格式或配置时不改可观察行为;不覆盖已有源码、`CMakeLists.txt` 和 `.clang-*`;不安装工具链;代理侧不写 `wsl` 或 `bash -lc`。后一步发现前一步没做完,退回那一步。拿不准先用增量修正;发现环境轴、编译器或构建目录需要改,退回整段,从定构建重走。
|
|
26
|
+
|
|
27
|
+
## 步骤
|
|
28
|
+
|
|
29
|
+
| 步 | 名称 | 文件 | 一句话 |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| 1 | 定构建 | `steps/01-build.md` | 一次配置一个编译器,Ninja,target-based CMake,编译数据库 |
|
|
32
|
+
| 2 | 定工具配置 | `steps/02-tooling.md` | 格式化、静态检查、clangd 各管一段,互不越界 |
|
|
33
|
+
| 3 | 通过检查 | `steps/03-check.md` | 先跑环境脚本的 `--live`,再跑项目入口,按失败位置分诊 |
|
|
34
|
+
|
|
35
|
+
每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/` 保存完整条文,只在排错、整目录重构,或步骤里明确指向某一条文时按需打开。
|
|
36
|
+
|
|
37
|
+
## 完成判据
|
|
38
|
+
|
|
39
|
+
- 项目 `environment.json` 的三个轴齐全且是合法组合;没有靠猜。
|
|
40
|
+
- 配置命令固定 Ninja 和单一编译器,`build/<compiler>/compile_commands.json` 存在,根 `build/compile_commands.json` 指向当前编译器。
|
|
41
|
+
- 标准写在 target 上,`CXX_EXTENSIONS OFF`,没有全局 `include_directories()` 或 GLOB。
|
|
42
|
+
- `clang-format --dry-run --Werror` 与 `clang-tidy` 在项目源码上零告警;只扫描项目源码和项目头。
|
|
43
|
+
- CTest 全绿,程序从该编译器的构建目录启动;失败时报告的是具体角色和原因。
|
|
44
|
+
- 没有改源码语义,没有覆盖已有工程文件,也没有安装或下载任何工具。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 固定版本拉取 GoogleTest;只在 tests/ 需要时调用。
|
|
2
|
+
include(FetchContent)
|
|
3
|
+
|
|
4
|
+
function(cpp_workflow_fetch_googletest)
|
|
5
|
+
if(POLICY CMP0135)
|
|
6
|
+
cmake_policy(SET CMP0135 NEW)
|
|
7
|
+
endif()
|
|
8
|
+
FetchContent_Declare(
|
|
9
|
+
googletest
|
|
10
|
+
URL https://codeload.github.com/google/googletest/tar.gz/refs/tags/v1.17.0
|
|
11
|
+
URL_HASH SHA256=65fab701d9829d38cb77c14acdc431d2108bfdbf8979e40eb8ae567edf10b27c
|
|
12
|
+
)
|
|
13
|
+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
14
|
+
FetchContent_MakeAvailable(googletest)
|
|
15
|
+
endfunction()
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# 让构建目录里的程序直接找到同目录的共享库;安装规则另配。
|
|
2
|
+
function(cpp_workflow_set_build_rpath target)
|
|
3
|
+
if(APPLE)
|
|
4
|
+
set_target_properties(${target} PROPERTIES BUILD_RPATH "@loader_path/../lib")
|
|
5
|
+
else()
|
|
6
|
+
set_target_properties(${target} PROPERTIES BUILD_RPATH "$ORIGIN/../lib")
|
|
7
|
+
endif()
|
|
8
|
+
endfunction()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# 100 列:模板与格式化串在 80 列下换行过碎;全工程统一。
|
|
2
|
+
Language: Cpp
|
|
3
|
+
BasedOnStyle: Google
|
|
4
|
+
Standard: c++20
|
|
5
|
+
ColumnLimit: 100
|
|
6
|
+
ReflowComments: true
|
|
7
|
+
AlignAfterOpenBracket: Align
|
|
8
|
+
AlignOperands: Align
|
|
9
|
+
BreakBeforeTernaryOperators: true
|
|
10
|
+
DerivePointerAlignment: false
|
|
11
|
+
PointerAlignment: Left
|
|
12
|
+
AccessModifierOffset: -1
|
|
13
|
+
EmptyLineBeforeAccessModifier: Always
|
|
14
|
+
EmptyLineAfterAccessModifier: Never
|
|
15
|
+
IndentWidth: 2
|
|
16
|
+
TabWidth: 2
|
|
17
|
+
UseTab: Never
|
|
18
|
+
MaxEmptyLinesToKeep: 1
|
|
19
|
+
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
20
|
+
AllowShortFunctionsOnASingleLine: Empty
|
|
21
|
+
AllowShortIfStatementsOnASingleLine: Never
|
|
22
|
+
AllowShortLoopsOnASingleLine: false
|
|
23
|
+
AllowShortCaseLabelsOnASingleLine: false
|
|
24
|
+
BreakAfterAttributes: Never
|
|
25
|
+
AlwaysBreakTemplateDeclarations: Yes
|
|
26
|
+
BreakConstructorInitializers: BeforeColon
|
|
27
|
+
ConstructorInitializerIndentWidth: 4
|
|
28
|
+
SpacesBeforeTrailingComments: 2
|
|
29
|
+
IncludeBlocks: Regroup
|
|
30
|
+
IncludeCategories:
|
|
31
|
+
# C 系统头先于 C++ 标准库;gtest 归第三方,不排到标准库前面。
|
|
32
|
+
- Regex: '^<[^/>]*\.h>'
|
|
33
|
+
Priority: 1
|
|
34
|
+
- Regex: '^<gtest/'
|
|
35
|
+
Priority: 3
|
|
36
|
+
- Regex: '^<.*>'
|
|
37
|
+
Priority: 2
|
|
38
|
+
# 其余引号头(本项目组件头)排最后。
|
|
39
|
+
- Regex: '.*'
|
|
40
|
+
Priority: 4
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
2
|
+
# 与 .clang-format 同一套命名;关闭项及理由集中写在 Checks 上方。
|
|
3
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
4
|
+
|
|
5
|
+
InheritParentConfig: false
|
|
6
|
+
|
|
7
|
+
# 关闭项:
|
|
8
|
+
# - bugprone-easily-swappable-parameters:相邻同型参数的顺序错误靠接口设计和 review,不靠命名噪声。
|
|
9
|
+
# - modernize-use-trailing-return-type:Google 风格不要求尾置返回类型。
|
|
10
|
+
# - portability-avoid-pragma-once:项目统一使用 #pragma once。
|
|
11
|
+
# - readability-identifier-length:短循环变量和测试数据(i、x)是领域习惯。
|
|
12
|
+
# - readability-magic-numbers 与 cppcoreguidelines-avoid-magic-numbers:阈值、尺寸和测试数据常直接写字面量。
|
|
13
|
+
Checks: >
|
|
14
|
+
-*,
|
|
15
|
+
bugprone-*,
|
|
16
|
+
cppcoreguidelines-*,
|
|
17
|
+
misc-*,
|
|
18
|
+
modernize-*,
|
|
19
|
+
performance-*,
|
|
20
|
+
portability-*,
|
|
21
|
+
readability-*,
|
|
22
|
+
clang-analyzer-core.*,
|
|
23
|
+
google-build-using-namespace,
|
|
24
|
+
google-explicit-constructor,
|
|
25
|
+
google-global-names-in-headers,
|
|
26
|
+
google-readability-casting,
|
|
27
|
+
-bugprone-easily-swappable-parameters,
|
|
28
|
+
-cppcoreguidelines-avoid-magic-numbers,
|
|
29
|
+
-modernize-use-trailing-return-type,
|
|
30
|
+
-portability-avoid-pragma-once,
|
|
31
|
+
-readability-identifier-length,
|
|
32
|
+
-readability-magic-numbers
|
|
33
|
+
|
|
34
|
+
WarningsAsErrors: '*'
|
|
35
|
+
# 头文件过滤由调用方按项目目录传入;这里不写 .*,避免把第三方头纳入。
|
|
36
|
+
FormatStyle: file
|
|
37
|
+
UseColor: true
|
|
38
|
+
|
|
39
|
+
CheckOptions:
|
|
40
|
+
# 类型与函数 PascalCase;变量 snake_case;私有成员尾随 _;常量 k 前缀。
|
|
41
|
+
- key: readability-identifier-naming.NamespaceCase
|
|
42
|
+
value: lower_case
|
|
43
|
+
- key: readability-identifier-naming.ClassCase
|
|
44
|
+
value: CamelCase
|
|
45
|
+
- key: readability-identifier-naming.StructCase
|
|
46
|
+
value: CamelCase
|
|
47
|
+
- key: readability-identifier-naming.EnumCase
|
|
48
|
+
value: CamelCase
|
|
49
|
+
- key: readability-identifier-naming.EnumConstantCase
|
|
50
|
+
value: CamelCase
|
|
51
|
+
- key: readability-identifier-naming.EnumConstantPrefix
|
|
52
|
+
value: 'k'
|
|
53
|
+
- key: readability-identifier-naming.FunctionCase
|
|
54
|
+
value: CamelCase
|
|
55
|
+
- key: readability-identifier-naming.TypeAliasCase
|
|
56
|
+
value: CamelCase
|
|
57
|
+
- key: readability-identifier-naming.TypedefCase
|
|
58
|
+
value: CamelCase
|
|
59
|
+
- key: readability-identifier-naming.TemplateParameterCase
|
|
60
|
+
value: CamelCase
|
|
61
|
+
- key: readability-identifier-naming.VariableCase
|
|
62
|
+
value: lower_case
|
|
63
|
+
- key: readability-identifier-naming.ParameterCase
|
|
64
|
+
value: lower_case
|
|
65
|
+
- key: readability-identifier-naming.FieldCase
|
|
66
|
+
value: lower_case
|
|
67
|
+
- key: readability-identifier-naming.PrivateMemberCase
|
|
68
|
+
value: lower_case
|
|
69
|
+
- key: readability-identifier-naming.PrivateMemberSuffix
|
|
70
|
+
value: '_'
|
|
71
|
+
- key: readability-identifier-naming.ConstexprVariableCase
|
|
72
|
+
value: CamelCase
|
|
73
|
+
- key: readability-identifier-naming.ConstexprVariablePrefix
|
|
74
|
+
value: 'k'
|
|
75
|
+
- key: readability-identifier-naming.GlobalConstantCase
|
|
76
|
+
value: CamelCase
|
|
77
|
+
- key: readability-identifier-naming.GlobalConstantPrefix
|
|
78
|
+
value: 'k'
|
|
79
|
+
- key: readability-identifier-naming.LocalConstantCase
|
|
80
|
+
value: CamelCase
|
|
81
|
+
- key: readability-identifier-naming.LocalConstantPrefix
|
|
82
|
+
value: 'k'
|
|
83
|
+
- key: readability-identifier-naming.MacroDefinitionCase
|
|
84
|
+
value: UPPER_CASE
|
|
85
|
+
# 函数长度:Google 建议短函数,超过 40 行提示。
|
|
86
|
+
- key: readability-function-size.LineThreshold
|
|
87
|
+
value: 40
|
|
88
|
+
- key: readability-function-size.StatementThreshold
|
|
89
|
+
value: 50
|
|
90
|
+
# 空容器/默认构造成员不加 {};与 NSDMI 规则配套。
|
|
91
|
+
- key: readability-redundant-member-init.IgnoreBaseInCopyConstructors
|
|
92
|
+
value: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
// 编译器驱动用绝对路径;GCC 模式改成 /usr/bin/g++。
|
|
3
|
+
// 只允许这一个驱动,不用 * 通配。
|
|
4
|
+
"clangd.arguments": [
|
|
5
|
+
"--query-driver=/usr/bin/clang++",
|
|
6
|
+
"--header-insertion=never",
|
|
7
|
+
"--background-index"
|
|
8
|
+
],
|
|
9
|
+
"cmake.buildDirectory": "${workspaceFolder}/build/clang",
|
|
10
|
+
"cmake.generator": "Ninja",
|
|
11
|
+
"cmake.configureOnOpen": false,
|
|
12
|
+
// 格式化统一交给 clangd,避免 cpptools 与 clang-format 两套结果。
|
|
13
|
+
"C_Cpp.intelliSenseEngine": "disabled",
|
|
14
|
+
"editor.formatOnSave": true,
|
|
15
|
+
"[cpp]": {
|
|
16
|
+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
|
|
17
|
+
},
|
|
18
|
+
"[c]": {
|
|
19
|
+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
|
|
20
|
+
},
|
|
21
|
+
"files.associations": {
|
|
22
|
+
"*.h": "cpp"
|
|
23
|
+
},
|
|
24
|
+
"files.encoding": "utf8",
|
|
25
|
+
"files.eol": "\n",
|
|
26
|
+
"files.exclude": {
|
|
27
|
+
"**/build": true,
|
|
28
|
+
"**/.cache": true
|
|
29
|
+
},
|
|
30
|
+
"search.exclude": {
|
|
31
|
+
"**/build": true,
|
|
32
|
+
"**/.cache": true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
3
|
+
# 配置、构建、格式化、静态检查、测试并运行当前 C++20 工程。
|
|
4
|
+
#
|
|
5
|
+
# 用法:./running-build.sh [clang|gcc];省略时用 clang。
|
|
6
|
+
# 构建目录:build/<compiler>;编译数据库:build/<compiler>/compile_commands.json
|
|
7
|
+
# 适用于 Linux、macOS 和 Windows + WSL;Windows 原生组合需要另写 PowerShell 版本。
|
|
8
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
cd "$(dirname "$0")"
|
|
12
|
+
|
|
13
|
+
readonly APP_NAME="app"
|
|
14
|
+
readonly BUILD_ROOT="build"
|
|
15
|
+
|
|
16
|
+
COMPILER="${1:-clang}"
|
|
17
|
+
case "${COMPILER}" in
|
|
18
|
+
clang)
|
|
19
|
+
readonly CXX="clang++"
|
|
20
|
+
;;
|
|
21
|
+
gcc)
|
|
22
|
+
readonly CXX="g++"
|
|
23
|
+
;;
|
|
24
|
+
*)
|
|
25
|
+
printf '用法: %s [clang|gcc]\n' "$0" >&2
|
|
26
|
+
exit 2
|
|
27
|
+
;;
|
|
28
|
+
esac
|
|
29
|
+
readonly COMPILER CXX
|
|
30
|
+
readonly BUILD_DIR="${BUILD_ROOT}/${COMPILER}"
|
|
31
|
+
|
|
32
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
33
|
+
# 输出辅助
|
|
34
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
35
|
+
|
|
36
|
+
header() {
|
|
37
|
+
printf '\n== %s ==\n' "$1"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
err() {
|
|
41
|
+
printf '错误: %s\n' "$1" >&2
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
trap 'status=$?; printf "失败(退出码 %s):%s\n" "${status}" "${BASH_COMMAND}" >&2' ERR
|
|
45
|
+
|
|
46
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
47
|
+
# 项目源码
|
|
48
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
49
|
+
|
|
50
|
+
collect_sources() {
|
|
51
|
+
find . \
|
|
52
|
+
\( -type d \( -name .git -o -name .cache -o -name node_modules \
|
|
53
|
+
-o -name third_party -o -name external -o -name vendor \
|
|
54
|
+
-o -name build -o -name temp -o -name templates \) -prune \) -o \
|
|
55
|
+
-type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.cxx' \
|
|
56
|
+
-o -name '*.h' -o -name '*.hh' -o -name '*.hpp' -o -name '*.hxx' \) -print0
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# 只让项目自身目录的头文件诊断进入结果。顶层目录从项目文件推导,
|
|
60
|
+
# 不硬编码 include/src;项目根同时覆盖 clang-tidy 输出的绝对路径。
|
|
61
|
+
# 第三方头即使被包含,也不在项目根 + 顶层目录的白名单里。
|
|
62
|
+
header_filter_for() {
|
|
63
|
+
local tops=()
|
|
64
|
+
local file rel top
|
|
65
|
+
for file in "$@"; do
|
|
66
|
+
rel="${file#./}"
|
|
67
|
+
case "${rel}" in
|
|
68
|
+
*/*)
|
|
69
|
+
top="${rel%%/*}"
|
|
70
|
+
tops+=("${top}")
|
|
71
|
+
;;
|
|
72
|
+
esac
|
|
73
|
+
done
|
|
74
|
+
local root
|
|
75
|
+
root="$(pwd -P)"
|
|
76
|
+
if [[ ${#tops[@]} -eq 0 ]]; then
|
|
77
|
+
printf '^(%s/)?[^/]+$' "${root}"
|
|
78
|
+
return 0
|
|
79
|
+
fi
|
|
80
|
+
printf '^(%s/)?((%s)/|[^/]+$)' "${root}" "$(printf '%s\n' "${tops[@]}" | sort -u | paste -sd '|' -)"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
84
|
+
# 主流程
|
|
85
|
+
#===--------------------------------------------------------------------------------------------===#
|
|
86
|
+
|
|
87
|
+
main() {
|
|
88
|
+
header "配置 (${COMPILER})"
|
|
89
|
+
cmake -S . -B "${BUILD_DIR}" -G Ninja \
|
|
90
|
+
-DCMAKE_BUILD_TYPE=Debug \
|
|
91
|
+
-DCMAKE_C_COMPILER="${COMPILER}" \
|
|
92
|
+
-DCMAKE_CXX_COMPILER="${CXX}" \
|
|
93
|
+
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
94
|
+
|
|
95
|
+
header "构建"
|
|
96
|
+
cmake --build "${BUILD_DIR}"
|
|
97
|
+
|
|
98
|
+
header "编译数据库"
|
|
99
|
+
rm -f "${BUILD_ROOT}/compile_commands.json"
|
|
100
|
+
ln -s "${COMPILER}/compile_commands.json" "${BUILD_ROOT}/compile_commands.json"
|
|
101
|
+
|
|
102
|
+
local format_sources=()
|
|
103
|
+
local tidy_sources=()
|
|
104
|
+
local file
|
|
105
|
+
while IFS= read -r -d '' file; do
|
|
106
|
+
format_sources+=("${file}")
|
|
107
|
+
case "${file}" in
|
|
108
|
+
*.c|*.cc|*.cpp|*.cxx) tidy_sources+=("${file}") ;;
|
|
109
|
+
esac
|
|
110
|
+
done < <(collect_sources)
|
|
111
|
+
|
|
112
|
+
header "换行检查"
|
|
113
|
+
if [[ ${#format_sources[@]} -gt 0 ]]; then
|
|
114
|
+
local crlf
|
|
115
|
+
crlf=$(grep -Il $'\r' "${format_sources[@]}" || true)
|
|
116
|
+
if [[ -n "${crlf}" ]]; then
|
|
117
|
+
err "以下文件含 CRLF,请改成 LF:${crlf}"
|
|
118
|
+
return 1
|
|
119
|
+
fi
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
header "格式检查"
|
|
123
|
+
if [[ ${#format_sources[@]} -gt 0 ]]; then
|
|
124
|
+
clang-format --dry-run --Werror "${format_sources[@]}"
|
|
125
|
+
else
|
|
126
|
+
err "没有找到项目源码,跳过 clang-format"
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
header "静态检查"
|
|
130
|
+
if [[ ${#tidy_sources[@]} -gt 0 ]]; then
|
|
131
|
+
local header_filter
|
|
132
|
+
local tidy_args=(--warnings-as-errors='*')
|
|
133
|
+
header_filter="$(header_filter_for "${format_sources[@]}")"
|
|
134
|
+
if [[ -n "${header_filter}" ]]; then
|
|
135
|
+
tidy_args+=(--header-filter="${header_filter}")
|
|
136
|
+
fi
|
|
137
|
+
clang-tidy -p "${BUILD_DIR}" "${tidy_args[@]}" "${tidy_sources[@]}"
|
|
138
|
+
else
|
|
139
|
+
err "没有找到 C++ 源文件,跳过 clang-tidy"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
header "测试"
|
|
143
|
+
ctest --test-dir "${BUILD_DIR}" --output-on-failure
|
|
144
|
+
|
|
145
|
+
header "运行 ${APP_NAME}"
|
|
146
|
+
(
|
|
147
|
+
cd "${BUILD_DIR}/bin"
|
|
148
|
+
"./${APP_NAME}"
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main "$@"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.20)
|
|
2
|
+
project({{PROJECT_NAME}} VERSION 0.1.0 LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
5
|
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
6
|
+
|
|
7
|
+
enable_testing()
|
|
8
|
+
|
|
9
|
+
add_executable(app
|
|
10
|
+
src/main.cpp
|
|
11
|
+
src/greeting.cpp
|
|
12
|
+
)
|
|
13
|
+
target_include_directories(app PRIVATE include)
|
|
14
|
+
target_compile_features(app PRIVATE cxx_std_20)
|
|
15
|
+
set_target_properties(app PROPERTIES CXX_EXTENSIONS OFF)
|
|
16
|
+
target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
17
|
+
|
|
18
|
+
add_test(NAME app_smoke COMMAND app)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.20)
|
|
2
|
+
project({{PROJECT_NAME}} VERSION 0.1.0 LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
5
|
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
6
|
+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
7
|
+
|
|
8
|
+
enable_testing()
|
|
9
|
+
|
|
10
|
+
add_subdirectory(greeting)
|
|
11
|
+
|
|
12
|
+
add_executable(app src/main.cpp)
|
|
13
|
+
target_compile_features(app PRIVATE cxx_std_20)
|
|
14
|
+
set_target_properties(app PROPERTIES CXX_EXTENSIONS OFF)
|
|
15
|
+
target_link_libraries(app PRIVATE greeting)
|
|
16
|
+
target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
17
|
+
|
|
18
|
+
add_test(NAME app_smoke COMMAND app)
|
|
19
|
+
|
|
20
|
+
if(APPLE)
|
|
21
|
+
set_target_properties(app PROPERTIES BUILD_RPATH "@loader_path/../lib")
|
|
22
|
+
else()
|
|
23
|
+
set_target_properties(app PROPERTIES BUILD_RPATH "$ORIGIN/../lib")
|
|
24
|
+
endif()
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
add_library(greeting SHARED src/greeting.cpp)
|
|
2
|
+
target_include_directories(greeting PUBLIC include)
|
|
3
|
+
target_compile_features(greeting PUBLIC cxx_std_20)
|
|
4
|
+
set_target_properties(greeting PROPERTIES CXX_EXTENSIONS OFF)
|
|
5
|
+
target_compile_options(greeting PRIVATE -Wall -Wextra -Werror -Wold-style-cast -Wshadow)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.20)
|
|
2
|
+
project({{PROJECT_NAME}} VERSION 0.1.0 LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
5
|
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
6
|
+
|
|
7
|
+
enable_testing()
|
|
8
|
+
|
|
9
|
+
add_executable(app src/main.cpp)
|
|
10
|
+
target_compile_features(app PRIVATE cxx_std_20)
|
|
11
|
+
set_target_properties(app PROPERTIES CXX_EXTENSIONS OFF)
|
|
12
|
+
target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
13
|
+
|
|
14
|
+
add_test(NAME app_smoke COMMAND app)
|