@chengzhao-dev/dsh-cpp-workflow 0.2.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.
Files changed (49) hide show
  1. package/README.en.md +7 -5
  2. package/README.md +7 -5
  3. package/lib/workspace.js +1 -56
  4. package/package.json +3 -2
  5. package/skills/building-cpp/SKILL.md +4 -2
  6. package/skills/building-cpp/assets/config/.clang-format +2 -0
  7. package/skills/building-cpp/assets/config/.clang-tidy +1 -0
  8. package/skills/building-cpp/assets/templates/projects/multi/CMakeLists.txt +2 -2
  9. package/skills/building-cpp/assets/templates/projects/shared-library/CMakeLists.txt +1 -1
  10. package/skills/building-cpp/assets/templates/projects/shared-library/greeting/CMakeLists.txt +1 -1
  11. package/skills/building-cpp/assets/templates/projects/single/CMakeLists.txt +1 -1
  12. package/skills/building-cpp/assets/templates/projects/static-library/CMakeLists.txt +1 -1
  13. package/skills/building-cpp/assets/templates/projects/static-library/greeting/CMakeLists.txt +1 -1
  14. package/skills/building-cpp/examples/cmake.md +15 -15
  15. package/skills/building-cpp/examples/tooling.md +3 -3
  16. package/skills/building-cpp/references/cmake.md +6 -6
  17. package/skills/building-cpp/references/encoding.md +49 -0
  18. package/skills/building-cpp/references/linking.md +6 -6
  19. package/skills/building-cpp/references/standards/c++23/README.md +1 -1
  20. package/skills/building-cpp/references/static-analysis.md +3 -3
  21. package/skills/building-cpp/scripts/checking-encoding.mjs +241 -0
  22. package/skills/building-cpp/steps/01-build.md +1 -1
  23. package/skills/building-cpp/steps/02-tooling.md +2 -2
  24. package/skills/building-cpp/steps/03-check.md +8 -6
  25. package/skills/developing-cpp/SKILL.md +19 -3
  26. package/skills/developing-cpp/examples/comments.md +161 -119
  27. package/skills/developing-cpp/examples/structure.md +4 -4
  28. package/skills/developing-cpp/references/comments.md +158 -69
  29. package/skills/developing-cpp/references/declaration-order.md +4 -2
  30. package/skills/developing-cpp/references/file-template.md +131 -0
  31. package/skills/developing-cpp/references/glossary.md +3 -3
  32. package/skills/developing-cpp/references/google-cpp-style.md +8 -8
  33. package/skills/developing-cpp/references/language.md +3 -3
  34. package/skills/developing-cpp/references/layout.md +21 -12
  35. package/skills/developing-cpp/references/naming.md +11 -2
  36. package/skills/developing-cpp/references/project-design.md +10 -1
  37. package/skills/developing-cpp/references/standard-library.md +1 -1
  38. package/skills/developing-cpp/scripts/checking-comments.mjs +316 -0
  39. package/skills/developing-cpp/steps/01-behavior.md +1 -1
  40. package/skills/developing-cpp/steps/02-boundary.md +5 -4
  41. package/skills/developing-cpp/steps/03-declaration.md +6 -6
  42. package/skills/developing-cpp/steps/04-implementation.md +3 -3
  43. /package/skills/building-cpp/assets/templates/projects/multi/src/{greeting.cc → greeting.cpp} +0 -0
  44. /package/skills/building-cpp/assets/templates/projects/multi/src/{main.cc → main.cpp} +0 -0
  45. /package/skills/building-cpp/assets/templates/projects/shared-library/greeting/src/{greeting.cc → greeting.cpp} +0 -0
  46. /package/skills/building-cpp/assets/templates/projects/shared-library/src/{main.cc → main.cpp} +0 -0
  47. /package/skills/building-cpp/assets/templates/projects/single/src/{main.cc → main.cpp} +0 -0
  48. /package/skills/building-cpp/assets/templates/projects/static-library/greeting/src/{greeting.cc → greeting.cpp} +0 -0
  49. /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.2.0
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.2.0
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
- Maintenance notes: flow and gate in [docs/plugin-flow.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-flow.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).
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.2.0
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.2.0
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
- 边界与门禁的维护说明在 [docs/plugin-flow.md](https://github.com/chengzhao-dev/dsh-cpp-workflow/blob/main/docs/plugin-flow.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)。
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, readdir } from 'node:fs/promises';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chengzhao-dev/dsh-cpp-workflow",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "C++11–C++23 工程流程技能包:源码四步与构建三步,按项目声明的环境组合校验 · C++11–C++23 workflow skills for DeepSeek Harness",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -42,7 +42,8 @@
42
42
  "icon": "./icon.svg",
43
43
  "scripts": {
44
44
  "build": "tsc -p tsconfig.json",
45
- "test": "npm run build && node scripts/checking-skill-links.mjs && node --test tests/*.test.mjs",
45
+ "test": "npm run build && node scripts/checking-skill-links.mjs && node skills/building-cpp/scripts/checking-encoding.mjs --quiet && node --test tests/*.test.mjs",
46
+ "check:encoding": "node skills/building-cpp/scripts/checking-encoding.mjs",
46
47
  "test:matrix": "bash scripts/checking-standard-matrix.sh",
47
48
  "pack:check": "npm pack --dry-run"
48
49
  },
@@ -13,6 +13,8 @@ metadata:
13
13
 
14
14
  编译失败先分因:诊断指向函数体,回 `developing-cpp` 的定实现;诊断指向声明或类型,回定声明;诊断是找不到头、链接失败、没有编译数据库或工具不在 PATH,留在本技能的定构建或定工具配置。
15
15
 
16
+ 源码和构建文件用 UTF-8 无 BOM、检出 LF;`.bat` / `.cmd` 用 CRLF;`.clang-format` 写 `LineEnding: LF`。MSVC 原生构建优先加 `/utf-8`,不要靠 BOM 过关。完整规则见 `references/encoding.md`,检查脚本是 `scripts/checking-encoding.mjs`,机器规则以仓库根 `.gitattributes` 与 `.editorconfig` 为准。
17
+
16
18
  存在项目技能 `cpp-workflow-project` 时先读它的 `SKILL.md`、`environment.json` 和 `stages/stage-table.md`。三个环境轴为空、`standard` 非法或组合非法时停在定构建,不猜 WSL、Clang 或构建目录;`windows` + `native` 直接拒绝,提示「本版本不能在 Windows 原生壳里构建」,不要给出补 PowerShell 的路线。环境组合空着时源码四步仍可做,只是不能构建。
17
19
 
18
20
  ## 两种走法
@@ -30,9 +32,9 @@ metadata:
30
32
  | --- | --- | --- | --- |
31
33
  | 1 | 定构建 | `steps/01-build.md` | 一次配置一个编译器,Ninja,target-based CMake,编译数据库 |
32
34
  | 2 | 定工具配置 | `steps/02-tooling.md` | 格式化、静态检查、clangd 各管一段,互不越界 |
33
- | 3 | 通过检查 | `steps/03-check.md` | 先跑环境脚本的 `--live`,再跑项目入口,按失败位置分诊 |
35
+ | 3 | 通过检查 | `steps/03-check.md` | 按编码 → 声明校验 → 活动校验 → 项目入口的次序跑,前一步失败就停 |
34
36
 
35
- 每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/` 保存完整条文,只在排错、整目录重构,或步骤里明确指向某一条文时按需打开。
37
+ 每步只打开同号的一个步骤文件。判不准才打开 `examples/` 里与该步对应的案例;`references/` 保存完整条文,只在排错、整目录重构,或步骤里明确指向某一条文时按需打开。链接、rpath 与产物布局读 `references/linking.md`;警告选项、GoogleTest 与 rpath 的 CMake 片段在 `assets/cmake/`,由 `references/cmake.md` 指路。
36
38
 
37
39
  ## 完成判据
38
40
 
@@ -3,3 +3,5 @@
3
3
  Language: Cpp
4
4
  BasedOnStyle: Google
5
5
  Standard: Latest
6
+ # 与根 .gitattributes 和 .editorconfig 同档:格式化不把行尾改回 CRLF。
7
+ LineEnding: LF
@@ -5,6 +5,7 @@ InheritParentConfig: false
5
5
  Checks: >
6
6
  -*,
7
7
  google-*,
8
+ portability-avoid-pragma-once,
8
9
  readability-identifier-naming
9
10
 
10
11
  WarningsAsErrors: '*'
@@ -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.cc
11
- src/greeting.cc
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.cc)
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
@@ -1,4 +1,4 @@
1
- add_library(greeting SHARED src/greeting.cc)
1
+ add_library(greeting SHARED src/greeting.cpp)
2
2
  target_include_directories(greeting PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
3
3
  target_compile_features(greeting PUBLIC cxx_std_23)
4
4
  set_target_properties(greeting PROPERTIES
@@ -6,7 +6,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
6
6
 
7
7
  enable_testing()
8
8
 
9
- add_executable(app src/main.cc)
9
+ add_executable(app src/main.cpp)
10
10
  target_compile_features(app PRIVATE cxx_std_23)
11
11
  set_target_properties(app PROPERTIES
12
12
  CXX_STANDARD 23
@@ -9,7 +9,7 @@ enable_testing()
9
9
 
10
10
  add_subdirectory(greeting)
11
11
 
12
- add_executable(app src/main.cc)
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
@@ -1,4 +1,4 @@
1
- add_library(greeting STATIC src/greeting.cc)
1
+ add_library(greeting STATIC src/greeting.cpp)
2
2
  target_include_directories(greeting PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
3
3
  target_compile_features(greeting PUBLIC cxx_std_23)
4
4
  set_target_properties(greeting 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.cc)
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.cc)
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.cc greeting/src/greeting.cc)
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/*.cc")
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.cc
61
- src/task_list.cc
62
- src/task_parser.cc
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.cc src/core.cc)
74
- add_executable(app src/main.cc) # 重复定义
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.cc)
81
- add_executable(app src/main.cc)
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.cc # 没有编译参数,头路径和标准都不对
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.cc
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.cc)
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.cc)
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.cc
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.cc
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/*.cc # 构建时悄悄改源码
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.cc)
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.cc)
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.cc)
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.cc`,辅助函数很少 | `CMakeLists.txt`, `src/main.cc` |
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/*.cc")`:新增文件不触发重新配置。
181
+ - `file(GLOB sources "src/*.cpp")`:新增文件不触发重新配置。
182
182
  - 把库和 `main()` 编进同一个 target:测试无法只链接库。
183
183
  - 在源码目录生成 `compile_commands.json` 或可执行文件。
184
184
  - 同时设 `CMAKE_CXX_COMPILER` 和 `CXX` 环境变量,互相覆盖。
@@ -0,0 +1,49 @@
1
+ # 编码与行尾
2
+
3
+ 默认组合是 UTF-8 无 BOM、LF。机器规则以仓库根 `.gitattributes` 与 `.editorconfig` 为准,本文件只记决定、MSVC 例外与检查方法。
4
+
5
+ ## 规则
6
+
7
+ - 文本文件用 UTF-8,不带 BOM。JSON 按 RFC 8259;YAML 按 YAML 1.2.2;不要 GBK、UTF-16 或 Latin-1。
8
+ - 所有文本文件用 LF,包括 `.sh`、Python、C++、Markdown、YAML、CMake 和配置文件。
9
+ - `.sh` 必须 LF:内核会把 shebang 末尾的 CR 当作解释器路径的一部分,导致 `bad interpreter`。
10
+ - `.bat` / `.cmd` 必须 CRLF:`cmd.exe` 对纯 LF 批处理不稳定。
11
+ - 每个文本文件末尾一个换行;文件中间不混用 LF 和 CRLF。
12
+ - 二进制文件(字体、图片)不转码,按 `binary` 处理。
13
+
14
+ ## MSVC 原生
15
+
16
+ MSVC 默认按 BOM 判断源码编码。源码没有 BOM 时,它按当前用户代码页解释,除非显式传入 `/utf-8` 或 `/source-charset:utf-8`。因此 BOM 不是 MSVC 的硬要求。
17
+
18
+ - 首选做法是加编译选项:在目标上写 `target_compile_options(<target> PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/utf-8>)`,源码继续 UTF-8 无 BOM、LF。
19
+ - 只有在无法改编译选项时,才把 MSVC 编译的 C/C++ 源文件保存为 UTF-8 BOM。BOM 只允许出现在这类源文件里。
20
+ - `.sh`、`.bat`、`.cmd`、`.json`、`.yml`、`.gitattributes`、`.editorconfig` 和 CMake 文件不要加 BOM。
21
+ - MSVC 接受 LF 源码;CRLF 不是必需项。只有 `.bat` / `.cmd` 固定 CRLF。
22
+ - WSL 与 Linux 构建按默认组合,不要把源码转成 CRLF 来迁就 Windows。
23
+
24
+ ## 工具
25
+
26
+ - `.gitattributes` 决定 Git 入库和检出;它覆盖贡献者自己的 `core.autocrlf`。
27
+ - `.editorconfig` 决定编辑器保存;`charset` 与 `end_of_line` 必须和 `.gitattributes` 同一档。
28
+ - `.clang-format` 写 `LineEnding: LF`,避免格式化把行尾改回 CRLF。
29
+
30
+ ## 检查
31
+
32
+ 在仓库根运行:
33
+
34
+ ```bash
35
+ node "<skill-dir>/scripts/checking-encoding.mjs" --profile portable
36
+ ```
37
+
38
+ - `portable`(默认)要求所有文本文件 UTF-8 无 BOM、LF、末尾换行。
39
+ - `msvc` 只放宽 MSVC 编译的 C/C++ 源文件:允许 UTF-8 BOM 与 CRLF;Markdown、配置与脚本仍按 `portable` 检查。
40
+ - 退出码:0 无问题,1 有问题,2 参数或 Git 错误。加 `--json` 输出机器可读结果。
41
+
42
+ 再跑 `git diff --check`,确认没有空白错误。不要用 `git add --renormalize` 把行尾改动混进功能改动;确需规范化时单独提交并说明。
43
+
44
+ ## 依据
45
+
46
+ - MSVC `/utf-8`:<https://learn.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-170>
47
+ - MSVC `/source-charset`:<https://learn.microsoft.com/en-us/cpp/build/reference/source-charset-set-source-character-set?view=msvc-170>
48
+ - Unicode UTF-8 BOM FAQ:<https://www.unicode.org/faq/utf_bom.html>
49
+ - Git `.gitattributes`:<https://git-scm.com/docs/gitattributes>
@@ -15,25 +15,25 @@
15
15
  - 链接:把多个目标文件和库合并,解析符号引用。`undefined reference` 在这一步失败。
16
16
  - 加载:程序启动时由动态加载器找到共享库;`error while loading shared libraries` 在这一步失败。
17
17
 
18
- `g++ -c file.cc` 只编译不链接;`g++ file.o -o app` 只链接。`-E` 只看预处理,`-S` 只看汇编。
18
+ `g++ -c file.cpp` 只编译不链接;`g++ file.o -o app` 只链接。`-E` 只看预处理,`-S` 只看汇编。
19
19
 
20
20
  ## 头文件、声明与定义
21
21
 
22
22
  - `#include` 是文本替换,不是模块导入;头文件只放声明、`inline` 定义、模板和 `constexpr` 定义。
23
- - 普通函数的定义放 `.cc`;在头文件里写非 `inline` 函数定义,多个翻译单元包含时会重复定义。
24
- - 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.cc`。
23
+ - 普通函数的定义放 `.cpp`;在头文件里写非 `inline` 函数定义,多个翻译单元包含时会重复定义。
24
+ - 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.cpp`。
25
25
  - 只用到声明时不要包含完整定义;前置声明可以减少编译依赖,但不能替代需要完整类型的场景(继承、成员对象、按值返回)。
26
- - 每个头文件自包含:单独编译一个只包含该头文件的 `.cc` 应通过。用路径式 `#define` 守卫防止重复包含,不用 `#pragma once`。
26
+ - 每个头文件自包含:单独编译一个只包含该头文件的 `.cpp` 应通过。用路径式 `#define` 守卫防止重复包含,不用 `#pragma once`。
27
27
 
28
28
  ## `undefined reference` 分诊
29
29
 
30
30
  | 现象 | 常见原因 | 修法 |
31
31
  | --- | --- | --- |
32
- | 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.cc` 没加入 target | 补定义,或把源文件加入 `target_sources` |
32
+ | 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.cpp` 没加入 target | 补定义,或把源文件加入 `target_sources` |
33
33
  | 只有某个平台失败 | 条件编译把定义排除了 | 检查宏和平台分支,保证每个平台都有定义 |
34
34
  | 第三方库符号缺失 | 没链接库,或库顺序不对 | `target_link_libraries` 加库;CMake 会处理顺序 |
35
35
  | C++ 符号被当成 C 符号 | 头文件缺少 `extern \"C\"` | C 接口头加 `extern \"C\"`,C++ 调用方也可见 |
36
- | 模板成员未定义 | 模板定义在 `.cc`,实例化点看不到 | 模板定义移到头文件,或显式实例化 |
36
+ | 模板成员未定义 | 模板定义在 `.cpp`,实例化点看不到 | 模板定义移到头文件,或显式实例化 |
37
37
  | 静态库中的目标文件没被拉入 | 链接器只取被引用符号所在的目标文件 | 确认符号确实被引用,或改用对象库/共享库 |
38
38
 
39
39
  先看链接器报的完整符号名和来源文件,不要只看第一行。
@@ -43,7 +43,7 @@
43
43
 
44
44
  ## 降档/升级
45
45
 
46
- 从 C++23 降到 C++20 见 [C++20 档案](../c++20/README.md)。升级到 C++26 前先确认 CMake 3.25+、编译器/标准库支持、clang-format 的 `c++26` 枚举;新增目录流程见[标准索引](../README.md#新增标准)。
46
+ 从 C++23 降到 C++20 见 [C++20 档案](../c++20/README.md)。升级到 C++26 前先确认 CMake 3.25+、编译器/标准库支持、clang-format 的 `c++26` 枚举;新增目录流程见 [标准索引](../README.md#新增标准)。
47
47
 
48
48
  ## 验证
49
49
 
@@ -5,7 +5,7 @@
5
5
  ## clang-format
6
6
 
7
7
  ```bash
8
- clang-format --dry-run --Werror src/*.cc include/*.h tests/*.cc
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/*.cc apps/*.cc tests/*.cc
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-*` 加 `readability-identifier-naming`。关闭某条时逐条写理由,不整族关闭;命名规则只配项目确实统一的项,不设 `FunctionCase`。
33
+ - 配置在工程根 `.clang-tidy`;默认集合是 `google-*`、`portability-avoid-pragma-once` 加 `readability-identifier-naming`(第二条去掉 `#pragma once`,与路径式守卫一致)。关闭某条时逐条写理由,不整族关闭;命名规则只配项目确实统一的项,不设 `FunctionCase`。
34
34
  - 没有编译数据库时先回到 `building-cpp` 的定构建生成;不要用 `--` 手工拼编译参数绕过。
35
35
  - `clang-tidy` 的诊断可能指向头文件;修头文件里的声明或实现,不要只改调用点。
36
36