@chengzhao-dev/dsh-cpp-workflow 0.3.0 → 0.3.1
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/README.en.md +7 -5
- package/README.md +7 -5
- package/lib/workspace.js +1 -56
- package/package.json +1 -1
- package/skills/building-cpp/SKILL.md +2 -2
- package/skills/building-cpp/assets/config/.clang-tidy +1 -0
- package/skills/building-cpp/assets/templates/projects/multi/CMakeLists.txt +2 -2
- package/skills/building-cpp/assets/templates/projects/shared-library/CMakeLists.txt +1 -1
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/CMakeLists.txt +1 -1
- package/skills/building-cpp/assets/templates/projects/single/CMakeLists.txt +1 -1
- package/skills/building-cpp/assets/templates/projects/static-library/CMakeLists.txt +1 -1
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/CMakeLists.txt +1 -1
- package/skills/building-cpp/examples/cmake.md +15 -15
- package/skills/building-cpp/examples/tooling.md +3 -3
- package/skills/building-cpp/references/cmake.md +6 -6
- package/skills/building-cpp/references/linking.md +6 -6
- package/skills/building-cpp/references/static-analysis.md +3 -3
- package/skills/building-cpp/steps/01-build.md +1 -1
- package/skills/building-cpp/steps/02-tooling.md +2 -2
- package/skills/developing-cpp/SKILL.md +17 -3
- package/skills/developing-cpp/examples/comments.md +151 -138
- package/skills/developing-cpp/examples/structure.md +4 -4
- package/skills/developing-cpp/references/comments.md +152 -81
- package/skills/developing-cpp/references/declaration-order.md +4 -2
- package/skills/developing-cpp/references/file-template.md +131 -0
- package/skills/developing-cpp/references/glossary.md +3 -3
- package/skills/developing-cpp/references/google-cpp-style.md +8 -8
- package/skills/developing-cpp/references/language.md +3 -3
- package/skills/developing-cpp/references/layout.md +21 -12
- package/skills/developing-cpp/references/naming.md +3 -2
- package/skills/developing-cpp/references/project-design.md +1 -1
- package/skills/developing-cpp/references/standard-library.md +1 -1
- package/skills/developing-cpp/scripts/checking-comments.mjs +316 -0
- package/skills/developing-cpp/steps/01-behavior.md +1 -1
- package/skills/developing-cpp/steps/02-boundary.md +4 -4
- package/skills/developing-cpp/steps/03-declaration.md +5 -5
- package/skills/developing-cpp/steps/04-implementation.md +3 -3
- /package/skills/building-cpp/assets/templates/projects/multi/src/{greeting.cc → greeting.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/multi/src/{main.cc → main.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/shared-library/greeting/src/{greeting.cc → greeting.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/shared-library/src/{main.cc → main.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/single/src/{main.cc → main.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/static-library/greeting/src/{greeting.cc → greeting.cpp} +0 -0
- /package/skills/building-cpp/assets/templates/projects/static-library/src/{main.cc → main.cpp} +0 -0
package/README.en.md
CHANGED
|
@@ -8,7 +8,7 @@ Two skills for C++11–C++23 source and build work; new projects default to C++2
|
|
|
8
8
|
|
|
9
9
|
| Skill | Covers | Open it when |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
| `developing-cpp` | Behavior, boundaries, declarations, implementation; naming, exceptions, and source comments in `.h` / `.cc` | The user names source code, or the work is a new project or whole-stage refactor |
|
|
11
|
+
| `developing-cpp` | Behavior, boundaries, declarations, implementation; naming, exceptions, and source comments in `.h` / `.cpp` / `.cc` | The user names source code, or the work is a new project or whole-stage refactor |
|
|
12
12
|
| `building-cpp` | Build setup, tool configuration, checks; CMake, Ninja, Clang config, build scripts, and environment combinations | The change touches build files, tool config, or the environment declaration, or the project is first connected to a build |
|
|
13
13
|
|
|
14
14
|
The exception material follows the C++ Core Guidelines' Error handling section and guides source and examples only during development; the plugin runtime never compiles or executes those rules. Both skills read the project skill `cpp-workflow-project` first. Without it, the workspace gate never exposes these names.
|
|
@@ -18,13 +18,13 @@ The exception material follows the C++ Core Guidelines' Error handling section a
|
|
|
18
18
|
Pinned npm install:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.3.
|
|
21
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.3.1
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
The matching Git tag:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.3.
|
|
27
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.3.1
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
The desktop app owns the `desktop` profile. If the command-line `add` is rejected, add the plugin in the app settings and use the same pinned npm version. A Git tag install uses the prebuilt `lib/` committed in the repository and runs no build on the target machine; the package has no install script that needs approval.
|
|
@@ -89,7 +89,9 @@ dsh-cpp-workflow/
|
|
|
89
89
|
└── icon.svg
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
The repository also keeps `src/`, `scripts/`, `tests/` and `docs/` for development and review; they are not published. The whitelist lives in [docs/plugin-layout.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-layout.md).
|
|
93
|
+
|
|
94
|
+
Maintenance notes: flow and gate in [docs/plugin-flow.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-flow.md), skill layers and data flow in [docs/architecture.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/architecture.md), trigger matrix in [docs/triggering.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/triggering.md), directory and npm whitelist in [docs/plugin-layout.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-layout.md), version rules in [docs/versioning.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/versioning.md).
|
|
93
95
|
|
|
94
96
|
## Local development
|
|
95
97
|
|
|
@@ -97,7 +99,7 @@ Requires Node.js 22 or newer.
|
|
|
97
99
|
|
|
98
100
|
```bash
|
|
99
101
|
npm ci
|
|
100
|
-
npm test # build, structural check, gate/environment/schema tests
|
|
102
|
+
npm test # build, structural check, gate/environment/schema/comment tests
|
|
101
103
|
npm run test:matrix # real build matrix: 4 templates x 5 standards
|
|
102
104
|
npm run pack:check # inspect the npm package contents
|
|
103
105
|
```
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
| 技能 | 管什么 | 什么时候打开 |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
| `developing-cpp` | 定行为、定边界、定声明、定实现;`.h` / `.cc` 的命名、异常和源码注释 | 用户点名源码,或需要新建/整段重构源码 |
|
|
11
|
+
| `developing-cpp` | 定行为、定边界、定声明、定实现;`.h` / `.cpp` / `.cc` 的命名、异常和源码注释 | 用户点名源码,或需要新建/整段重构源码 |
|
|
12
12
|
| `building-cpp` | 定构建、定工具配置、通过检查;CMake、Ninja、Clang 配置、构建脚本和环境组合 | 改动落在构建文件、工具配置或环境声明上,或第一次接构建 |
|
|
13
13
|
|
|
14
14
|
异常条文采用 C++ Core Guidelines 的 Error handling,只在开发阶段指导源码和示例;插件运行时不编译、不执行这些规则。两个技能都先读项目技能 `cpp-workflow-project`。没有项目技能时,门禁不会放出这两个名字。
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
npm 安装钉死版本:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.3.
|
|
21
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.3.1
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
同版本的 Git 标签:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.3.
|
|
27
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.3.1
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
桌面应用独占 `desktop` profile。命令行 `add` 被拒绝时,在应用设置里添加插件,地址填同一个 npm 版本。Git 标签安装使用仓库内已构建的 `lib/`,不在目标机器上重新构建;包内也不含需要授权执行的安装脚本。
|
|
@@ -89,7 +89,9 @@ dsh-cpp-workflow/
|
|
|
89
89
|
└── icon.svg
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
仓库另有 `src/`、`scripts/`、`tests/` 与 `docs/`,只服务开发与评审,不进包;白名单见 [docs/plugin-layout.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-layout.md)。
|
|
93
|
+
|
|
94
|
+
边界与门禁的维护说明在 [docs/plugin-flow.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-flow.md),技能的层次与数据流在 [docs/architecture.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/architecture.md),触发矩阵在 [docs/triggering.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/triggering.md),目录和进包白名单在 [docs/plugin-layout.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-layout.md),版本规则在 [docs/versioning.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/versioning.md)。
|
|
93
95
|
|
|
94
96
|
## 本地开发
|
|
95
97
|
|
|
@@ -97,7 +99,7 @@ dsh-cpp-workflow/
|
|
|
97
99
|
|
|
98
100
|
```bash
|
|
99
101
|
npm ci
|
|
100
|
-
npm test # 构建、结构检查、门禁/环境/schema
|
|
102
|
+
npm test # 构建、结构检查、门禁/环境/schema/注释测试
|
|
101
103
|
npm run test:matrix # 四套模板 × 五档标准的真实构建矩阵
|
|
102
104
|
npm run pack:check # 核对 npm 包内容
|
|
103
105
|
```
|
package/lib/workspace.js
CHANGED
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
// freshly copied template still sees the workflow. The git root is the
|
|
7
7
|
// repository boundary: marker lookup ignores sibling directories and never
|
|
8
8
|
// searches above the root.
|
|
9
|
-
import { access
|
|
9
|
+
import { access } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
export const PROJECT_SKILL = path.join('.agents', 'skills', 'cpp-workflow-project', 'SKILL.md');
|
|
12
12
|
export const MAX_ASCENT = 64;
|
|
13
|
-
export const MAX_SCAN_DEPTH = 12;
|
|
14
|
-
export const MAX_SCAN_ENTRIES = 4000;
|
|
15
13
|
const SKIPPED_DIRS = new Set([
|
|
16
14
|
'.git',
|
|
17
15
|
'node_modules',
|
|
@@ -22,16 +20,6 @@ const SKIPPED_DIRS = new Set([
|
|
|
22
20
|
'temp',
|
|
23
21
|
'.cache',
|
|
24
22
|
]);
|
|
25
|
-
export const CPP_SOURCE_EXTENSIONS = new Set([
|
|
26
|
-
'.c',
|
|
27
|
-
'.cc',
|
|
28
|
-
'.cpp',
|
|
29
|
-
'.cxx',
|
|
30
|
-
'.h',
|
|
31
|
-
'.hh',
|
|
32
|
-
'.hpp',
|
|
33
|
-
'.hxx',
|
|
34
|
-
]);
|
|
35
23
|
export const CPP_BUILD_FILES = new Set(['CMakeLists.txt']);
|
|
36
24
|
async function exists(target) {
|
|
37
25
|
try {
|
|
@@ -107,49 +95,6 @@ export async function findProjectSkill(cwd, gitRoot) {
|
|
|
107
95
|
export async function hasProjectSkill(cwd, gitRoot) {
|
|
108
96
|
return (await findProjectSkill(cwd, gitRoot)) !== undefined;
|
|
109
97
|
}
|
|
110
|
-
/**
|
|
111
|
-
* True when `root` contains at least one first-party `CMakeLists.txt` or C++
|
|
112
|
-
* source/header. Generated, dependency, template and build trees are skipped.
|
|
113
|
-
* The scan is bounded to 12 levels and 4000 directory entries.
|
|
114
|
-
*/
|
|
115
|
-
export async function hasCppProject(root) {
|
|
116
|
-
let seen = 0;
|
|
117
|
-
const queue = [{ dir: root, depth: 0 }];
|
|
118
|
-
while (queue.length > 0) {
|
|
119
|
-
const current = queue.shift();
|
|
120
|
-
if (!current)
|
|
121
|
-
break;
|
|
122
|
-
let entries;
|
|
123
|
-
try {
|
|
124
|
-
entries = await readdir(current.dir, { withFileTypes: true });
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
for (const entry of entries) {
|
|
130
|
-
seen += 1;
|
|
131
|
-
if (seen > MAX_SCAN_ENTRIES)
|
|
132
|
-
return false;
|
|
133
|
-
if (entry.isSymbolicLink())
|
|
134
|
-
continue;
|
|
135
|
-
if (entry.isDirectory()) {
|
|
136
|
-
if (current.depth >= MAX_SCAN_DEPTH)
|
|
137
|
-
continue;
|
|
138
|
-
if (SKIPPED_DIRS.has(entry.name))
|
|
139
|
-
continue;
|
|
140
|
-
queue.push({ dir: path.join(current.dir, entry.name), depth: current.depth + 1 });
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
if (!entry.isFile())
|
|
144
|
-
continue;
|
|
145
|
-
if (CPP_BUILD_FILES.has(entry.name))
|
|
146
|
-
return true;
|
|
147
|
-
if (CPP_SOURCE_EXTENSIONS.has(path.extname(entry.name).toLowerCase()))
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
98
|
/**
|
|
154
99
|
* Session gate. The project skill must sit between `cwd` and the git root
|
|
155
100
|
* (inclusive). First-party C++ or CMake evidence is deliberately not required:
|
package/package.json
CHANGED
|
@@ -32,9 +32,9 @@ metadata:
|
|
|
32
32
|
| --- | --- | --- | --- |
|
|
33
33
|
| 1 | 定构建 | `steps/01-build.md` | 一次配置一个编译器,Ninja,target-based CMake,编译数据库 |
|
|
34
34
|
| 2 | 定工具配置 | `steps/02-tooling.md` | 格式化、静态检查、clangd 各管一段,互不越界 |
|
|
35
|
-
| 3 | 通过检查 | `steps/03-check.md` |
|
|
35
|
+
| 3 | 通过检查 | `steps/03-check.md` | 按编码 → 声明校验 → 活动校验 → 项目入口的次序跑,前一步失败就停 |
|
|
36
36
|
|
|
37
|
-
每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/`
|
|
37
|
+
每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/` 保存完整条文,只在排错、整目录重构,或步骤里明确指向某一条文时按需打开。链接、rpath 与产物布局读 `references/linking.md`;警告选项、GoogleTest 与 rpath 的 CMake 片段在 `assets/cmake/`,由 `references/cmake.md` 指路。
|
|
38
38
|
|
|
39
39
|
## 完成判据
|
|
40
40
|
|
|
@@ -7,8 +7,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
|
7
7
|
enable_testing()
|
|
8
8
|
|
|
9
9
|
add_executable(app
|
|
10
|
-
src/main.
|
|
11
|
-
src/greeting.
|
|
10
|
+
src/main.cpp
|
|
11
|
+
src/greeting.cpp
|
|
12
12
|
)
|
|
13
13
|
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
14
14
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
@@ -9,7 +9,7 @@ enable_testing()
|
|
|
9
9
|
|
|
10
10
|
add_subdirectory(greeting)
|
|
11
11
|
|
|
12
|
-
add_executable(app src/main.
|
|
12
|
+
add_executable(app src/main.cpp)
|
|
13
13
|
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
14
14
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
15
15
|
set_target_properties(app PROPERTIES
|
|
@@ -9,7 +9,7 @@ enable_testing()
|
|
|
9
9
|
|
|
10
10
|
add_subdirectory(greeting)
|
|
11
11
|
|
|
12
|
-
add_executable(app src/main.
|
|
12
|
+
add_executable(app src/main.cpp)
|
|
13
13
|
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
14
14
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
15
15
|
set_target_properties(app PROPERTIES
|
|
@@ -10,13 +10,13 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
10
10
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
11
11
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
12
12
|
|
|
13
|
-
add_library(greeting STATIC greeting/src/greeting.
|
|
13
|
+
add_library(greeting STATIC greeting/src/greeting.cpp)
|
|
14
14
|
target_include_directories(greeting PUBLIC greeting/include)
|
|
15
15
|
target_compile_features(greeting PUBLIC cxx_std_23)
|
|
16
16
|
set_target_properties(greeting PROPERTIES CXX_EXTENSIONS OFF)
|
|
17
17
|
target_compile_options(greeting PRIVATE -Wall -Wextra -Werror)
|
|
18
18
|
|
|
19
|
-
add_executable(app src/main.
|
|
19
|
+
add_executable(app src/main.cpp)
|
|
20
20
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
21
21
|
set_target_properties(app PROPERTIES CXX_EXTENSIONS OFF)
|
|
22
22
|
target_link_libraries(app PRIVATE greeting)
|
|
@@ -30,7 +30,7 @@ target_link_libraries(app PRIVATE greeting)
|
|
|
30
30
|
|
|
31
31
|
```cmake
|
|
32
32
|
include_directories(include greeting/include)
|
|
33
|
-
add_executable(app src/main.
|
|
33
|
+
add_executable(app src/main.cpp greeting/src/greeting.cpp)
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
问题:所有 target 共享 include,边界消失;程序直接编译库源码,测试无法只链接库。
|
|
@@ -47,7 +47,7 @@ target_link_libraries(app PRIVATE greeting)
|
|
|
47
47
|
**差**:
|
|
48
48
|
|
|
49
49
|
```cmake
|
|
50
|
-
file(GLOB SOURCES "src/*.
|
|
50
|
+
file(GLOB SOURCES "src/*.cpp")
|
|
51
51
|
add_executable(app ${SOURCES})
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -57,9 +57,9 @@ add_executable(app ${SOURCES})
|
|
|
57
57
|
|
|
58
58
|
```cmake
|
|
59
59
|
add_executable(app
|
|
60
|
-
src/main.
|
|
61
|
-
src/task_list.
|
|
62
|
-
src/task_parser.
|
|
60
|
+
src/main.cpp
|
|
61
|
+
src/task_list.cpp
|
|
62
|
+
src/task_parser.cpp
|
|
63
63
|
)
|
|
64
64
|
```
|
|
65
65
|
|
|
@@ -70,15 +70,15 @@ add_executable(app
|
|
|
70
70
|
**差**:
|
|
71
71
|
|
|
72
72
|
```cmake
|
|
73
|
-
add_library(core STATIC src/main.
|
|
74
|
-
add_executable(app src/main.
|
|
73
|
+
add_library(core STATIC src/main.cpp src/core.cpp)
|
|
74
|
+
add_executable(app src/main.cpp) # 重复定义
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
**好**:
|
|
78
78
|
|
|
79
79
|
```cmake
|
|
80
|
-
add_library(core STATIC src/core.
|
|
81
|
-
add_executable(app src/main.
|
|
80
|
+
add_library(core STATIC src/core.cpp)
|
|
81
|
+
add_executable(app src/main.cpp)
|
|
82
82
|
target_link_libraries(app PRIVATE core)
|
|
83
83
|
```
|
|
84
84
|
|
|
@@ -93,7 +93,7 @@ target_link_libraries(app PRIVATE core)
|
|
|
93
93
|
```
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
clang-tidy src/main.
|
|
96
|
+
clang-tidy src/main.cpp # 没有编译参数,头路径和标准都不对
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
**好**:
|
|
@@ -106,7 +106,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
106
106
|
cmake -S . -B build/clang -G Ninja -DCMAKE_CXX_COMPILER=clang++
|
|
107
107
|
rm -f build/compile_commands.json
|
|
108
108
|
ln -s clang/compile_commands.json build/compile_commands.json
|
|
109
|
-
clang-tidy -p build/clang src/main.
|
|
109
|
+
clang-tidy -p build/clang src/main.cpp
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
## 共享库运行时路径
|
|
@@ -120,11 +120,11 @@ LD_LIBRARY_PATH=build/clang/lib ./build/clang/bin/app # 每次运行都要包
|
|
|
120
120
|
**好**:
|
|
121
121
|
|
|
122
122
|
```cmake
|
|
123
|
-
add_library(greeting SHARED greeting/src/greeting.
|
|
123
|
+
add_library(greeting SHARED greeting/src/greeting.cpp)
|
|
124
124
|
set_target_properties(greeting PROPERTIES
|
|
125
125
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
126
126
|
|
|
127
|
-
add_executable(app src/main.
|
|
127
|
+
add_executable(app src/main.cpp)
|
|
128
128
|
target_link_libraries(app PRIVATE greeting)
|
|
129
129
|
if(APPLE)
|
|
130
130
|
set_target_properties(app PROPERTIES BUILD_RPATH "@loader_path/../lib")
|
|
@@ -121,7 +121,7 @@ Checks: >
|
|
|
121
121
|
**差**:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
clang-tidy -p build/clang --system-headers src/main.
|
|
124
|
+
clang-tidy -p build/clang --system-headers src/main.cpp
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
系统头也参与诊断,出现大量第三方告警。
|
|
@@ -130,7 +130,7 @@ clang-tidy -p build/clang --system-headers src/main.cc
|
|
|
130
130
|
|
|
131
131
|
```bash
|
|
132
132
|
clang-tidy -p build/clang --header-filter="^$(pwd -P)/(include|src)/" \
|
|
133
|
-
--warnings-as-errors='*' src/main.
|
|
133
|
+
--warnings-as-errors='*' src/main.cpp
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
`--header-filter` 只列项目顶层目录,避免把第三方头纳入;系统头默认排除。工程有别的顶层目录时按实际替换。
|
|
@@ -140,7 +140,7 @@ clang-tidy -p build/clang --header-filter="^$(pwd -P)/(include|src)/" \
|
|
|
140
140
|
**差**:
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
|
-
clang-format -i src/*.
|
|
143
|
+
clang-format -i src/*.cpp # 构建时悄悄改源码
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
**好**:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CMake
|
|
2
2
|
|
|
3
|
-
目标:一个编译器、Ninja、target-based 规则、可用的编译数据库。下面是最小形状和常见边界;模板在 `assets/templates/projects
|
|
3
|
+
目标:一个编译器、Ninja、target-based 规则、可用的编译数据库。下面是最小形状和常见边界;模板在 `assets/templates/projects/`,可复用的 CMake 片段在 `assets/cmake/`:`applying-warnings.cmake` 管警告选项,`fetching-googletest.cmake` 取测试框架,`setting-rpath.cmake` 设运行时库路径。
|
|
4
4
|
|
|
5
5
|
## 排版
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ project({{PROJECT_NAME}} VERSION 0.1.0 LANGUAGES CXX)
|
|
|
19
19
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
20
20
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
21
21
|
|
|
22
|
-
add_executable(app src/main.
|
|
22
|
+
add_executable(app src/main.cpp)
|
|
23
23
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
24
24
|
set_target_properties(app PROPERTIES
|
|
25
25
|
CXX_STANDARD 23
|
|
@@ -42,7 +42,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
|
42
42
|
|
|
43
43
|
add_subdirectory(greeting)
|
|
44
44
|
|
|
45
|
-
add_executable(app src/main.
|
|
45
|
+
add_executable(app src/main.cpp)
|
|
46
46
|
target_compile_features(app PRIVATE cxx_std_23)
|
|
47
47
|
set_target_properties(app PROPERTIES
|
|
48
48
|
CXX_STANDARD 23
|
|
@@ -55,7 +55,7 @@ target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
|
55
55
|
|
|
56
56
|
```cmake
|
|
57
57
|
# greeting/CMakeLists.txt
|
|
58
|
-
add_library(greeting STATIC src/greeting.
|
|
58
|
+
add_library(greeting STATIC src/greeting.cpp)
|
|
59
59
|
target_include_directories(greeting PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
|
60
60
|
target_compile_features(greeting PUBLIC cxx_std_23)
|
|
61
61
|
set_target_properties(greeting PROPERTIES
|
|
@@ -168,7 +168,7 @@ FetchContent_MakeAvailable(googletest)
|
|
|
168
168
|
|
|
169
169
|
| 模板 | 何时用 | 关键文件 |
|
|
170
170
|
| --- | --- | --- |
|
|
171
|
-
| `single` | 一个 `main.
|
|
171
|
+
| `single` | 一个 `main.cpp`,辅助函数很少 | `CMakeLists.txt`, `src/main.cpp` |
|
|
172
172
|
| `multi` | 多个源文件,一个程序 | `CMakeLists.txt`, `include/`, `src/` |
|
|
173
173
|
| `static-library` | 库需要被测试或第二个程序链接 | 根 + `greeting/` 子目录 |
|
|
174
174
|
| `shared-library` | 需要运行时加载/替换 | 同上,`SHARED` + RPATH |
|
|
@@ -178,7 +178,7 @@ FetchContent_MakeAvailable(googletest)
|
|
|
178
178
|
## 反模式
|
|
179
179
|
|
|
180
180
|
- 全局 `include_directories(include)`:所有 target 共享,边界消失。
|
|
181
|
-
- `file(GLOB sources "src/*.
|
|
181
|
+
- `file(GLOB sources "src/*.cpp")`:新增文件不触发重新配置。
|
|
182
182
|
- 把库和 `main()` 编进同一个 target:测试无法只链接库。
|
|
183
183
|
- 在源码目录生成 `compile_commands.json` 或可执行文件。
|
|
184
184
|
- 同时设 `CMAKE_CXX_COMPILER` 和 `CXX` 环境变量,互相覆盖。
|
|
@@ -15,25 +15,25 @@
|
|
|
15
15
|
- 链接:把多个目标文件和库合并,解析符号引用。`undefined reference` 在这一步失败。
|
|
16
16
|
- 加载:程序启动时由动态加载器找到共享库;`error while loading shared libraries` 在这一步失败。
|
|
17
17
|
|
|
18
|
-
`g++ -c file.
|
|
18
|
+
`g++ -c file.cpp` 只编译不链接;`g++ file.o -o app` 只链接。`-E` 只看预处理,`-S` 只看汇编。
|
|
19
19
|
|
|
20
20
|
## 头文件、声明与定义
|
|
21
21
|
|
|
22
22
|
- `#include` 是文本替换,不是模块导入;头文件只放声明、`inline` 定义、模板和 `constexpr` 定义。
|
|
23
|
-
- 普通函数的定义放 `.
|
|
24
|
-
- 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.
|
|
23
|
+
- 普通函数的定义放 `.cpp`;在头文件里写非 `inline` 函数定义,多个翻译单元包含时会重复定义。
|
|
24
|
+
- 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.cpp`。
|
|
25
25
|
- 只用到声明时不要包含完整定义;前置声明可以减少编译依赖,但不能替代需要完整类型的场景(继承、成员对象、按值返回)。
|
|
26
|
-
- 每个头文件自包含:单独编译一个只包含该头文件的 `.
|
|
26
|
+
- 每个头文件自包含:单独编译一个只包含该头文件的 `.cpp` 应通过。用路径式 `#define` 守卫防止重复包含,不用 `#pragma once`。
|
|
27
27
|
|
|
28
28
|
## `undefined reference` 分诊
|
|
29
29
|
|
|
30
30
|
| 现象 | 常见原因 | 修法 |
|
|
31
31
|
| --- | --- | --- |
|
|
32
|
-
| 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.
|
|
32
|
+
| 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.cpp` 没加入 target | 补定义,或把源文件加入 `target_sources` |
|
|
33
33
|
| 只有某个平台失败 | 条件编译把定义排除了 | 检查宏和平台分支,保证每个平台都有定义 |
|
|
34
34
|
| 第三方库符号缺失 | 没链接库,或库顺序不对 | `target_link_libraries` 加库;CMake 会处理顺序 |
|
|
35
35
|
| C++ 符号被当成 C 符号 | 头文件缺少 `extern \"C\"` | C 接口头加 `extern \"C\"`,C++ 调用方也可见 |
|
|
36
|
-
| 模板成员未定义 | 模板定义在 `.
|
|
36
|
+
| 模板成员未定义 | 模板定义在 `.cpp`,实例化点看不到 | 模板定义移到头文件,或显式实例化 |
|
|
37
37
|
| 静态库中的目标文件没被拉入 | 链接器只取被引用符号所在的目标文件 | 确认符号确实被引用,或改用对象库/共享库 |
|
|
38
38
|
|
|
39
39
|
先看链接器报的完整符号名和来源文件,不要只看第一行。
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## clang-format
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
clang-format --dry-run --Werror src/*.
|
|
8
|
+
clang-format --dry-run --Werror src/*.cpp include/*.h tests/*.cpp
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
- 检查用 `--dry-run --Werror`;需要自动修复时单独跑 `clang-format -i`,不要在构建脚本里悄悄改源码。
|
|
@@ -21,7 +21,7 @@ clang-format --dry-run --Werror src/*.cc include/*.h tests/*.cc
|
|
|
21
21
|
clang-tidy -p build/clang \
|
|
22
22
|
--header-filter="^$(pwd -P)/(include|src|apps|tests)/" \
|
|
23
23
|
--warnings-as-errors='*' \
|
|
24
|
-
src/*.
|
|
24
|
+
src/*.cpp apps/*.cpp tests/*.cpp
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
- `-p` 指向当前编译器的构建目录,读取 `compile_commands.json`。
|
|
@@ -30,7 +30,7 @@ clang-tidy -p build/clang \
|
|
|
30
30
|
- 系统头默认被排除,不要加 `--system-headers`。
|
|
31
31
|
- 只扫描项目源文件;不要把 `build/` 或第三方源码传给 clang-tidy。
|
|
32
32
|
- `--warnings-as-errors='*'` 把警告当失败;修代码,不要新增 `NOLINT`。确需抑制时写 `// NOLINT(检查名): 理由`,理由必须具体。
|
|
33
|
-
- 配置在工程根 `.clang-tidy`;默认集合是 `google
|
|
33
|
+
- 配置在工程根 `.clang-tidy`;默认集合是 `google-*`、`portability-avoid-pragma-once` 加 `readability-identifier-naming`(第二条去掉 `#pragma once`,与路径式守卫一致)。关闭某条时逐条写理由,不整族关闭;命名规则只配项目确实统一的项,不设 `FunctionCase`。
|
|
34
34
|
- 没有编译数据库时先回到 `building-cpp` 的定构建生成;不要用 `--` 手工拼编译参数绕过。
|
|
35
35
|
- `clang-tidy` 的诊断可能指向头文件;修头文件里的声明或实现,不要只改调用点。
|
|
36
36
|
|
|
@@ -60,7 +60,7 @@ GCC 模式把目录和编译器换成 `build/gcc`、`g++`。工程确有 C 源
|
|
|
60
60
|
|
|
61
61
|
## 情况
|
|
62
62
|
|
|
63
|
-
**新工程**:从 `assets/templates/projects/` 选形态:`single` 单文件、`multi` 多文件单程序、`static-library` 静态库 + 程序、`shared-library` 动态库 + 程序。只复制目标工程缺的文件;已有的 `CMakeLists.txt`、`.clang-*`、源码不覆盖。模板里的 `{{PROJECT_NAME}}` 换成真实工程名,默认标准 C++23;四套模板已按 `__cplusplus` 条件使用 `std::format`,把 `standard`、`cxx_std_*`、`CXX_STANDARD` 和 `.clang-format` 的解析档位一起降到 C++11–C++20 后仍应能构建,降完跑 `references/standards/README.md` 的五档矩阵。模板源码是 `.
|
|
63
|
+
**新工程**:从 `assets/templates/projects/` 选形态:`single` 单文件、`multi` 多文件单程序、`static-library` 静态库 + 程序、`shared-library` 动态库 + 程序。只复制目标工程缺的文件;已有的 `CMakeLists.txt`、`.clang-*`、源码不覆盖。模板里的 `{{PROJECT_NAME}}` 换成真实工程名,默认标准 C++23;四套模板已按 `__cplusplus` 条件使用 `std::format`,把 `standard`、`cxx_std_*`、`CXX_STANDARD` 和 `.clang-format` 的解析档位一起降到 C++11–C++20 后仍应能构建,降完跑 `references/standards/README.md` 的五档矩阵。模板源码是 `.cpp`,头文件用路径式 `#define` 守卫;新增文件沿用 `.cpp` / `.h`,已有工程保持原有扩展名。
|
|
64
64
|
|
|
65
65
|
**已有工程**:先读现有 `CMakeLists.txt`,找出全局设置、GLOB、输出目录和 target 命名;只改与当前任务相关的一处。大改前先让通过检查的项目入口跑通,保留可回退点。
|
|
66
66
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
- `.clangd` 的 `CompilationDatabase` 指向 `build/<compiler>`;切换编译器时同步改,不能留旧目录。**不要写 `-std`**:它会覆盖 `compile_commands.json`,把 C++23 工程降成旧标准;标准只由构建声明和编译数据库决定。
|
|
14
14
|
- `--query-driver` 是 clangd 的命令行参数,写在 `.vscode/settings.json` 的 `clangd.arguments` 里,不是 `.clangd` 的 YAML 键。它告诉 clangd 允许执行哪个编译器驱动来取系统头路径;路径写绝对路径,并与 `environment.json` 的编译器一致。
|
|
15
15
|
- 首次复制时按轴替换三处:`compiler=clang` 用 `CompilationDatabase: build/clang`、`--query-driver=/usr/bin/clang++` 和 `cmake.debugConfig` 的 `MIMode: lldb` / `miDebuggerPath: /usr/bin/lldb`;`compiler=gcc` 用 `build/gcc`、`/usr/bin/g++` 和 `MIMode: gdb` / `/usr/bin/gdb`。只复制模板而不改这三处,GCC 模式会指向错误的数据库、驱动或调试器。原工程已有的 `.clangd` 不覆盖;要改先征得同意。
|
|
16
|
-
- `.clang-format`
|
|
17
|
-
- `.clang-tidy` 用 `Checks: '-*, google-*, readability-identifier-naming'`,保留 `WarningsAsErrors: '*'` 和 `FormatStyle: file`。`google-*` 覆盖 Google 风格能静态检查的部分;`readability-identifier-naming` 只配项目确实统一的命名项:类型/枚举/别名/模板参数 PascalCase,变量/参数/成员 snake_case,类成员尾随 `_`,结构体成员不尾随,常量 `k` + PascalCase。不要设 `FunctionCase`,Google 允许 `count()` / `set_count()`
|
|
16
|
+
- `.clang-format` 保留 `Language: Cpp`、`BasedOnStyle: Google` 和 `Standard`:模板资产写 `Latest`;工程按 `environment.json` 声明 C++11–C++20 时,把 `Standard` 改成 `c++NN`(映射见 `references/standards/README.md`)。clang-format 21/22 的 `Standard` 不接受 `c++23`,所以 C++23 工程仍写 `Latest`。列宽 80、每级 2 空格、不用 tab、包含顺序都取 Google 预设;不要覆盖 `ColumnLimit`、`TabWidth`、`IncludeCategories` 或指针对齐。需要新规则时先改 `references/google-cpp-style.md` 并说明理由。
|
|
17
|
+
- `.clang-tidy` 用 `Checks: '-*, google-*, portability-avoid-pragma-once, readability-identifier-naming'`,保留 `WarningsAsErrors: '*'` 和 `FormatStyle: file`。`google-*` 覆盖 Google 风格能静态检查的部分;`readability-identifier-naming` 只配项目确实统一的命名项:类型/枚举/别名/模板参数 PascalCase,变量/参数/成员 snake_case,类成员尾随 `_`,结构体成员不尾随,常量 `k` + PascalCase。不要设 `FunctionCase`,Google 允许 `count()` / `set_count()` 这类访问器;`portability-avoid-pragma-once` 要打开,因为工程统一用路径式守卫;不要重新打开 `cppcoreguidelines-*` 整包。
|
|
18
18
|
- `.clang-tidy` 关闭项和例外必须写理由;不要借 `-*` 之后再打开 `cppcoreguidelines-*` 这类非 Google 整族检查。
|
|
19
19
|
- `.vscode/extensions.json` 推荐 clangd、CMake Tools 与 C/C++ 扩展;`.vscode/settings.json` 固定 clangd 参数、CMake 构建目录和 `cmake.debugConfig`。配置、构建、运行和调试只从 CMake Tools 进入,不写 `tasks.json` 或 `launch.json`;C/C++ 扩展只作为 CMake 快速调试的后端,IntelliSense 关闭,避免和 clangd 并行。配置注释用 JSONC 的 `//`,贴在被解释的键上方。
|
|
20
20
|
- 配置注释写「为什么这样设」,不写「这一项是什么」;不写策略头、不指向文档路径。
|
|
@@ -9,7 +9,7 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
## 适用场景
|
|
11
11
|
|
|
12
|
-
管 `.h` / `.cc`
|
|
12
|
+
管 `.h` / `.hpp` / `.cpp` / `.cc` 里换一台机器也不会改的内容:可观察行为、库与程序的边界、声明、命名、异常和源码注释。文件槽位与守卫以 `references/file-template.md` 为准;排版、命名、头文件与包含顺序以 `references/google-cpp-style.md` 的 Google 基线为准。异常条文采用 C++ Core Guidelines 的 Error handling,作为开发阶段的源码指导;它不进入插件运行时。`CMakeLists.txt`、`cmake/`、`running-build.sh`、`.clang-*`、`.vscode/` 和 `environment.json` 只开 `building-cpp`。只改函数体、命名、异常或注释且入口命令可运行时,定实现后只开 `building-cpp` 的「通过检查」;新增或移动源文件、改库与程序的边界、补测试 target 时,声明和实现可以先写,但完成前必须开 `building-cpp` 的定构建,把文件写进 CMake,再决定是否定工具配置,最后通过检查。`.qmd`、仓库 README、Python 和非 C++ 文档不打开本技能。
|
|
13
13
|
|
|
14
14
|
存在项目技能 `cpp-workflow-project` 时先读它的 `SKILL.md`:工程名、库与程序的边界、阶段表、术语增补、入口命令。没有项目技能时门禁不会放出本技能,不要猜项目约定。
|
|
15
15
|
|
|
@@ -31,9 +31,22 @@ metadata:
|
|
|
31
31
|
| 1 | 定行为 | `steps/01-behavior.md` | 把这一处要能观察到的结果写成验收句 |
|
|
32
32
|
| 2 | 定边界 | `steps/02-boundary.md` | 决定哪些放库、哪些放程序,依赖朝哪个方向 |
|
|
33
33
|
| 3 | 定声明 | `steps/03-declaration.md` | 写命名、声明顺序、头文件契约和声明注释 |
|
|
34
|
-
| 4 | 定实现 | `steps/04-implementation.md` | 写 `.
|
|
34
|
+
| 4 | 定实现 | `steps/04-implementation.md` | 写 `.cpp` 函数体的操作顺序、分组和实现注释 |
|
|
35
35
|
|
|
36
|
-
每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/`
|
|
36
|
+
每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/` 保存完整条文,只在排错、整目录重构,或步骤里明确指向某一条文时按需打开。性能问题读 `references/performance.md`,标准库设施选型读 `references/standard-library.md`,链接与产物的细节读 `building-cpp` 的 `references/linking.md`。
|
|
37
|
+
|
|
38
|
+
### 四类改动
|
|
39
|
+
|
|
40
|
+
先认这次改的是哪一类,再决定从哪一步进;一次改动混了两类时,按「写作 → 布局 → 排版 → 润色」的次序拆开做,前一类落定并经检查再进下一类。
|
|
41
|
+
|
|
42
|
+
| 类型 | 典型请求 | 从哪进 | 先读哪份条文 |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| 写作 | 新增类型、函数或文件;改可观察行为;改库与程序的边界 | 第 1 步 | `steps/01-behavior.md`、`02-boundary.md`、`references/project-design.md` |
|
|
45
|
+
| 布局 | 换文件位置、拆头文件、调声明顺序、补测试 target | 第 3 步 | `references/file-template.md`、`declaration-order.md` |
|
|
46
|
+
| 排版 | 只改缩进、行宽、包含顺序或格式 | 第 3 步的声明写法,或 `building-cpp` 的「定工具配置」 | `references/google-cpp-style.md`、`layout.md` |
|
|
47
|
+
| 润色 | 只改命名、只改注释措辞 | 第 3、4 步 | `references/naming.md`、`comments.md` |
|
|
48
|
+
|
|
49
|
+
只改格式时不动行为,只改注释时不动签名;类型注释的职责、跨文件边界与线程规则,只按 `references/comments.md` 的条文取内容。
|
|
37
50
|
|
|
38
51
|
## 完成判据
|
|
39
52
|
|
|
@@ -41,4 +54,5 @@ metadata:
|
|
|
41
54
|
- 第 2 步的库 target 不依赖终端、GUI 或脚本;程序 target 只做装配和输入输出;共享抽象有第二个真实使用方。
|
|
42
55
|
- 第 3 步的公共头文件自包含,命名、声明顺序和异常声明符合 `references/` 的条文。
|
|
43
56
|
- 第 4 步的实现只兑现声明;资源由 RAII 管理;失败是正常结果时用返回值,函数无法完成任务时抛异常,不拿异常做正常分支。
|
|
57
|
+
- 源码注释符合 `references/comments.md` 的四层规范,`node "<skill-dir>/scripts/checking-comments.mjs" --root <项目根>` 无输出。
|
|
44
58
|
- 没有改 `CMakeLists.txt`、`.clang-*`、构建脚本,也没有把外部资料路径或项目专属类名写进通用条文。
|