ccgo 3.7.2

A high-performance C++ cross-platform build CLI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# 版本冲突解决

## 概述

CCGO 提供基于语义化版本的**智能版本冲突解决**,自动检测和解决依赖版本冲突。它确保项目使用所有依赖之间相互兼容的版本。

## 收益

- 🎯 **自动检测** —— 在依赖解析期间识别版本冲突
- 🔄 **智能解析** —— 使用 semver 规则查找兼容版本
- 📊 **清晰报告** —— 展示详细的冲突信息
-**正确性保证** —— 仅允许兼容版本
- 🚀 **零配置** —— 自动生效

## 工作原理

### 语义化版本

CCGO 使用 [Semantic Versioning(SemVer)](https://semver.org/) 进行版本解析:

- **格式**`MAJOR.MINOR.PATCH`(例如 `1.2.3`- **版本范围**:支持 `^``~``>=``<`- **兼容性**:判定版本之间能否协同工作

### 版本需求

CCGO 支持多种版本需求格式:

| 格式      | 示例              | 含义                         |
|-----------|-------------------|------------------------------|
| **精确**  | `1.2.3`           | 精确为 1.2.3                 |
| **Caret** | `^1.2.3`          | >= 1.2.3, < 2.0.0(兼容)    |
| **Tilde** | `~1.2.3`          | >= 1.2.3, < 1.3.0(仅 patch)|
| **通配符**| `1.2.*``*`    | 任意 patch 或任意版本        |
| **范围**  | `>=1.0, <2.0`     | 多个约束                     |

### 冲突检测

CCGO 在以下情况下检测到冲突:
1. 多个依赖要求同一包的不同版本
2. 这些版本需求按 semver 规则**不兼容**

```
Project
  ├─ dep_a (requires fmt@^10.0.0)
  └─ dep_b (requires fmt@^11.0.0)   ← 冲突!
```

### 解析策略

检测到冲突时,CCGO:

1. **分析需求** —— 检查每个包的所有版本需求
2. **查找兼容版本** —— 使用 semver 找到满足所有需求的版本
3. **选择最高版本** —— 优先选用满足条件的最高版本
4. **报告失败** —— 若不存在兼容版本,输出详细错误

## 使用方法

### 自动解析

版本冲突解析在 `ccgo install` 期间自动进行:

```bash
$ ccgo install

📊 Resolving dependency graph...
⚠️  Detected 1 version conflicts:

   Package: fmt
      dep_a requires ^10.0.0
      dep_b requires 10.1.0
   ✓ Resolved to: 10.1.0

✓ Dependency graph resolved
```

### 兼容需求

需求兼容时,CCGO 静默完成解析:

```toml
# 项目 CCGO.toml
[[dependencies]]
name = "dep_a"
# dep_a requires fmt@^10.0.0

[[dependencies]]
name = "dep_b"
# dep_b requires fmt@10.1.0
```

**解析结果**:使用 `10.1.0`(同时满足 `^10.0.0` 和 `10.1.0`)

### 不兼容需求

需求冲突时,CCGO 输出错误:

```bash
$ ccgo install

📊 Resolving dependency graph...
⚠️  Detected 1 version conflicts:

   Package: fmt
      dep_a requires 10.0.0
      dep_b requires 11.0.0

Error: Cannot resolve version conflict for 'fmt': incompatible requirements
  - dep_a requires 10.0.0
  - dep_b requires 11.0.0
```

## 示例

### 示例 1:Caret 范围兼容

```toml
# dep_a/CCGO.toml
[[dependencies]]
name = "fmt"
version = "^10.0.0"   # 允许 10.x.x,< 11.0.0

# dep_b/CCGO.toml
[[dependencies]]
name = "fmt"
version = "10.2.1"    # 范围内的具体版本
```

**结果**:✅ 解析为 `10.2.1`(同时满足两个需求)

### 示例 2:Tilde 范围

```toml
# dep_a/CCGO.toml
[[dependencies]]
name = "spdlog"
version = "~1.11.0"   # 允许 1.11.x patch

# dep_b/CCGO.toml
[[dependencies]]
name = "spdlog"
version = "1.11.2"    # patch 版本
```

**结果**:✅ 解析为 `1.11.2`

### 示例 3:主版本冲突

```toml
# dep_a/CCGO.toml
[[dependencies]]
name = "json"
version = "3.10.0"    # v3.x

# dep_b/CCGO.toml
[[dependencies]]
name = "json"
version = "4.0.0"     # v4.x
```

**结果**:❌ 错误 —— 主版本不兼容

### 示例 4:通配符

```toml
# dep_a/CCGO.toml
[[dependencies]]
name = "catch2"
version = "*"         # 任意版本

# dep_b/CCGO.toml
[[dependencies]]
name = "catch2"
version = "3.4.0"     # 具体版本
```

**结果**:✅ 解析为 `3.4.0`(通配符接受任意版本)

## 常见场景

### 场景 1:菱形依赖

```
    Project
   /        \
  A          B
   \        /
    C@1.0  C@1.1
```

若 C@1.1 与 A 的需求兼容(例如 A 需要 `^1.0`):
- **解析结果**:使用 C@1.1
若不兼容(例如 A 需要精确的 `1.0.0`):
- **解析结果**:错误 ❌

### 场景 2:深层传递冲突

```
Project → A → B → C@2.0
Project → D → E → C@3.0
```

即便嵌套较深,CCGO 也能检测到 C@2.0 与 C@3.0 之间的冲突。

### 场景 3:多路径指向同一依赖

```
Project → A → C@^1.0
Project → B → C@^1.0
Project → D → C@1.2.0
```

三个需求互相兼容 —— 解析为 C@1.2.0 ✅

## 版本需求最佳实践

### 推荐做法

✅ **库依赖使用 caret 范围**
```toml
version = "^1.2.3"   # 允许兼容更新
```

✅ **关键依赖使用精确版本**
```toml
version = "2.5.0"    # 锁定具体版本
```

✅ **保持项目内主版本一致**
```toml
# 良好:均使用 fmt v10
dep_a = { version = "^10.0.0" }
dep_b = { version = "10.1.0" }
```

✅ **定期更新**,避免冲突积累
```bash
ccgo update
```

### 应避免

❌ **生产环境不要使用通配符**
```toml
version = "*"        # 版本不可预测
```

❌ **避免无谓地混用主版本**
```toml
# 不好:主版本不一致
dep_a = "1.0.0"      # v1
dep_b = "2.0.0"      # v2  ← 极易冲突
```

❌ **不要过度收紧约束**
```toml
version = "=1.2.3"   # 过于严格,难以解析
```

## 故障排查

### 冲突无法解决

**症状**:报错提示需求不兼容

**方案 1 —— 更新依赖**:
```bash
# 更新依赖到兼容版本
ccgo update

# 查看可用版本
ccgo search <package_name>
```

**方案 2 —— 调整版本需求**:
```toml
# 之前(过于严格)
[[dependencies]]
name = "fmt"
version = "10.0.0"    # 精确版本

# 之后(更灵活)
[[dependencies]]
name = "fmt"
version = "^10.0.0"   # 允许兼容版本
```

**方案 3 —— 联系维护者**:
若依赖之间确有冲突需求,可联系维护者:
- 请求版本更新
- 上报兼容性问题
- 建议调整版本范围

### 理解冲突报告

```
⚠️  Detected 1 version conflicts:

   Package: boost
      graphics_lib requires ^1.75.0
      network_lib requires ^1.80.0
      core_lib requires 1.76.0
```

**分析**:
- `graphics_lib` 需要 Boost 1.75+(< 2.0)
- `network_lib` 需要 Boost 1.80+(< 2.0)
- `core_lib` 需要精确 1.76.0

**问题所在**:core_lib 的精确版本(1.76.0)与 network_lib 的下限(1.80.0)冲突

**修复**:将 core_lib 改为使用 `^1.76.0` 而非 `1.76.0`

### 版本未找到

**症状**:报错 "Cannot extract version from range"

**原因**:版本格式无效或不受支持

**解决方法**:使用标准 semver 格式
```toml
# 不好
version = "v1.2.3"     # 不要带 'v' 前缀
version = "1.2"        # 缺失 patch 号

# 良好
version = "1.2.3"      # 完整 semver
version = "^1.2.0"     # 合法范围
```

## 进阶主题

### 自定义版本解析

目前 CCGO 仅支持自动解析。后续版本可能支持:

```toml
[resolution]
# 强制指定版本(覆盖冲突)
fmt = "10.1.0"
boost = "1.80.0"
```

### 版本锁定文件

为了保证可复现构建,CCGO 将支持锁定文件:

```bash
# 生成锁定文件
ccgo install

# 这会创建 CCGO.lock,记录精确解析的版本

# 使用锁定版本
ccgo install --locked
```

### 冲突解析策略

未来可能新增的策略:

1. **最高兼容**(当前)—— 选择满足所有需求的最高版本
2. **最低兼容** —— 选择最低版本(更保守)
3. **始终最新** —— 使用最新可用版本
4. **用户指定** —— 在 CCGO.toml 中手动覆盖

## 实现细节

### 版本比较算法

```rust
// 伪代码
fn is_compatible(req1: &VersionReq, req2: &VersionReq) -> bool {
    // 检查是否存在某个版本能同时满足两个需求
    for candidate_version in all_versions {
        if req1.matches(candidate_version) && req2.matches(candidate_version) {
            return true;
        }
    }
    false
}
```

### 冲突解析算法

```rust
// 伪代码
fn resolve_conflict(requirements: Vec<VersionReq>) -> Result<Version> {
    // 找到满足所有需求的最高版本
    let mut candidates = vec![];

    for req in requirements {
        let versions = extract_versions_from(req);
        candidates.extend(versions);
    }

    // 按版本号排序(高版本在前)
    candidates.sort_by(|a, b| b.cmp(a));

    // 找到第一个满足所有需求的版本
    for version in candidates {
        if requirements.iter().all(|req| req.matches(&version)) {
            return Ok(version);
        }
    }

    Err("No compatible version found")
}
```

## 另请参阅

- [依赖管理]features/dependency-management.zh.md —— 整体依赖系统
- [Semantic Versioning]https://semver.org/ —— SemVer 规范
- [依赖解析]dependency-resolution.zh.md —— 传递依赖处理

## 变更日志

### v3.0.12 (2026-01-21)

- ✅ 实现版本冲突检测
- ✅ 语义化版本支持(精确、范围、通配符)
- ✅ 智能冲突解析,选择最高兼容版本
- ✅ 详细的冲突报告
- ✅ 支持 caret(^)、tilde(~)和范围操作符
- ✅ 含解决建议的全面错误信息

---

*版本冲突解决自动确保项目使用相互兼容的依赖版本。*