@chengzhao-dev/dsh-cpp-workflow 0.1.1 → 0.3.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/README.en.md +18 -15
- package/README.md +18 -15
- package/lib/index.js +7 -8
- package/lib/workspace.js +14 -14
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +7 -5
- package/skills/building-cpp/SKILL.md +8 -6
- package/skills/building-cpp/assets/config/.clang-format +5 -38
- package/skills/building-cpp/assets/config/.clang-tidy +8 -39
- package/skills/building-cpp/assets/config/.clangd +2 -5
- package/skills/building-cpp/assets/config/.vscode/extensions.json +2 -1
- package/skills/building-cpp/assets/config/.vscode/settings.json +16 -1
- package/skills/building-cpp/assets/templates/projects/common/running-build.sh +29 -18
- package/skills/building-cpp/assets/templates/projects/multi/CMakeLists.txt +9 -5
- package/skills/building-cpp/assets/templates/projects/multi/include/greeting.h +5 -3
- package/skills/building-cpp/assets/templates/projects/multi/src/greeting.cc +18 -0
- package/skills/building-cpp/assets/templates/projects/multi/src/main.cc +8 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/CMakeLists.txt +8 -3
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/CMakeLists.txt +15 -5
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/include/greeting.h +5 -3
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/src/greeting.cc +18 -0
- package/skills/building-cpp/assets/templates/projects/shared-library/src/main.cc +8 -0
- package/skills/building-cpp/assets/templates/projects/single/CMakeLists.txt +7 -3
- package/skills/building-cpp/assets/templates/projects/single/src/main.cc +15 -0
- package/skills/building-cpp/assets/templates/projects/static-library/CMakeLists.txt +8 -3
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/CMakeLists.txt +15 -5
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/include/greeting.h +5 -3
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/src/greeting.cc +18 -0
- package/skills/building-cpp/assets/templates/projects/static-library/src/main.cc +8 -0
- package/skills/building-cpp/examples/cmake.md +17 -17
- package/skills/building-cpp/examples/environment.md +4 -3
- package/skills/building-cpp/examples/tooling.md +31 -16
- package/skills/building-cpp/references/build-script.md +2 -2
- package/skills/building-cpp/references/cmake.md +35 -17
- package/skills/building-cpp/references/encoding.md +49 -0
- package/skills/building-cpp/references/environment.md +17 -13
- package/skills/building-cpp/references/linking.md +6 -6
- package/skills/building-cpp/references/standards/README.md +165 -0
- package/skills/building-cpp/references/standards/c++11/README.md +50 -0
- package/skills/building-cpp/references/standards/c++11/cmake-snippet.cmake +7 -0
- package/skills/building-cpp/references/standards/c++14/README.md +48 -0
- package/skills/building-cpp/references/standards/c++14/cmake-snippet.cmake +7 -0
- package/skills/building-cpp/references/standards/c++17/README.md +49 -0
- package/skills/building-cpp/references/standards/c++17/cmake-snippet.cmake +7 -0
- package/skills/building-cpp/references/standards/c++20/README.md +49 -0
- package/skills/building-cpp/references/standards/c++20/cmake-snippet.cmake +7 -0
- package/skills/building-cpp/references/standards/c++23/README.md +50 -0
- package/skills/building-cpp/references/standards/c++23/cmake-snippet.cmake +7 -0
- package/skills/building-cpp/references/static-analysis.md +27 -15
- package/skills/building-cpp/scripts/checking-encoding.mjs +241 -0
- package/skills/building-cpp/scripts/checking-environment.mjs +21 -21
- package/skills/building-cpp/steps/01-build.md +10 -8
- package/skills/building-cpp/steps/02-tooling.md +9 -7
- package/skills/building-cpp/steps/03-check.md +9 -7
- package/skills/developing-cpp/SKILL.md +8 -6
- package/skills/developing-cpp/examples/comments.md +39 -8
- package/skills/developing-cpp/examples/exceptions.md +64 -45
- package/skills/developing-cpp/examples/naming.md +2 -2
- package/skills/developing-cpp/examples/structure.md +12 -9
- package/skills/developing-cpp/references/comments.md +28 -8
- package/skills/developing-cpp/references/declaration-order.md +7 -4
- package/skills/developing-cpp/references/exceptions.md +83 -46
- package/skills/developing-cpp/references/glossary.md +6 -6
- package/skills/developing-cpp/references/google-cpp-style.md +27 -37
- package/skills/developing-cpp/references/language.md +4 -4
- package/skills/developing-cpp/references/layout.md +14 -14
- package/skills/developing-cpp/references/naming.md +15 -6
- package/skills/developing-cpp/references/project-design.md +12 -3
- package/skills/developing-cpp/references/standard-library.md +1 -1
- package/skills/developing-cpp/steps/02-boundary.md +8 -7
- package/skills/developing-cpp/steps/03-declaration.md +9 -8
- package/skills/developing-cpp/steps/04-implementation.md +11 -7
- package/templates/cpp-workflow-project/SKILL.md +1 -1
- package/templates/cpp-workflow-project/environment.json +2 -1
- package/skills/building-cpp/assets/templates/projects/multi/src/greeting.cpp +0 -13
- package/skills/building-cpp/assets/templates/projects/multi/src/main.cpp +0 -8
- package/skills/building-cpp/assets/templates/projects/shared-library/greeting/src/greeting.cpp +0 -13
- package/skills/building-cpp/assets/templates/projects/shared-library/src/main.cpp +0 -8
- package/skills/building-cpp/assets/templates/projects/single/src/main.cpp +0 -9
- package/skills/building-cpp/assets/templates/projects/static-library/greeting/src/greeting.cpp +0 -13
- package/skills/building-cpp/assets/templates/projects/static-library/src/main.cpp +0 -8
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
目标:一个编译器、Ninja、target-based 规则、可用的编译数据库。下面是最小形状和常见边界;模板在 `assets/templates/projects/`。
|
|
4
4
|
|
|
5
|
+
## 排版
|
|
6
|
+
|
|
7
|
+
CMake 没有官方风格指南。这里跟随 Google 自家项目的 `cmake-format` 配置:缩进 2 个空格、行宽 80、不用 tab。来源是 [or-tools 的 .cmake-format.py](https://github.com/google/or-tools/blob/stable/.cmake-format.py) 与 [draco 的 .cmake-format.py](https://github.com/google/draco/blob/master/.cmake-format.py),两处都设 `tab_size=2`、`line_width=80`。命令行、列表和注释都按这个宽度换行;`CMakeLists.txt` 与 `*.cmake` 一视同仁。
|
|
8
|
+
|
|
9
|
+
Shell 脚本用 2 个空格缩进、不用 tab,来源是 [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html#indentation)。
|
|
10
|
+
|
|
5
11
|
## 最小可用形状
|
|
6
12
|
|
|
7
13
|
### 单文件
|
|
@@ -13,9 +19,13 @@ project({{PROJECT_NAME}} VERSION 0.1.0 LANGUAGES CXX)
|
|
|
13
19
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
14
20
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
15
21
|
|
|
16
|
-
add_executable(app src/main.
|
|
17
|
-
target_compile_features(app PRIVATE
|
|
18
|
-
set_target_properties(app PROPERTIES
|
|
22
|
+
add_executable(app src/main.cc)
|
|
23
|
+
target_compile_features(app PRIVATE cxx_std_23)
|
|
24
|
+
set_target_properties(app PROPERTIES
|
|
25
|
+
CXX_STANDARD 23
|
|
26
|
+
CXX_STANDARD_REQUIRED ON
|
|
27
|
+
CXX_EXTENSIONS OFF
|
|
28
|
+
)
|
|
19
29
|
target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
20
30
|
```
|
|
21
31
|
|
|
@@ -32,32 +42,40 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
|
|
32
42
|
|
|
33
43
|
add_subdirectory(greeting)
|
|
34
44
|
|
|
35
|
-
add_executable(app src/main.
|
|
36
|
-
target_compile_features(app PRIVATE
|
|
37
|
-
set_target_properties(app PROPERTIES
|
|
45
|
+
add_executable(app src/main.cc)
|
|
46
|
+
target_compile_features(app PRIVATE cxx_std_23)
|
|
47
|
+
set_target_properties(app PROPERTIES
|
|
48
|
+
CXX_STANDARD 23
|
|
49
|
+
CXX_STANDARD_REQUIRED ON
|
|
50
|
+
CXX_EXTENSIONS OFF
|
|
51
|
+
)
|
|
38
52
|
target_link_libraries(app PRIVATE greeting)
|
|
39
53
|
target_compile_options(app PRIVATE -Wall -Wextra -Werror)
|
|
40
54
|
```
|
|
41
55
|
|
|
42
56
|
```cmake
|
|
43
57
|
# greeting/CMakeLists.txt
|
|
44
|
-
add_library(greeting STATIC src/greeting.
|
|
45
|
-
target_include_directories(greeting PUBLIC
|
|
46
|
-
target_compile_features(greeting PUBLIC
|
|
47
|
-
set_target_properties(greeting PROPERTIES
|
|
58
|
+
add_library(greeting STATIC src/greeting.cc)
|
|
59
|
+
target_include_directories(greeting PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
|
60
|
+
target_compile_features(greeting PUBLIC cxx_std_23)
|
|
61
|
+
set_target_properties(greeting PROPERTIES
|
|
62
|
+
CXX_STANDARD 23
|
|
63
|
+
CXX_STANDARD_REQUIRED ON
|
|
64
|
+
CXX_EXTENSIONS OFF
|
|
65
|
+
)
|
|
48
66
|
target_compile_options(greeting PRIVATE -Wall -Wextra -Werror -Wold-style-cast -Wshadow)
|
|
49
67
|
```
|
|
50
68
|
|
|
51
|
-
- 库的 `PUBLIC
|
|
52
|
-
- `
|
|
53
|
-
- `CXX_EXTENSIONS OFF` 把 `-std=gnu++
|
|
69
|
+
- 库的 `PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..` 让程序能从仓库根写 `#include "greeting/include/greeting.h"`,不需要程序再写 include 路径。
|
|
70
|
+
- `cxx_std_23` 用 `PUBLIC` 从库传播;程序自己再加一次也无害。`CXX_STANDARD_REQUIRED ON` 防止 CMake 在编译器不支持时静默 decay;显式 `CXX_STANDARD` 与 `standard` 保持一致。
|
|
71
|
+
- `CXX_EXTENSIONS OFF` 把 `-std=gnu++23` 收成 `-std=c++23`,与 Google 的「不用非标准扩展」一致;每个 target 都要设。configure 后检查 `compile_commands.json` 的最后一条 `-std=`,不能是 `gnu++NN`。
|
|
54
72
|
- 程序 target 固定 `app`;库 target 用组件名。
|
|
55
73
|
|
|
56
74
|
## target-based 规则
|
|
57
75
|
|
|
58
76
|
- 每个 target 自己声明 include、标准、编译选项、链接库;不要用全局 `include_directories()`、`add_definitions()`、`CMAKE_CXX_FLAGS` 给所有 target 加料。
|
|
59
77
|
- `target_include_directories(<target> PUBLIC|PRIVATE <dir>)`:公共头给 `PUBLIC`,私有实现目录给 `PRIVATE`。
|
|
60
|
-
- `target_compile_features(<target> PUBLIC
|
|
78
|
+
- `target_compile_features(<target> PUBLIC cxx_std_23)`:标准是 target 属性,不是全局开关。
|
|
61
79
|
- `target_link_libraries(<target> PRIVATE|PUBLIC <lib>)`:实现依赖用 `PRIVATE`,接口依赖用 `PUBLIC`。
|
|
62
80
|
- 不要 `file(GLOB ...)`;显式列源文件,新增文件时改 CMake,构建系统才知道。`CONFIGURE_DEPENDS` 依赖构建系统每次检查目录,跨生成器行为也不完全一致,不作为工程规则。
|
|
63
81
|
- 不把 `main()` 编进库;程序只做装配和 I/O。
|
|
@@ -117,7 +135,7 @@ endif()
|
|
|
117
135
|
- 一个构建树只用一个 C++ 标准库实现。Clang 可以配 libstdc++(Linux 默认)或 libc++,但 `clang++`、`clang-tidy`、`clangd` 和链接进同一个程序的库必须一致。
|
|
118
136
|
- `-stdlib=libc++` 是编译和链接都要的选项,不要只加在编译选项上;也不要全局 `add_compile_options`,按 target 传,或由工具链文件统一设置。
|
|
119
137
|
- 混用 libstdc++ 与 libc++ 的典型症状是链接期大量未定义符号、`std::string` ABI 不匹配,或运行期崩溃;先查 `clang++ -v` 与 `ldd`,不要靠加 `-lstdc++` 掩盖。
|
|
120
|
-
- 项目想固定 libc++ 时,在 CMake 工具链文件或项目自己的编译选项里写清,不要只写在某个人的脚本里;`environment.json` 只保留 `host`、`build_host`、`compiler`
|
|
138
|
+
- 项目想固定 libc++ 时,在 CMake 工具链文件或项目自己的编译选项里写清,不要只写在某个人的脚本里;`environment.json` 只保留 `host`、`build_host`、`compiler`、`standard` 四个轴,不放 libc++。换机器后必须能复现同一组合。
|
|
121
139
|
- 本插件默认使用目标平台默认标准库;只有项目明确要求 libc++ 时才切换,并保证整套工具一致。
|
|
122
140
|
|
|
123
141
|
## 警告与静态检查
|
|
@@ -150,7 +168,7 @@ FetchContent_MakeAvailable(googletest)
|
|
|
150
168
|
|
|
151
169
|
| 模板 | 何时用 | 关键文件 |
|
|
152
170
|
| --- | --- | --- |
|
|
153
|
-
| `single` | 一个 `main.
|
|
171
|
+
| `single` | 一个 `main.cc`,辅助函数很少 | `CMakeLists.txt`, `src/main.cc` |
|
|
154
172
|
| `multi` | 多个源文件,一个程序 | `CMakeLists.txt`, `include/`, `src/` |
|
|
155
173
|
| `static-library` | 库需要被测试或第二个程序链接 | 根 + `greeting/` 子目录 |
|
|
156
174
|
| `shared-library` | 需要运行时加载/替换 | 同上,`SHARED` + RPATH |
|
|
@@ -160,7 +178,7 @@ FetchContent_MakeAvailable(googletest)
|
|
|
160
178
|
## 反模式
|
|
161
179
|
|
|
162
180
|
- 全局 `include_directories(include)`:所有 target 共享,边界消失。
|
|
163
|
-
- `file(GLOB sources "src/*.
|
|
181
|
+
- `file(GLOB sources "src/*.cc")`:新增文件不触发重新配置。
|
|
164
182
|
- 把库和 `main()` 编进同一个 target:测试无法只链接库。
|
|
165
183
|
- 在源码目录生成 `compile_commands.json` 或可执行文件。
|
|
166
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>
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# 环境组合
|
|
2
2
|
|
|
3
|
-
环境是**声明**,不是探测结果。项目技能 `cpp-workflow-project` 的 `environment.json`
|
|
3
|
+
环境是**声明**,不是探测结果。项目技能 `cpp-workflow-project` 的 `environment.json` 写清楚三个环境轴和一个语言标准;构建规则、工具配置和检查都按这个声明执行。声明为空或组合非法时,先修声明,不要靠猜。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 四个轴
|
|
6
6
|
|
|
7
7
|
| 轴 | 取值 | 说明 |
|
|
8
8
|
| --- | --- | --- |
|
|
9
9
|
| `host` | `windows` / `linux` / `macos` | 编辑器与代理壳所在的系统 |
|
|
10
10
|
| `build_host` | `native` / `wsl` | 编译在哪执行;`wsl` 只对 `host=windows` 合法 |
|
|
11
11
|
| `compiler` | `clang` / `gcc` | 一次只配一个;不支持 MSVC、clang-cl,也不把 C 编译器单独作为一个轴 |
|
|
12
|
+
| `standard` | `c++11` / `c++14` / `c++17` / `c++20` / `c++23` | 一个工程一个标准;新工程默认 `c++23`,旧声明缺字段时也按 `c++23` 处理 |
|
|
12
13
|
|
|
13
14
|
```json
|
|
14
15
|
{
|
|
15
16
|
"host": "windows",
|
|
16
17
|
"build_host": "wsl",
|
|
17
|
-
"compiler": "clang"
|
|
18
|
+
"compiler": "clang",
|
|
19
|
+
"standard": "c++23"
|
|
18
20
|
}
|
|
19
21
|
```
|
|
20
22
|
|
|
@@ -24,8 +26,6 @@
|
|
|
24
26
|
| --- | --- | --- | --- | --- |
|
|
25
27
|
| windows | wsl | clang | 合法 | 是(WSL 内跑 POSIX 脚本) |
|
|
26
28
|
| windows | wsl | gcc | 合法 | 是 |
|
|
27
|
-
| windows | native | clang | 合法 | 否:缺 POSIX 壳(本版无 PowerShell 脚本) |
|
|
28
|
-
| windows | native | gcc | 合法 | 否:缺 POSIX 壳(本版无 PowerShell 脚本) |
|
|
29
29
|
| linux | native | clang | 合法 | 是 |
|
|
30
30
|
| linux | native | gcc | 合法 | 是 |
|
|
31
31
|
| macos | native | clang | 合法 | 是 |
|
|
@@ -33,12 +33,13 @@
|
|
|
33
33
|
|
|
34
34
|
非法组合:
|
|
35
35
|
|
|
36
|
-
- `host`
|
|
37
|
-
-
|
|
36
|
+
- `host`、`build_host`、`compiler` 不是各自允许的值,或 `standard` 不在 `c++11`–`c++23` 内。
|
|
37
|
+
- 三个环境轴任意为空、缺失、写成数组或同时写两个值;`standard` 缺失或为空时按默认 `c++23` 处理并给出提示(视为声明升级,不覆盖已写出的 `c++11`–`c++20`)。
|
|
38
38
|
- `host=linux` / `host=macos` + `build_host=wsl`。
|
|
39
|
+
- `host=windows` + `build_host=native`:本版本不支持,静态校验直接返回失败。
|
|
39
40
|
- `compiler=msvc`、`compiler=clang-cl`、`compiler=c`。
|
|
40
41
|
|
|
41
|
-
`windows` + `native`
|
|
42
|
+
`windows` + `native` 不再作为「合法但不能构建」的声明保留。声明校验直接返回 `ok: false`,`issues` 只有一句「本版本不能在 Windows 原生壳里构建」;不要建议改 WSL,也不要临时写 PowerShell 脚本伪装成已支持。
|
|
42
43
|
|
|
43
44
|
## 工具角色
|
|
44
45
|
|
|
@@ -56,11 +57,12 @@
|
|
|
56
57
|
|
|
57
58
|
## 版本与能力
|
|
58
59
|
|
|
59
|
-
-
|
|
60
|
-
- **clang-format / clang-tidy**:≥ 16
|
|
60
|
+
- **标准**:新工程默认 C++23,可声明 `c++11`–`c++23`;编译器必须支持对应的 `-std=c++NN`。CMake ≥ 3.20;C++11/14 的 `cxx_std_*` 需要 CMake ≥ 3.8,但本工作流统一按 3.20 起步。`CXX_STANDARD_REQUIRED ON` 防止标准 decay;C++23 的库设施(如 `std::print`)以实际编译器/标准库为准。
|
|
61
|
+
- **clang-format / clang-tidy**:≥ 16。这是本工作流的工具基线;低于该版本时检查器报告具体角色和版本。
|
|
61
62
|
- **clang 模式同版本**:`clang++`、`clang-format`、`clang-tidy`、`clangd` 必须是同一 LLVM 主版本。混装 17 的 clangd 与 18 的 clang-format 会出现诊断与格式化不一致。Apple Clang 也按这条核对;若工具版本对不上,报告的是具体角色和版本,不要为了通过而改声明。
|
|
62
|
-
- **gcc 模式**:检查器不拿 GCC 的主版本去比 Clang 工具;`clang-format` / `clang-tidy` 仍要 ≥ 16,`clangd` 只要求可用。`g++` 必须是真的 GCC,不能是 Apple clang 的别名。GCC 需要自带 C++
|
|
63
|
+
- **gcc 模式**:检查器不拿 GCC 的主版本去比 Clang 工具;`clang-format` / `clang-tidy` 仍要 ≥ 16,`clangd` 只要求可用。`g++` 必须是真的 GCC,不能是 Apple clang 的别名。GCC 需要自带 C++23 `<print>` / `std::expected` 的标准库;版本过旧时先升级工具链,或把项目标准降到实际可用的档位,不要改检查器绕过。
|
|
63
64
|
- **Apple Clang**:`/usr/bin/clang++` 通常是 Apple Clang;clangd 需能经 `xcrun` 找到 SDK。不要混用 Homebrew LLVM 与 Xcode 资源目录,也不要把 Homebrew 路径写死。
|
|
65
|
+
- **调试器**:VSCode 的 `CMake: Debug` 由 CMake Tools 调 C/C++ 扩展的 `cppdbg`;clang 模式要 `lldb`,gcc 模式要 `gdb`。调试器不在 `--live` 的编译器角色核对里,也不写进 `environment.json`;缺它时是调试启动失败,不是构建声明失败。
|
|
64
66
|
|
|
65
67
|
## 构建目录
|
|
66
68
|
|
|
@@ -76,7 +78,7 @@
|
|
|
76
78
|
|
|
77
79
|
`<skill-dir>/scripts/checking-environment.mjs` 做两件事:
|
|
78
80
|
|
|
79
|
-
1. **静态**(默认):读 `environment.json
|
|
81
|
+
1. **静态**(默认):读 `environment.json`,检查三个环境轴、`standard` 和组合。轴为空或组合非法时以退出码 2 结束,不查找任何可执行文件。
|
|
80
82
|
2. **活动**(`--live`):先做声明校验,再核对当前进程是否在声明的 build host 上,然后查 PATH、角色和版本。声明本身不合法时仍以退出码 2 结束;声明合法但活动核对失败时以退出码 3 结束。
|
|
81
83
|
|
|
82
84
|
```bash
|
|
@@ -89,7 +91,7 @@ node "<skill-dir>/scripts/checking-environment.mjs" --project . --live
|
|
|
89
91
|
约束:
|
|
90
92
|
|
|
91
93
|
- 只读:不安装、不下载、不改 PATH、不写项目文件。
|
|
92
|
-
- `--live` 在 `host=windows` + `build_host=native`
|
|
94
|
+
- `--live` 在 `host=windows` + `build_host=native` 下不会继续:声明校验已经失败,错误是「本版本不能在 Windows 原生壳里构建」。
|
|
93
95
|
- WSL 模式要求当前进程在 WSL 内(`WSL_DISTRO_NAME` / `WSL_INTEROP` 或 `/proc/version` 含 Microsoft);只在 Linux 上但不在 WSL 时失败。
|
|
94
96
|
- macOS 上声明 `compiler=gcc` 时,`g++ --version` 若显示 Apple clang,按「不是真正的 GCC」失败。
|
|
95
97
|
- 没有 `--live` 时不做任何 PATH 探测,CI 和 Windows 开发机都能做声明校验。
|
|
@@ -102,3 +104,5 @@ node "<skill-dir>/scripts/checking-environment.mjs" --project . --live
|
|
|
102
104
|
| 2 | 声明缺失、轴为空、组合非法 |
|
|
103
105
|
| 3 | 活动校验失败:不在声明的 build host、角色缺失、版本不符 |
|
|
104
106
|
| 1 | 脚本自身错误:参数错误或内部异常 |
|
|
107
|
+
|
|
108
|
+
各标准对应的编译器、库设施和工具档位见 [standards/README.md](standards/README.md)。
|
|
@@ -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.cc` 只编译不链接;`g++ file.o -o app` 只链接。`-E` 只看预处理,`-S` 只看汇编。
|
|
19
19
|
|
|
20
20
|
## 头文件、声明与定义
|
|
21
21
|
|
|
22
22
|
- `#include` 是文本替换,不是模块导入;头文件只放声明、`inline` 定义、模板和 `constexpr` 定义。
|
|
23
|
-
- 普通函数的定义放 `.
|
|
24
|
-
- 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.
|
|
23
|
+
- 普通函数的定义放 `.cc`;在头文件里写非 `inline` 函数定义,多个翻译单元包含时会重复定义。
|
|
24
|
+
- 类定义放头文件;成员函数在类外定义时写 `ClassName::`,定义放 `.cc`。
|
|
25
25
|
- 只用到声明时不要包含完整定义;前置声明可以减少编译依赖,但不能替代需要完整类型的场景(继承、成员对象、按值返回)。
|
|
26
|
-
- 每个头文件自包含:单独编译一个只包含该头文件的 `.
|
|
26
|
+
- 每个头文件自包含:单独编译一个只包含该头文件的 `.cc` 应通过。用路径式 `#define` 守卫防止重复包含,不用 `#pragma once`。
|
|
27
27
|
|
|
28
28
|
## `undefined reference` 分诊
|
|
29
29
|
|
|
30
30
|
| 现象 | 常见原因 | 修法 |
|
|
31
31
|
| --- | --- | --- |
|
|
32
|
-
| 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.
|
|
32
|
+
| 链接器说某个成员函数未定义 | 声明了但没写定义,或 `.cc` 没加入 target | 补定义,或把源文件加入 `target_sources` |
|
|
33
33
|
| 只有某个平台失败 | 条件编译把定义排除了 | 检查宏和平台分支,保证每个平台都有定义 |
|
|
34
34
|
| 第三方库符号缺失 | 没链接库,或库顺序不对 | `target_link_libraries` 加库;CMake 会处理顺序 |
|
|
35
35
|
| C++ 符号被当成 C 符号 | 头文件缺少 `extern \"C\"` | C 接口头加 `extern \"C\"`,C++ 调用方也可见 |
|
|
36
|
-
| 模板成员未定义 | 模板定义在 `.
|
|
36
|
+
| 模板成员未定义 | 模板定义在 `.cc`,实例化点看不到 | 模板定义移到头文件,或显式实例化 |
|
|
37
37
|
| 静态库中的目标文件没被拉入 | 链接器只取被引用符号所在的目标文件 | 确认符号确实被引用,或改用对象库/共享库 |
|
|
38
38
|
|
|
39
39
|
先看链接器报的完整符号名和来源文件,不要只看第一行。
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# 语言标准档案
|
|
2
|
+
|
|
3
|
+
本工作流默认 **C++23**,但一个工程只选一个 `standard`,不为同一份源码承诺“同时兼容 C++11–C++23”。标准是项目级事实,写在 `.agents/skills/cpp-workflow-project/environment.json`。
|
|
4
|
+
|
|
5
|
+
每个标准单独一个目录:`c++11/`、`c++14/`、`c++17/`、`c++20/`、`c++23/`。目录里放这一档自己的编译器下限、语言/库设施、CMake 片段和工具映射;模板仍然只有一套公共骨架,靠 `__cplusplus` 条件选择实现,不复制五份模板。
|
|
6
|
+
|
|
7
|
+
Google C++ Style Guide 上游仍写 “target C++20”,本工作流默认 C++23 是一处明确偏离;Google 的排版、命名、头文件和异常之外的规则不变。异常政策仍按 [exceptions.md](../../../developing-cpp/references/exceptions.md)。
|
|
8
|
+
|
|
9
|
+
## 选择标准
|
|
10
|
+
|
|
11
|
+
| 标准 | 目录 | 一句话 |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| C++11 | [c++11/README.md](c++11/README.md) | 老工具链、老库仍要维护时的最低档 |
|
|
14
|
+
| C++14 | [c++14/README.md](c++14/README.md) | 需要 `make_unique`、泛型 lambda,但还不想上 C++17 |
|
|
15
|
+
| C++17 | [c++17/README.md](c++17/README.md) | 需要 `string_view`、`optional`、`if constexpr` 的稳定基线 |
|
|
16
|
+
| C++20 | [c++20/README.md](c++20/README.md) | 需要 concepts、ranges、`std::format` 的现代基线 |
|
|
17
|
+
| C++23 | [c++23/README.md](c++23/README.md) | 本工作流默认;需要 `print`、`expected` 等设施时选它 |
|
|
18
|
+
|
|
19
|
+
新工程写 `c++23`;已有工程按现有 `CMakeLists.txt` 和编译器能力选,不为了“统一”擅自升降。降档前先读对应目录的“不能假设”和“降档要改什么”。
|
|
20
|
+
|
|
21
|
+
## 三个规划粒度
|
|
22
|
+
|
|
23
|
+
| 粒度 | 先看 | 产出 |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| 项目 | 本页选择表、编译器/库门槛 | `environment.json` 的 `standard`,以及“为什么选这档” |
|
|
26
|
+
| target | 该档的 `cmake-snippet.cmake` | `cxx_std_*`、`CXX_STANDARD`、`CXX_STANDARD_REQUIRED`、`CXX_EXTENSIONS` |
|
|
27
|
+
| 代码/工具 | 该档 README 的“能用/不能假设/降档” | 设施替换、`.clang-format` 档位、`.clangd` 不写 `-std` |
|
|
28
|
+
| 验证 | 本页验证矩阵、`scripts/checking-standard-matrix.sh` | configure/build/CTest 和 `compile_commands.json` 的精确 `-std` |
|
|
29
|
+
|
|
30
|
+
每个标准目录都按这四层写;不要只在项目层改 `standard`,却在 target 层留着 C++23 的 `cxx_std_23`。
|
|
31
|
+
|
|
32
|
+
## 共用矩阵
|
|
33
|
+
|
|
34
|
+
| `standard` | CMake meta-feature | `CXX_STANDARD` | `__cplusplus` | clang-format 21/22 | 模板实用下限(含标准库设施) |
|
|
35
|
+
| --- | --- | --- | --- | --- | --- |
|
|
36
|
+
| `c++11` | `cxx_std_11` | 11 | `201103L` | `c++11` | GCC 4.8 / Clang 3.4 |
|
|
37
|
+
| `c++14` | `cxx_std_14` | 14 | `201402L` | `c++14` | GCC 5 / Clang 3.4 |
|
|
38
|
+
| `c++17` | `cxx_std_17` | 17 | `201703L` | `c++17` | GCC 7 / Clang 5 |
|
|
39
|
+
| `c++20` | `cxx_std_20` | 20 | `202002L` | `c++20` | GCC 13 / Clang 16(`std::format`) |
|
|
40
|
+
| `c++23` | `cxx_std_23` | 23 | `202302L` | `Latest` | GCC 13 / Clang 17(模板只用 `std::format`) |
|
|
41
|
+
|
|
42
|
+
“语言核心最低编译器”只保证语法和核心库;标准库设施要单独看:
|
|
43
|
+
|
|
44
|
+
| 设施 | 标准 | 额外门槛 |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `std::string_view`、`std::optional`、`std::variant`、`if constexpr` | C++17 | 随语言核心 |
|
|
47
|
+
| `std::format` | C++20 | libstdc++ 13+;libc++ 14+(特性宏到 19 才稳定) |
|
|
48
|
+
| `std::print`、`std::expected`、`std::stacktrace` | C++23 | `std::print`:libstdc++ 14+、libc++ 19+;`std::expected` 随各库 C++23 实现;`std::stacktrace` 还要链接对应库 |
|
|
49
|
+
|
|
50
|
+
Clang/GCC 的 “Partial” 状态意味着 C++23 不是全量实现。用到具体设施前,先查:
|
|
51
|
+
|
|
52
|
+
- [GCC C++ status](https://gcc.gnu.org/projects/cxx-status.html)
|
|
53
|
+
- [Clang C++ status](https://clang.llvm.org/cxx_status.html)
|
|
54
|
+
- [cppreference C++23 compiler support](https://en.cppreference.com/w/cpp/compiler_support/23)
|
|
55
|
+
|
|
56
|
+
## 共用规则
|
|
57
|
+
|
|
58
|
+
### CMake
|
|
59
|
+
|
|
60
|
+
每个 target 同时写 meta-feature 和精确属性;片段见各标准目录的 `cmake-snippet.cmake`,把 target 名换成实际 target:
|
|
61
|
+
|
|
62
|
+
```cmake
|
|
63
|
+
target_compile_features(app PRIVATE cxx_std_23)
|
|
64
|
+
set_target_properties(app PROPERTIES
|
|
65
|
+
CXX_STANDARD 23
|
|
66
|
+
CXX_STANDARD_REQUIRED ON
|
|
67
|
+
CXX_EXTENSIONS OFF
|
|
68
|
+
)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- `cxx_std_23` 是“至少”,会向依赖它的 target 传播。
|
|
72
|
+
- `CXX_STANDARD` 是请求值;`CXX_STANDARD_REQUIRED ON` 防止编译器不支持时静默 decay。
|
|
73
|
+
- `CXX_EXTENSIONS OFF` 把 `-std=gnu++23` 收成 `-std=c++23`。
|
|
74
|
+
- configure 后读 `compile_commands.json` 的最后一个 `-std=`;必须是 `-std=c++NN`,不能是 `gnu++NN`。
|
|
75
|
+
- CMake 最低 3.20(模板统一要求);只单独使用低档片段时,C++11/14 的 `cxx_std_*` meta-feature 最低 3.8,C++20 为 3.12。C++23 的 `CXX_STANDARD 23` 自 3.20 才有。
|
|
76
|
+
|
|
77
|
+
### clang-format
|
|
78
|
+
|
|
79
|
+
clang-format 21/22 的 `Standard` 只到 `c++20`。映射:
|
|
80
|
+
|
|
81
|
+
| 声明 | 配置 |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `c++11`–`c++20` | 对应 `Standard: c++NN` |
|
|
84
|
+
| `c++23` | `Standard: Latest`(21/22 没有 `c++23`) |
|
|
85
|
+
| `c++26`(未来) | 工具支持时写 `c++26`,否则 `Latest` |
|
|
86
|
+
|
|
87
|
+
不要为了“看起来精确”写 `c++23`;clang-format 21 会报 `unknown enumerated scalar` 并退出 1。
|
|
88
|
+
|
|
89
|
+
### clangd
|
|
90
|
+
|
|
91
|
+
`.clangd` **不写 `-std`**。clangd 从 `compile_commands.json` 读标准;写死 `-std=c++20` 会把 C++23 工程降级,表现为 `<print>` 不存在、`if consteval` 解析失败。
|
|
92
|
+
|
|
93
|
+
只保留:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
CompileFlags:
|
|
97
|
+
CompilationDatabase: build/clang
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
切换编译器时改目录;没有数据库时先回到定构建生成。
|
|
101
|
+
|
|
102
|
+
### clang-tidy
|
|
103
|
+
|
|
104
|
+
`.clang-tidy` 不写标准,标准来自编译数据库。检查项保持 Google 基线:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
Checks: '-*, google-*, readability-identifier-naming'
|
|
108
|
+
WarningsAsErrors: '*'
|
|
109
|
+
FormatStyle: file
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
低标准工程不要为了通过检查去打开 `cppcoreguidelines-*` 整包;那会把 C++ Core Guidelines 的现代写法带进 C++11 代码。
|
|
113
|
+
|
|
114
|
+
### 标准库
|
|
115
|
+
|
|
116
|
+
默认用系统默认标准库。需要 libc++ 时,在 CMake 工具链文件或 target 选项里显式写:
|
|
117
|
+
|
|
118
|
+
```cmake
|
|
119
|
+
target_compile_options(app PRIVATE -stdlib=libc++)
|
|
120
|
+
target_link_options(app PRIVATE -stdlib=libc++)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
不要只写进某个人的 `.clangd` 或 shell 脚本;换机器后不可复现。
|
|
124
|
+
|
|
125
|
+
## 降档时改什么
|
|
126
|
+
|
|
127
|
+
默认模板按 `__cplusplus` 条件使用 `std::format`;选低标准仍不是只改一个数字:
|
|
128
|
+
|
|
129
|
+
| 从默认 C++23 降到 | 必须处理 |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `c++20` | `std::print` → `std::format` + `std::cout`;`std::expected` → `std::optional`/结果类型 |
|
|
132
|
+
| `c++17` | 再去掉 `std::format`,用 `std::ostringstream`;去掉 `std::span`、`std::bit_cast` |
|
|
133
|
+
| `c++14` | 去掉 `std::string_view`、`[[nodiscard]]`、结构化绑定、`if constexpr`、`std::optional` |
|
|
134
|
+
| `c++11` | 再去掉通用 lambda、`std::make_unique`、`std::index_sequence`、`constexpr` 放宽用法 |
|
|
135
|
+
|
|
136
|
+
每个标准目录里的“不能假设”和“降档要改什么”是该档的检查清单;模板只保证自身能构建,不替项目代码做兼容层。
|
|
137
|
+
|
|
138
|
+
## 验证矩阵
|
|
139
|
+
|
|
140
|
+
| 标准 | configure | build | run | compile_commands `-std` | clang-format | clangd |
|
|
141
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
142
|
+
| `c++11` | 必测 | 必测 | 必测 | `c++11` | `c++11` | 读 DB |
|
|
143
|
+
| `c++14` | 必测 | 必测 | 必测 | `c++14` | `c++14` | 读 DB |
|
|
144
|
+
| `c++17` | 必测 | 必测 | 必测 | `c++17` | `c++17` | 读 DB |
|
|
145
|
+
| `c++20` | 必测 | 必测 | 必测 | `c++20` | `c++20` | 读 DB |
|
|
146
|
+
| `c++23` | 必测 | 必测 | 必测 | `c++23` | `Latest` | 读 DB |
|
|
147
|
+
|
|
148
|
+
本仓库在 WSL(clang 21.1.8、CMake 4.2.3、Ninja 1.13.2)上跑过四套模板 × 五档共 20 个构建:single、multi、static-library、shared-library 全部 configure/build/CTest 通过,`compile_commands.json` 都得到精确的 `-std=c++11/14/17/20/23`。模板用 `__cplusplus` 条件选择 `std::format` 或字符串拼接,默认仍交付 C++23。可复现脚本:[checking-standard-matrix.sh](../../../../scripts/checking-standard-matrix.sh)。
|
|
149
|
+
|
|
150
|
+
## 新增标准
|
|
151
|
+
|
|
152
|
+
增加 C++26 或更高标准时,不复制模板,按这个顺序做:
|
|
153
|
+
|
|
154
|
+
1. 新建 `standards/c++26/`,写 `README.md`,复制对应档的 `cmake-snippet.cmake` 并改数字。
|
|
155
|
+
2. 更新本页矩阵和 `checking-environment.mjs` 的 `STANDARDS`。
|
|
156
|
+
3. 确认 CMake 的 `CXX_STANDARD 26`、clang-format 的 `Standard` 能力、编译器/标准库门槛。
|
|
157
|
+
4. 在四套模板 × 新档上跑 configure/build/CTest,并在 `compile_commands.json` 核对 `-std=c++26`。
|
|
158
|
+
5. 只在新档稳定后改默认;默认变更属于发布说明里要写清的破坏性变化。
|
|
159
|
+
|
|
160
|
+
## 相关文件
|
|
161
|
+
|
|
162
|
+
- [environment.md](../environment.md):四轴声明与校验。
|
|
163
|
+
- [cmake.md](../cmake.md):CMake 形状与排版。
|
|
164
|
+
- [static-analysis.md](../static-analysis.md):clang-format / clang-tidy / clangd 分工。
|
|
165
|
+
- [01-build.md](../../steps/01-build.md):定构建步骤。
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# C++11 标准档案
|
|
2
|
+
|
|
3
|
+
[返回标准索引](../README.md)
|
|
4
|
+
|
|
5
|
+
| 项 | 值 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `standard` | `c++11` |
|
|
8
|
+
| CMake meta-feature | `cxx_std_11` |
|
|
9
|
+
| `CXX_STANDARD` | `11` |
|
|
10
|
+
| `__cplusplus` | `201103L` |
|
|
11
|
+
| clang-format 21/22 | `Standard: c++11` |
|
|
12
|
+
| 模板实用下限 | GCC 4.8 / Clang 3.4 |
|
|
13
|
+
|
|
14
|
+
## 最重要的三件事
|
|
15
|
+
|
|
16
|
+
1. 代码只用 C++11 子集:没有 `std::make_unique`、通用 lambda、`std::string_view`、`std::optional`、`if constexpr`。
|
|
17
|
+
2. CMake 同时写 `cxx_std_11` 和 `CXX_STANDARD 11`,并开 `CXX_STANDARD_REQUIRED ON`;只写 `cxx_std_11` 可能被更高默认标准满足。
|
|
18
|
+
3. 验证时读 `compile_commands.json`,确认实际是 `-std=c++11`,不是 `gnu++11` 或更高的 `-std`。
|
|
19
|
+
|
|
20
|
+
## 本档能用
|
|
21
|
+
|
|
22
|
+
- `auto`、范围 `for`、lambda、右值引用与移动语义。
|
|
23
|
+
- `std::unique_ptr`、`std::shared_ptr`、`std::thread`、`std::chrono`。
|
|
24
|
+
- `enum class`、`override` / `final`、变参模板、`constexpr` 的受限用法。
|
|
25
|
+
- `std::array`、`std::unordered_map` / `unordered_set`。
|
|
26
|
+
|
|
27
|
+
## 本档不能假设
|
|
28
|
+
|
|
29
|
+
- 没有 `std::make_unique`、泛型 lambda、变量模板、返回类型推导。
|
|
30
|
+
- 没有 `std::string_view`、`std::optional`、`std::variant`、`if constexpr`、结构化绑定。
|
|
31
|
+
- 没有 `[[nodiscard]]`、`std::filesystem`、`std::format`、`std::print`。
|
|
32
|
+
- 不要用 C++14 的放宽 `constexpr` 写循环或多语句函数。
|
|
33
|
+
|
|
34
|
+
## CMake
|
|
35
|
+
|
|
36
|
+
把 [cmake-snippet.cmake](cmake-snippet.cmake) 的 target 名换成实际 target。新建工程仍建议 CMake ≥ 3.20;低版本工具链只影响 `CXX_STANDARD` 的可用性,不影响本工作流的目录约定。
|
|
37
|
+
|
|
38
|
+
## 工具
|
|
39
|
+
|
|
40
|
+
- `.clang-format`:`Standard: c++11`。
|
|
41
|
+
- `.clangd`:不写 `-std`,从 `compile_commands.json` 读。
|
|
42
|
+
- `.clang-tidy`:仍用 Google 基线;不要打开 `cppcoreguidelines-*` 整包。
|
|
43
|
+
|
|
44
|
+
## 降档/升级
|
|
45
|
+
|
|
46
|
+
这是最低档,没有“再降”的路径。从 C++14 降到这里时,先去掉 `std::make_unique`、泛型 lambda、返回类型推导和变量模板;`std::unique_ptr<T>(new T(...))` 只作为过渡,不要在新代码里扩散。
|
|
47
|
+
|
|
48
|
+
## 验证
|
|
49
|
+
|
|
50
|
+
configure、build、run 必测;`compile_commands.json` 的最后一个 `-std=` 必须是 `-std=c++11`,不能是 `gnu++11`。模板的 `__cplusplus` 分支在 C++11 下应走字符串拼接实现。
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# C++14 标准档案
|
|
2
|
+
|
|
3
|
+
[返回标准索引](../README.md)
|
|
4
|
+
|
|
5
|
+
| 项 | 值 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `standard` | `c++14` |
|
|
8
|
+
| CMake meta-feature | `cxx_std_14` |
|
|
9
|
+
| `CXX_STANDARD` | `14` |
|
|
10
|
+
| `__cplusplus` | `201402L` |
|
|
11
|
+
| clang-format 21/22 | `Standard: c++14` |
|
|
12
|
+
| 模板实用下限 | GCC 5 / Clang 3.4 |
|
|
13
|
+
|
|
14
|
+
## 最重要的三件事
|
|
15
|
+
|
|
16
|
+
1. C++14 只多出 `std::make_unique`、泛型 lambda、放宽的 `constexpr` 等;不要顺手用 C++17 的 `string_view`/`optional`。
|
|
17
|
+
2. `std::make_unique` 是这一档最常用的替换点,但不要把 C++11 的 `std::unique_ptr(new T)` 直接当成跨档写法。
|
|
18
|
+
3. 同样用 `CXX_STANDARD 14` + `REQUIRED ON` 锁定模式,并检查 `compile_commands.json` 是 `-std=c++14`。
|
|
19
|
+
|
|
20
|
+
## 本档能用
|
|
21
|
+
|
|
22
|
+
- C++11 的全部内容。
|
|
23
|
+
- `std::make_unique`、泛型 lambda、变量模板、返回类型推导。
|
|
24
|
+
- 二进制字面量、数字分隔符、放宽的 `constexpr`、`std::integer_sequence`。
|
|
25
|
+
|
|
26
|
+
## 本档不能假设
|
|
27
|
+
|
|
28
|
+
- 没有 `std::string_view`、`std::optional`、`std::variant`、`if constexpr`、结构化绑定。
|
|
29
|
+
- 没有 `[[nodiscard]]`、`std::filesystem`、`std::format`、`std::print`。
|
|
30
|
+
- 不要把结构化绑定或 `if constexpr` 写进 C++14 代码再靠编译器扩展通过。
|
|
31
|
+
|
|
32
|
+
## CMake
|
|
33
|
+
|
|
34
|
+
把 [cmake-snippet.cmake](cmake-snippet.cmake) 的 target 名换成实际 target。
|
|
35
|
+
|
|
36
|
+
## 工具
|
|
37
|
+
|
|
38
|
+
- `.clang-format`:`Standard: c++14`。
|
|
39
|
+
- `.clangd`:不写 `-std`,从 `compile_commands.json` 读。
|
|
40
|
+
- `.clang-tidy`:仍用 Google 基线;命名规则不要引入 C++17 属性。
|
|
41
|
+
|
|
42
|
+
## 降档/升级
|
|
43
|
+
|
|
44
|
+
从 C++17 降到这里时,把 `string_view` 改成 `const std::string&`,把 `optional` 改成 `bool` + 输出参数或项目结果类型,把 `if constexpr` 改成标签分派或重载。升级到 C++17 后也不要立刻把公共接口全改成 `string_view`,先看调用方生命周期。
|
|
45
|
+
|
|
46
|
+
## 验证
|
|
47
|
+
|
|
48
|
+
configure、build、run 必测;`compile_commands.json` 的最后一个 `-std=` 必须是 `-std=c++14`。模板在 C++14 下应走字符串拼接实现。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# C++17 标准档案
|
|
2
|
+
|
|
3
|
+
[返回标准索引](../README.md)
|
|
4
|
+
|
|
5
|
+
| 项 | 值 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `standard` | `c++17` |
|
|
8
|
+
| CMake meta-feature | `cxx_std_17` |
|
|
9
|
+
| `CXX_STANDARD` | `17` |
|
|
10
|
+
| `__cplusplus` | `201703L` |
|
|
11
|
+
| clang-format 21/22 | `Standard: c++17` |
|
|
12
|
+
| 模板实用下限 | GCC 7 / Clang 5(语言核心) |
|
|
13
|
+
|
|
14
|
+
## 最重要的三件事
|
|
15
|
+
|
|
16
|
+
1. `std::string_view`/`std::optional`/`std::variant`/`if constexpr` 是这一档的主力;它们不能出现在 C++11/14 档案里。
|
|
17
|
+
2. 还没有 `std::format`;字符串拼接/`ostringstream` 仍是这一档的默认写法。
|
|
18
|
+
3. `std::filesystem` 在旧 GCC 上要额外链接 `stdc++fs`,先查工具链再写进 CMake。
|
|
19
|
+
|
|
20
|
+
## 本档能用
|
|
21
|
+
|
|
22
|
+
- C++14 的全部内容。
|
|
23
|
+
- `std::string_view`、`std::optional`、`std::variant`、`std::any`。
|
|
24
|
+
- `if constexpr`、结构化绑定、`[[nodiscard]]`、内联变量、嵌套命名空间。
|
|
25
|
+
- `std::filesystem`、并行算法(库实现和链接方式另看)。
|
|
26
|
+
|
|
27
|
+
## 本档不能假设
|
|
28
|
+
|
|
29
|
+
- 没有 concepts、ranges、`std::format`、`std::span`、`std::bit_cast`。
|
|
30
|
+
- 没有 `std::print`、`std::expected`、`std::stacktrace`。
|
|
31
|
+
- `std::filesystem` 在 GCC 8 需要额外链接 `stdc++fs`,GCC 9 起才稳定;不要把“语言核心达标”当成文件系统库也达标。
|
|
32
|
+
|
|
33
|
+
## CMake
|
|
34
|
+
|
|
35
|
+
把 [cmake-snippet.cmake](cmake-snippet.cmake) 的 target 名换成实际 target。用到 `std::filesystem` 且工具链较老时,在 target 上补 `stdc++fs`,不要全局加链接选项。
|
|
36
|
+
|
|
37
|
+
## 工具
|
|
38
|
+
|
|
39
|
+
- `.clang-format`:`Standard: c++17`。
|
|
40
|
+
- `.clangd`:不写 `-std`,从 `compile_commands.json` 读。
|
|
41
|
+
- `.clang-tidy`:Google 基线;`[[nodiscard]]` 可以开始用于公共查询。
|
|
42
|
+
|
|
43
|
+
## 降档/升级
|
|
44
|
+
|
|
45
|
+
从 C++20 降到这里时,把 concepts 改成 `enable_if`/重载,把 ranges 改成迭代器算法,把 `std::format` 改成 `std::ostringstream`。升级到 C++20 后先确认 `std::format` 的库门槛(libstdc++ 13+ / libc++ 14+),不要只看编译器版本。
|
|
46
|
+
|
|
47
|
+
## 验证
|
|
48
|
+
|
|
49
|
+
configure、build、run 必测;`compile_commands.json` 的最后一个 `-std=` 必须是 `-std=c++17`。模板在 C++17 下仍走字符串拼接实现。
|