Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

334 records.
335 records.

## By subject

Records that declare one. Everything else is listed by date below.

### build

- [依赖 image 的资源归属、模块扫描边界与锁文件稳定写入](2026-10-21-resource-ownership-module-scan-and-lock-write-design.md) — active

### build-program

- [构建依赖的一条管线:配置与产物两轴、包的实例、库接口、兼容系统与工作空间收尾(#797)](2026-10-11-build-dependencies-one-pipeline-design.md) — active
Expand Down Expand Up @@ -134,6 +138,7 @@ Records that declare one. Everything else is listed by date below.

### 2026-10

- [依赖 image 的资源归属、模块扫描边界与锁文件稳定写入](2026-10-21-resource-ownership-module-scan-and-lock-write-design.md) — active
- [首次初始化、home 重定向与网络诊断优化设计](2026-10-19-first-run-home-and-network-design.md) — landed
- [升级的连续性:打包修订不在使用路径上替换载荷、替换失败不拆掉可用状态、home 中的悬空记录自愈、真实的升级 lane](2026-10-17-upgrade-continuity-design.md) — active
- [mcpp 对 xlings 的依赖:Provider 端口、归属与位置、上游复用、系统级安装、payload 不可变、文件系统能力与长路径(#809)](2026-10-16-xlings-provider-port-and-shared-store-design.md) — active
Expand Down
20 changes: 19 additions & 1 deletion .github/tools/upgrade_lane.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,33 @@ new_project() { # <dir> <bin>
# ── the previous release builds the home ───────────────────────────────
run old-env "$W" "$OLD" self env || fail "the previous release does not start"
if [ "$VARIANT" = snapshot ]; then
# self env is read-only since 2026.10.19.1. Establish the old home
# explicitly before replacing its index; otherwise tar's empty -C argument
# leaves the live index in use and this lane never installs old packaging.
run old-init "$W" "$OLD" self init || { fail "the previous release cannot initialize its home"; exit 1; }
git clone -q --filter=blob:none https://github.com/openxlings/xim-pkgindex "$W/xpi" \
&& git -C "$W/xpi" checkout -q "$SNAPSHOT" || { echo "::error::cannot fetch the snapshot index"; exit 1; }
idx="$REG/data/xim-pkgindex"
[ -d "$idx" ] || idx=$(find "$MCPP_HOME" -type d -name xim-pkgindex | head -1)
[ -n "$idx" ] && [ -d "$idx/pkgs" ] \
|| { fail "the previous release created no index directory"; exit 1; }
find "$idx" -mindepth 1 -maxdepth 1 ! -name .xlings-index-version -exec rm -rf {} +
(cd "$W/xpi" && git archive HEAD) | tar x -C "$idx"
(cd "$W/xpi" && git archive HEAD) | tar x -C "$idx" \
|| { fail "the snapshot index was not materialized"; exit 1; }
[ -f "$idx/pkgs/l/llvm.lua" ] \
|| { fail "the snapshot has no LLVM descriptor"; exit 1; }
echo "llvm.lua revisions now: $(grep -o 'revision = [0-9]*' "$idx/pkgs/l/llvm.lua" | sort -u | tr '\n' ' ')"
fi
run old-tc "$W" "$OLD" toolchain install "$TC" || fail "the previous release cannot install $TC"
if [ "$VARIANT" = snapshot ]; then
"$PY" - "$REG/data/xpkgs/xim-x-llvm/23.1.3/.xpkg-install.json" <<'PY' \
|| { fail "the snapshot did not install LLVM revision zero"; exit 1; }
import json, sys
with open(sys.argv[1]) as f:
installed = json.load(f)
assert installed.get("revision", 0) == 0, installed
PY
fi
[ "$VARIANT" = orphan ] && { run old-tc-gcc "$W" "$OLD" toolchain install gcc@16.1.0 || fail "the previous release cannot install gcc"; }
new_project p-old "$OLD"
run old-run "$W/p-old" "$OLD" run || fail "the previous release cannot run a new project"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/cross-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ jobs:
run: |
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
bash tests/e2e/198_windows_resources_cross.sh
bash tests/e2e/923_cross_dependency_images_keep_their_resources.sh

# Packaging a Windows program FROM LINUX — and this job is the only
# place that can happen, for the same reason as the two above.
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@
> Each `## [<version>]` section is that release's notes. Entries are written in English
> from 2026.9.28.3 on; earlier entries remain as written.

## [2026.10.21.1] - 2026-10-21

### Fixed

- Dependency-owned executable artifacts and shared libraries embed their own
Windows resources. Resource ownership follows package identity, including
targets with the same name in different packages; consumer resources no
longer enter dependency images.
- Repeated planning preserves the contents and modification time of unchanged
lockfiles, including read-only files and either LF or CRLF line endings.
Lockfile read and write failures are reported to the caller.
- Build-database watch lists and input fingerprints exclude synthesized host
manifests and lockfiles while retaining editable build-dependency inputs.

### Documentation

- Clarify that the default module scanner reads source files without expanding
includes. Visible imports retain their transitive module mappings; no new
implicit-import compatibility mode is introduced.

## [2026.10.19.1] - 2026-10-19

### Added
Expand Down
9 changes: 9 additions & 0 deletions docs/04-mcpp-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,10 @@ set `MCPP_VERIFY_MODGRAPH=1` when generating the build.

### 2.8.4 What The Default Scanner Reads

The default scanner reads each source file without expanding `#include`. Imports
that it discovers belong in the scanned source file itself. A header containing
`import` does not add an edge to this default module graph.

The scanner answers two questions per file — what does this unit provide, and
what does it require — and nothing else decides them.

Expand Down Expand Up @@ -1778,6 +1782,11 @@ generates the resource script automatically.
**not** need (and cannot use) a `cfg(windows)` predicate — write it once,
unconditionally.

Resources belong to the package that owns the executable or shared library.
Dependency-owned executable artifacts and shared libraries embed their own
resources, including when built through a consumer (2026.10.21.1+). Resources
do not propagate from a static dependency to its consumer.

**The resource object is the target's.** rc.exe and llvm-rc produce a `.res`,
which carries no machine and is linked as it is. windres produces a COFF object,
which does: mcpp gives LLVM's windres the target triple and GNU windres the BFD
Expand Down
5 changes: 5 additions & 0 deletions docs/05-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ package declares `[features]` but does not include the requested feature (includ
the result of backend desugaring), a warning is issued by default, and an error
under `mcpp build --strict`.

An unchanged `mcpp.lock` retains its contents and modification time when a build
records the same resolution (2026.10.21.1+). LF and CRLF line endings are accepted
without rewriting an otherwise identical file. This does not skip dependency
resolution or change which dependencies the lock pins.

**Git dependencies and `mcpp.lock`**: a `tag` or `rev` already names a fixed point
in history, but a `branch` moves. The first build resolves the branch to a commit
and records it in `mcpp.lock`, and every later build rebuilds **that** commit — the
Expand Down
12 changes: 8 additions & 4 deletions docs/specs/build-database.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
|---|---|
| 规范编号 | SPEC-005 |
| 标题 | mcpp 输出的构建数据库:内容、取值规则与不写工程目录的保证 |
| 状态 | 评审中 v1.8 |
| 版本 | 1.8 |
| 最后修改 | 2026-10-11 |
| 对应实现 | mcpp >= 2026.9.15.1;v1.3 修改的 R2.5、R3.7、R3.8、R4.1、R5.2 为 mcpp >= 2026.9.26.2;v1.4 修改的 R2.5 为 mcpp >= 2026.9.27.1;v1.5 修改的 R3.7、R3.12、R5.1、R5.2 为 mcpp >= 2026.9.28.1;v1.6 修改的 R2.1、R3.3、R3.4、R3.5、R4.1、R5.2 为 mcpp >= 2026.9.29.5;v1.7 新增的 R3.8a 为 mcpp >= 2026.9.30.2;v1.8 新增的 R3.13 为 mcpp >= 2026.10.11.1 |
| 状态 | 评审中 v1.9 |
| 版本 | 1.9 |
| 最后修改 | 2026-10-21 |
| 对应实现 | mcpp >= 2026.9.15.1;v1.3 修改的 R2.5、R3.7、R3.8、R4.1、R5.2 为 mcpp >= 2026.9.26.2;v1.4 修改的 R2.5 为 mcpp >= 2026.9.27.1;v1.5 修改的 R3.7、R3.12、R5.1、R5.2 为 mcpp >= 2026.9.28.1;v1.6 修改的 R2.1、R3.3、R3.4、R3.5、R4.1、R5.2 为 mcpp >= 2026.9.29.5;v1.7 新增的 R3.8a 为 mcpp >= 2026.9.30.2;v1.8 新增的 R3.13 为 mcpp >= 2026.10.11.1;v1.9 明确的 R6.1a 为 mcpp >= 2026.10.21.1 |
| 相关设计文档 | `.agents/docs/2026-09-14-636-build-database-and-the-latest-xlings.md`<br>`.agents/docs/2026-09-26-compile-database-and-issue-699-design.md` |
| 相关 issue | #636, #648, #655, #699, #702, #707, #732, #797 |
| 依据的外部规范 | S1「C++ Build Database: IDE Profile」profile 0.3.0(§7.2 的 `generated`,Sunrisepeak/mcpp-language-server#28;此前为 0.2.0)与 S2 0.2.0 §3.4,取自 https://github.com/Sunrisepeak/lsp-mcpp-private 提交 `b82859d`(schema 自提交 `28ecd6e` 起未变);S2 0.3.0 §3.4 的部分回答(S2-3.4-12、S2-3.4-13,Sunrisepeak/mcpp-language-server#25);JSON Compilation Database |
Expand Down Expand Up @@ -239,6 +239,9 @@ mcpp 输出的 S1 文档满足 S1 等级 2,不输出 `ide.options`。等级 3
`tests/**/*.cpp`);构建程序声明的输入文件与 glob;`$MCPP_HOME/config.toml`。位于
工作区根之下的条目写成相对工作区根、以 `/` 分隔的路径或 glob;之外的条目写成绝对
路径,其 glob 展开为运行时匹配到的文件。**已实现**
- **R6.1a** 合成构建程序图的根与成员清单、锁文件属于规划输出,**禁止**进入 `watch`
与 `inputs-fingerprint` 的文件输入集合。该图引用的真实可编辑包的清单、源文件与声明输入
仍按 R6.1 监视。**已实现**(mcpp >= 2026.10.21.1,#807)
- **R6.2** 不监视:环境变量,包括 `MCPP_TOOLCHAIN`、`MCPP_HOME` 与构建程序声明的
环境变量;存储中的包与 git 依赖的检出,它们的版本或提交写在已监视的清单与锁中。
**已实现**
Expand All @@ -261,3 +264,4 @@ mcpp 输出的 S1 文档满足 S1 等级 2,不输出 `ide.options`。等级 3
| 1.6 | 2026-09-29 | 工作区按配置规划,与 `mcpp build` 相同(R2.1、R3.3、R3.4、R5.2):成员共用的包在一个配置中只描述一次;集合名的前缀由 `<成员>/` 改为只在文档描述多个配置时出现的 `<配置>/`;一个配置的规划失败时逐成员规划。R3.5:被选成员的集合按其目标给出 `ide.kind`。R4.1:同一文件与输出一条条目。 |
| 1.7 | 2026-09-30 | 新增 R3.8a:同一配置中两个包提供同一个模块名时,两个单元都列出它,可能导入它的单元的 `arguments` 带有构建所用的绑定(#732)。 |
| 1.8 | 2026-10-11 | 新增 R3.13:构建程序、构建程序实例的库与引擎接口以 `<包>:build`、`<包>:host`、`mcpp:core`、`mcpp:std:host` 集合描述,`ide.configuration` 为 `build-program`,只进入 S1 文档(#797)。 |
| 1.9 | 2026-10-21 | R6.1a 明确合成 host 清单与锁文件不作为 watch 或 fingerprint 输入,保留可编辑依赖输入(#807)。 |
17 changes: 15 additions & 2 deletions docs/specs/manifest-semantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
| **规范编号** | SPEC-004 |
| **标题** | `mcpp.toml` 的平面划分、条件化形状、解析轴与命名规约 |
| **状态** | **草案(Draft)** |
| **版本** | 1.15 |
| **最后修改** | 2026-10-11 |
| **版本** | 1.16 |
| **最后修改** | 2026-10-21 |
| **最低实现版本** | 条件化形状:mcpp **2026.8.29.1**(`[target.<selector>.build-dependencies]` 起齐备);目标轴:mcpp **2026.9.6.4** |
| **作者/维护** | mcpp-community |
| **相关设计文档** | `.agents/docs/2026-09-07-mcpp-toml-unified-semantics-design.md`<br>`.agents/docs/2026-06-04-manifest-schema-ownership.md`<br>`.agents/docs/2026-09-03-xlings-workspace-as-the-one-table.md`<br>`.agents/docs/2026-09-25-issue-690-workspace-build-inheritance-consistency.md`<br>`.agents/docs/2026-09-27-eight-reports-by-home-and-one-optimisation-plan.md`<br>`.agents/docs/2026-10-05-std-module-pair-msvc-lto-and-export-discovery-design.md`<br>`.agents/docs/2026-10-06-windows-x86-arch-vocabulary-and-rc-follow-ups-design.md`<br>`.agents/docs/2026-10-10-one-source-one-meaning-design.md`<br>`.agents/docs/2026-10-11-build-dependencies-one-pipeline-design.md` |
Expand Down Expand Up @@ -707,6 +707,18 @@ mcpp 2026.10.10.1,#785、#786;第 14 至 16 条与第 13 条的依赖位置为 m

**状态:已实现(mcpp 2026.10.11.1,#797)。**

## 13. Windows 资源的归属

1. `[resources]` **必须**只作用于声明包自己拥有的可执行程序与共享库,包括未被直接选择、
通过 `artifacts` 构建的程序以及普通依赖共享库。image 的归属按限定包身份决定,
**禁止**按 target 名称推断或将根包视为所有 image 的拥有者。
2. 依赖资源**禁止**传播到消费者 image。静态库没有自己的 PE image,其资源不自动合并进
消费者。测试 image 只接收现有测试 manifest 规则所允许的内容。
3. 声明文件的存在性校验与资源编译分开:校验对所有目标生效;编译只对 PE 目标生效。
本次计划未生成的 target 不参与 image 的 manifest 冲突检查。

**已实现**(mcpp >= 2026.10.21.1,#826)。

## 变更记录

| 版本 | 日期 | 变更 |
Expand All @@ -727,3 +739,4 @@ mcpp 2026.10.10.1,#785、#786;第 14 至 16 条与第 13 条的依赖位置为 m
| 1.13 | 2026-10-06 | mcpp 2026.10.5.3:§4.6 陈述架构段的等同拼写,`x86` 即 `i686`;`i386` 至 `i586` 不与 `i686` 相互替代。 |
| 1.14 | 2026-10-10 | mcpp 2026.10.10.1(#785、#786):§2 陈述键的作用域与来源;§9 新增第 12 条前缀即语义(工作空间层 `[workspace.X]`、按键合并、W7)与第 13 条按位置读取的兼容期;第 7 条发布写出工作空间层;第 8 条改为 `[workspace.xlings]`;第 10 条按求值后的配置分组。 |
| 1.15 | 2026-10-11 | mcpp 2026.10.11.1(#797):新增 §12 依赖的库与配置(两条轴、实例、一个包一个版本、按配置激活特性、`host-module` 的含义与默认值、构建程序图、构建插件、兼容读法);§9 第 13 条的移除版本改为 mcpp 2027.1,并补依赖位置;新增 §9 第 14 至 16 条(`[xlings.overrides]` 属于构建的根、`[workspace.dependencies]` 的继承、虚拟根旁的 `build.mcpp`)。 |
| 1.16 | 2026-10-21 | 新增 §13,明确依赖 EXE、DLL 的资源只进入其所属包的 image,且按计划内目标校验 manifest 冲突(#826)。 |
6 changes: 6 additions & 0 deletions docs/zh/04-mcpp-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,9 @@ override),在生成构建时设置 `MCPP_VERIFY_MODGRAPH=1`。

### 2.8.4 默认扫描器读到的东西

默认扫描器逐个读取源文件,不展开 `#include`。需要由它发现的 import 写在被扫描的
源文件本身;头文件中的 `import` 不为默认模块图增加导入边。

扫描器为每个文件回答两个问题——这个单元提供什么、这个单元需要
什么——没有别的东西决定这两个答案。

Expand Down Expand Up @@ -1663,6 +1666,9 @@ icon = "assets/app.ico"
没有资源单元、没有诊断、构建逐字节相同。**不需要**(也不能用)一个
`cfg(windows)` 谓词——写一次,无条件生效即可。

资源属于拥有可执行程序或共享库的包。依赖的 executable artifact 与共享库在通过
消费者构建时也嵌入自己的资源(2026.10.21.1+)。静态依赖的资源不传播给消费者。

**资源对象属于目标。** rc.exe 与 llvm-rc 产出 `.res`,它不带机器类型,
按原样参与链接。windres 产出 COFF 对象,它带机器类型:mcpp 交给 LLVM 的
windres 目标三元组,交给 GNU windres BFD 格式名(`pe-i386`、`pe-x86-64`),
Expand Down
3 changes: 3 additions & 0 deletions docs/zh/05-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ widget = { version = "1.0", backend = "glfw_opengl3" } # Sugar for: features=["
一族 `backend-*`)。若目标包声明了 `[features]` 但不含所请求的 feature
(包括 backend 脱糖的结果),默认给出 warning,`mcpp build --strict` 下报错。

构建记录相同的解析结果时,`mcpp.lock` 保留原内容与修改时间(2026.10.21.1+)。
仅 LF 与 CRLF 行结束形式不同不会触发改写。这不跳过依赖解析,也不改变锁定范围。

**Git 依赖与 `mcpp.lock`**:`tag` 和 `rev` 已经指向历史中的一个固定点,而
`branch` 是会移动的。首次构建把分支解析成一个 commit 并写进 `mcpp.lock`,
此后每次构建都重新构建**那个** commit —— lock 是权威来源而不是缓存提示,
Expand Down
2 changes: 1 addition & 1 deletion mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mcpp"
version = "2026.10.19.1"
version = "2026.10.21.1"
description = "Modern C++ build & package management tool"
license = "Apache-2.0"
authors = ["mcpp-community"]
Expand Down
2 changes: 1 addition & 1 deletion modules/versioning/src/version.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ import std;

export namespace mcpp {

inline constexpr std::string_view MCPP_VERSION = "2026.10.19.1";
inline constexpr std::string_view MCPP_VERSION = "2026.10.21.1";

} // namespace mcpp
6 changes: 5 additions & 1 deletion src/build/build_database.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,12 @@ Rendered render(std::span<const Member> members,
sets.push_back(std::move(setJson));
}

watch_file(ctx.projectRoot / "mcpp.lock");
// A host graph's root and members are manifests we synthesized, not
// editable inputs. Watching their lock makes emit trigger itself (#807).
// Keep the real path libraries of that graph: their sources can change.
if (!member.buildPrograms) watch_file(ctx.projectRoot / "mcpp.lock");
for (auto const& sp : ctx.sourcePackages) {
if (member.buildPrograms && relative_to(sp.root, ctx.projectRoot)) continue;
watch_file(sp.root / "mcpp.toml");
std::error_code ec;
if (std::filesystem::exists(sp.root / "build.mcpp", ec))
Expand Down
6 changes: 5 additions & 1 deletion src/build/prepare/plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ static std::expected<void, std::string> step13_source_packages(PrepareState& sta
[&](const BuildContext::SourcePackage& sp) {
return sp.root.lexically_normal() == normalized;
});
if (!known)
// Legacy project-local index payloads can lie outside storeRoots.
// Their version, not an editable source tree, is the input (#807).
const bool versionPayload = i > 0 && i - 1 < state.dep_cache_identities.size()
&& state.dep_cache_identities[i - 1].sourceKind == "version";
if (!known && !versionPayload)
ctx.sourcePackages.push_back({qualified(state.packages[i].manifest),
normalized,
state.packages[i].manifest.modules.sources});
Expand Down
3 changes: 2 additions & 1 deletion src/build/prepare/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ std::expected<void, std::string> step13_lockfile(PrepareState& state, BuildConte
return std::unexpected(msg);
}
}
(void)mcpp::lockfile::write(lock, lockPath);
if (auto written = mcpp::lockfile::write(lock, lockPath); !written)
return std::unexpected(written.error().message);
}

// Same data, second consumer: the "Compiling <dep> v<version>" banner.
Expand Down
Loading
Loading