Skip to content

Commit ebc26c6

Browse files
authored
Merge pull request #24 from yizhinailong/main
add compile_commands.json
2 parents ad69e13 + eba834d commit ebc26c6

12 files changed

Lines changed: 26443 additions & 212 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# compile_commands.json 设计方案
2+
3+
> mcpp 0.0.9 — IDE 集成(clangd / VSCode / CLion)
4+
5+
## 1. 动机
6+
7+
C++ IDE 和语言服务器(clangd)需要 `compile_commands.json` 来理解编译参数,
8+
提供跳转、补全、诊断等功能。CMake/Meson/xmake 都有此能力,mcpp 需要补齐。
9+
10+
## 2. 模块文件划分
11+
12+
```
13+
src/build/
14+
plan.cppm ← BuildPlan 数据结构(不变)
15+
flags.cppm ← 🆕 共用 flag 计算逻辑
16+
compile_commands.cppm ← 🆕 compile_commands.json 生成
17+
ninja_backend.cppm ← ninja build.ninja 生成(瘦身,复用 flags)
18+
backend.cppm ← Backend 抽象接口(不变)
19+
```
20+
21+
### 2.1 `src/build/flags.cppm`
22+
23+
职责:从 BuildPlan 计算出所有编译/链接 flag。
24+
25+
```cpp
26+
export module mcpp.build.flags;
27+
import mcpp.build.plan;
28+
29+
export namespace mcpp::build {
30+
31+
struct CompileFlags {
32+
std::string cxx; // "-std=c++23 -fmodules -O2 -I... --sysroot=..."
33+
std::string cc; // "-std=c11 -O2 -I... --sysroot=..."
34+
std::string ld; // "-static -static-libstdc++ --sysroot=..."
35+
std::filesystem::path cxxBinary; // g++ 路径
36+
std::filesystem::path ccBinary; // gcc 路径(派生)
37+
std::filesystem::path arBinary; // ar 路径
38+
};
39+
40+
CompileFlags compute_flags(const BuildPlan& plan);
41+
42+
}
43+
```
44+
45+
从 ninja_backend.cppm 中提取:
46+
- include_dirs → `-I` 拼接
47+
- sysroot → `--sysroot=`
48+
- binutils → `-B`
49+
- opt_flag (`-O2` / `-Og`)
50+
- pic_flag、user_cxxflags/cflags
51+
- C 编译器路径推导 (`derive_c_compiler`)
52+
53+
**一处计算,多处消费**(ninja、compile_commands、未来后端)。
54+
55+
### 2.2 `src/build/compile_commands.cppm`
56+
57+
职责:生成标准 compile_commands.json。
58+
59+
```cpp
60+
export module mcpp.build.compile_commands;
61+
import mcpp.build.plan;
62+
import mcpp.build.flags;
63+
64+
export namespace mcpp::build {
65+
66+
std::string emit_compile_commands(const BuildPlan& plan,
67+
const CompileFlags& flags);
68+
69+
void write_compile_commands(const BuildPlan& plan,
70+
const CompileFlags& flags);
71+
72+
}
73+
```
74+
75+
-`arguments` 数组格式(clangd 推荐,避免 shell 转义问题)
76+
- 写到 `<projectRoot>/compile_commands.json`(clangd 默认向上查找)
77+
78+
### 2.3 `ninja_backend.cppm` 瘦身
79+
80+
- 删除 `compute_cxxflags()` / `compute_cflags()` 重复代码
81+
- `import mcpp.build.flags;` 复用 `CompileFlags`
82+
- `emit_ninja_string` 里直接用 `flags.cxx` / `flags.cc`
83+
84+
## 3. 调用链
85+
86+
```
87+
cli.cppm: cmd_build()
88+
├── BuildPlan plan = make_plan(...)
89+
├── CompileFlags flags = compute_flags(plan)
90+
├── write_compile_commands(plan, flags) ← 每次 build 自动
91+
└── backend->build(plan, opts) ← ninja 也用 flags
92+
```
93+
94+
## 4. JSON 格式
95+
96+
```json
97+
[
98+
{
99+
"directory": "/home/user/myproject",
100+
"file": "src/main.cpp",
101+
"arguments": [
102+
"/path/to/g++",
103+
"-std=c++23", "-fmodules", "-O2",
104+
"-I/path/to/include",
105+
"-c", "src/main.cpp",
106+
"-o", "target/.../obj/main.o"
107+
],
108+
"output": "target/.../obj/main.o"
109+
}
110+
]
111+
```
112+
113+
对标 clang JSON Compilation Database 规范:
114+
- `directory` + `file`: 必填
115+
- `arguments`: 推荐(优于 `command` 字符串)
116+
- `output`: 可选
117+
118+
## 5. 输出位置
119+
120+
`<projectRoot>/compile_commands.json` — clangd 从源文件向上找,根目录放置
121+
零配置即生效。
122+
123+
## 6. 后续扩展
124+
125+
| 扩展方向 | 实现方式 |
126+
|---|---|
127+
| 新后端(Makefile 等) | import `flags.cppm`,不重复计算 |
128+
| 增量更新 | diff 旧文件,避免无谓重写触发 clangd 重建索引 |
129+
| `mcpp compile-commands` 子命令 | 单独生成,不依赖完整 build |
130+
| per-target 过滤 | 函数参数加 target filter |
131+
| `.clangd` 配置 | `mcpp init` 可选生成 |

.clang-format

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# -----------------------------------------------------------------------------
2+
# mcpp-community C++ Style Configuration
3+
#
4+
# This configuration follows the style specification defined in:
5+
# https://github.com/mcpp-community/mcpp-style-ref
6+
#
7+
# Maintained by: mcpp-community
8+
# -----------------------------------------------------------------------------
9+
10+
Language: Cpp # Apply configuration to C++
11+
12+
# -----------------------------------------------------------------------------
13+
# Language Standard
14+
# -----------------------------------------------------------------------------
15+
Standard: Latest # Always use the latest supported C++ standard
16+
17+
# -----------------------------------------------------------------------------
18+
# Indentation
19+
# -----------------------------------------------------------------------------
20+
IndentWidth: 4 # Use 4 spaces for indentation
21+
TabWidth: 4 # Visual width of tab
22+
UseTab: Never # Never use tabs
23+
24+
# -----------------------------------------------------------------------------
25+
# Line Width
26+
# -----------------------------------------------------------------------------
27+
ColumnLimit: 100 # Maximum line width
28+
29+
# -----------------------------------------------------------------------------
30+
# Spaces
31+
# -----------------------------------------------------------------------------
32+
SpaceBeforeParens: ControlStatements # Space before parentheses for control statements (if/for/while); function calls remain tight
33+
SpacesInContainerLiterals: true # Enforce spaces in container literals
34+
SpaceBeforeAssignmentOperators: true # Add space before assignment operators
35+
SpacesInParentheses: false # No extra spaces inside parentheses
36+
PointerAlignment: Left # Pointer/reference attaches to type
37+
QualifierAlignment: Left # Place qualifiers like const to the left
38+
39+
# -----------------------------------------------------------------------------
40+
# Braces
41+
# -----------------------------------------------------------------------------
42+
BreakBeforeBraces: Attach # Opening brace stays on same line
43+
AllowShortFunctionsOnASingleLine: Empty # Allow empty functions like `void f() {}`
44+
AllowShortIfStatementsOnASingleLine: Never # Disallow single-line if statements
45+
AllowShortBlocksOnASingleLine: Empty # Allow empty blocks on one line
46+
AllowShortLoopsOnASingleLine: false # Disallow one-line loops
47+
48+
# -----------------------------------------------------------------------------
49+
# Constructor Initializer List
50+
# -----------------------------------------------------------------------------
51+
BreakConstructorInitializers: BeforeColon # Keep initializer list compact when short
52+
ConstructorInitializerAllOnOneLineOrOnePerLine: true # Allow compact initializer lists
53+
BreakConstructorInitializersBeforeComma: false # Do not break before commas
54+
55+
# -----------------------------------------------------------------------------
56+
# Access Modifiers
57+
# -----------------------------------------------------------------------------
58+
AccessModifierOffset: -4 # Align access modifiers with class indentation
59+
EmptyLineBeforeAccessModifier: Never # Do not insert empty line before access specifiers
60+
EmptyLineAfterAccessModifier: Never # Do not insert empty line after access specifiers
61+
62+
# -----------------------------------------------------------------------------
63+
# Namespace Formatting
64+
# -----------------------------------------------------------------------------
65+
NamespaceIndentation: None # Do not indent contents inside namespace
66+
FixNamespaceComments: true # Enforce closing namespace comments
67+
CompactNamespaces: true # Prefer namespace a::b instead of nested namespaces
68+
69+
# -----------------------------------------------------------------------------
70+
# Switch / Case Formatting
71+
# -----------------------------------------------------------------------------
72+
IndentCaseLabels: true # Indent case/default labels
73+
IndentCaseBlocks: true # Indent statements inside case blocks
74+
75+
# -----------------------------------------------------------------------------
76+
# Includes
77+
# -----------------------------------------------------------------------------
78+
SortIncludes: true # Automatically sort includes
79+
IncludeBlocks: Regroup # Regroup include blocks
80+
IncludeCategories:
81+
- Regex: "^<.*>" # Standard / third-party headers
82+
Priority: 1
83+
- Regex: '^".*"' # Project headers
84+
Priority: 2
85+
86+
# -----------------------------------------------------------------------------
87+
# Comment Alignment
88+
# -----------------------------------------------------------------------------
89+
AlignTrailingComments: true # Align trailing comments
90+
SpacesBeforeTrailingComments: 2 # Two spaces before trailing comments
91+
92+
# -----------------------------------------------------------------------------
93+
# Parameter Formatting
94+
# -----------------------------------------------------------------------------
95+
BinPackParameters: true # Allow parameters on same line
96+
BinPackArguments: true # Allow arguments on same line
97+
98+
# -----------------------------------------------------------------------------
99+
# Template Formatting
100+
# -----------------------------------------------------------------------------
101+
AlwaysBreakTemplateDeclarations: Yes # Always place template declarations on their own line
102+
103+
# -----------------------------------------------------------------------------
104+
# Operator Line Breaking
105+
# -----------------------------------------------------------------------------
106+
BreakBeforeBinaryOperators: None # Break after operators
107+
108+
# -----------------------------------------------------------------------------
109+
# Method Chain Formatting
110+
# -----------------------------------------------------------------------------
111+
PenaltyBreakBeforeFirstCallParameter: 10000 # Avoid breaking chained calls unless necessary
112+
113+
# -----------------------------------------------------------------------------
114+
# Lambda Formatting
115+
# -----------------------------------------------------------------------------
116+
AllowShortLambdasOnASingleLine: All # Allow short lambdas on one line
117+
118+
# -----------------------------------------------------------------------------
119+
# Using Declarations
120+
# -----------------------------------------------------------------------------
121+
SortUsingDeclarations: true # Automatically sort using declarations
122+
123+
# -----------------------------------------------------------------------------
124+
# Return Type Formatting
125+
# -----------------------------------------------------------------------------
126+
AlwaysBreakAfterReturnType: None # Break return type only when exceeding ColumnLimit
127+
128+
# -----------------------------------------------------------------------------
129+
# Concepts / Requires
130+
# -----------------------------------------------------------------------------
131+
RequiresClausePosition: OwnLine # Force requires clause to a new line
132+
IndentRequiresClause: false # Do not indent requires clause

.github/workflows/ci.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ jobs:
5656
- name: Bootstrap mcpp via xlings
5757
env:
5858
XLINGS_NON_INTERACTIVE: '1'
59-
XLINGS_VERSION: '0.4.25'
59+
XLINGS_VERSION: '0.4.30'
6060
run: |
61-
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
62-
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
63-
curl -fsSL -o "/tmp/${tarball}" \
64-
"https://github.com/d2learn/xlings/releases/download/v${XLINGS_VERSION}/${tarball}"
65-
tar -xzf "/tmp/${tarball}" -C /tmp
66-
"/tmp/xlings-${XLINGS_VERSION}-linux-x86_64/subos/default/bin/xlings" self install
67-
fi
61+
# Always install the pinned version — cache may hold an older
62+
# xlings whose sysroot/packages are incompatible.
63+
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
64+
curl -fsSL -o "/tmp/${tarball}" \
65+
"https://github.com/d2learn/xlings/releases/download/v${XLINGS_VERSION}/${tarball}"
66+
tar -xzf "/tmp/${tarball}" -C /tmp
67+
"/tmp/xlings-${XLINGS_VERSION}-linux-x86_64/subos/default/bin/xlings" self install
6868
export PATH="$HOME/.xlings/subos/default/bin:$PATH"
6969
xlings --version
7070
# xim:mcpp — `xlings install` is idempotent so cache hits skip

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
# Pin xlings to a known-good version. The upstream install
9999
# script always grabs `latest` (no version override), so we
100100
# download + self-install manually to avoid broken releases.
101-
XLINGS_VERSION: '0.4.25'
101+
XLINGS_VERSION: '0.4.30'
102102
run: |
103103
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
104104
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ target/
33

44
# mcpp's per-workspace xlings sandbox + lockfile + diagnostic logs
55
/.xlings/
6+
.sisyphus
67
.claude
78
mcpp.lock
89
doctor.log
@@ -19,3 +20,4 @@ doctor.log
1920
*.pcm
2021
*.ifc
2122
*.ddi
23+
compile_commands.json

mcpp.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ license = "Apache-2.0"
66
authors = ["mcpp-community"]
77
repo = "https://github.com/mcpp-community/mcpp"
88

9+
[build]
10+
# nlohmann/json.hpp lives in src/libs/json/; expose it to the global
11+
# module fragment `#include <json.hpp>` in src/libs/json.cppm.
12+
include_dirs = ["src/libs/json"]
13+
914
[toolchain]
1015
default = "gcc@16.1.0"
1116

0 commit comments

Comments
 (0)