Skip to content

Commit 6b6cfbd

Browse files
speak-agentclaude
andcommitted
2026.9.27.1: e2e 804 for a path host tool's toolchain (#710); e2e 802 pins gcc; compatibility notes
e2e 804 builds a host tool reached through a plain path dependency, which belongs to no workspace: without a [toolchain] of its own the tool is built by the consumer's build-program compiler (llvm 22.1.8 in the test, while the global default on Linux is gcc), and with one it is built by that compiler. The released 2026.9.26.2 fails the first criterion; this branch passes both. e2e 802 read libstdc++'s NEEDED entry under whatever toolchain the machine defaults to, so it failed where the user's default is llvm; the manifest now names gcc@16.1.0. CHANGELOG: the changes an existing project can observe -- an unresolved `workspace = true` is refused (#714), `sources = []` no longer infers a library, and the build-database note code was renamed without an alias. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent bba733a commit 6b6cfbd

3 files changed

Lines changed: 120 additions & 0 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,20 @@
5252
- `mcpp pack` 的 bundle-all 形态随 glibc 载荷复制 `lib/locale` 与 `lib/gconv`,启动脚本设置
5353
`LOCPATH` 与 `GCONV_PATH`(用户已设置时保留用户的值)。
5454

55+
### 兼容性
56+
57+
以下变化对已有工程可见:
58+
59+
- 未解析的 `workspace = true` 此前静默成为空版本依赖,现在在加载时报错并点名条目(#714)。
60+
修正方法是在工作空间根的 `[workspace.dependencies]` 中声明该包,或在条目上写明版本。
61+
- `[build] sources = []` 不再推断库目标。依赖这一推断的包在 `[targets]` 中声明库目标。
62+
- note 代码 `MCPP_BUILD_DATABASE_HOST_TOOL_UNBUILT` 由 `MCPP_BUILD_DATABASE_HOST_TOOL_DEFERRED`
63+
取代,不保留旧代码。
64+
5565
### 其他
5666

67+
- 测试:e2e 804 覆盖不属于任何工作空间的路径宿主工具包的工具链选择(#710);e2e 802 固定 gcc
68+
工具链,使其断言不依赖机器的默认工具链。
5769
- ELF 检查以一次读取载入文件。此前逐字节读入,`mcpp test` 的链接后检查在测试程序较多时耗时
5870
数十分钟。
5971
- 规范:SPEC-001 v1.5、SPEC-004 v1.8、SPEC-005 v1.4、SPEC-007 v0.3。

‎tests/e2e/802_a_host_build_applies_its_host_row.sh‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ version = "0.1.0"
3333
standard = "c++23"
3434
import_std = false
3535
36+
# The criteria read libstdc++'s NEEDED entry, so the compiler is gcc whatever
37+
# the machine's default toolchain is.
38+
[toolchain]
39+
default = "gcc@16.1.0"
40+
3641
[targets.cxxrt]
3742
kind = "bin"
3843
main = "src/main.cpp"
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env bash
2+
# requires: gcc elf
3+
# 804_a_path_host_tool_builds_with_its_chosen_toolchain.sh — mcpp#710.
4+
#
5+
# A host tool is built by one compiler, chosen once and recorded in the tool
6+
# store's key: `MCPP_TOOLCHAIN` when set, else the tool package's own
7+
# `[toolchain]` (its workspace's, for a member), else the compiler the
8+
# consumer compiles its build programs with. The member case has a unit test
9+
# (HostToolToolchain.AMemberToolReadsItsWorkspaceToolchain). This test covers
10+
# a tool reached through a plain path dependency, which belongs to no
11+
# workspace:
12+
# 1. a tool package that names no toolchain is built by the consumer's
13+
# build-program compiler (llvm 22.1.8 here), not by the global default
14+
# (gcc on Linux), which is what the sub-build used to resolve for itself;
15+
# 2. a tool package that names its own toolchain is built by it
16+
# (gcc 16.1.0) while the consumer keeps llvm.
17+
# The compiler that produced the tool is read from its `.comment` section.
18+
set -e
19+
20+
TMP=$(mktemp -d)
21+
trap "rm -rf $TMP" EXIT
22+
cd "$TMP"
23+
24+
# An isolated home, so neither the user's default toolchain nor a stale tool
25+
# store entry decides the outcome. The registry is shared: toolchains are
26+
# expensive to install.
27+
export MCPP_HOME="$TMP/mcpphome"
28+
mkdir -p "$MCPP_HOME"
29+
if [ -d "$HOME/.mcpp/registry" ]; then
30+
ln -s "$HOME/.mcpp/registry" "$MCPP_HOME/registry"
31+
fi
32+
unset MCPP_TOOLCHAIN
33+
34+
mkdir -p toolpkg/src app/src
35+
write_tool() { # $1 = the body of the tool's [toolchain] table, empty for none
36+
cat > toolpkg/mcpp.toml <<'TOML'
37+
[package]
38+
name = "toolpkg"
39+
version = "0.1.0"
40+
41+
[targets.stamp]
42+
kind = "bin"
43+
main = "src/stamp.cpp"
44+
TOML
45+
if [[ -n "$1" ]]; then
46+
printf '\n[toolchain]\n%s\n' "$1" >> toolpkg/mcpp.toml
47+
fi
48+
}
49+
cat > toolpkg/src/stamp.cpp <<'CPP'
50+
int main() { return 0; }
51+
CPP
52+
53+
cat > app/mcpp.toml <<'TOML'
54+
[package]
55+
name = "app"
56+
version = "0.1.0"
57+
58+
[toolchain]
59+
default = "llvm@22.1.8"
60+
61+
[dependencies]
62+
toolpkg = { path = "../toolpkg", tools = ["stamp"] }
63+
TOML
64+
cat > app/src/main.cpp <<'CPP'
65+
int main() {}
66+
CPP
67+
cat > app/build.mcpp <<'CPP'
68+
#include <string>
69+
import mcpp;
70+
int main() {
71+
const char* tool = mcpp::dep_bin("toolpkg", "stamp");
72+
if (!tool || !*tool) return 1;
73+
mcpp::warning((std::string("TOOL=") + tool).c_str());
74+
}
75+
CPP
76+
77+
tool_path() { sed -n 's/.*TOOL=//p' "$1" | tail -1; }
78+
79+
# ── 1 ── no toolchain of its own: the consumer's build-program compiler
80+
write_tool ""
81+
(cd app && "$MCPP" build > ../b1.log 2>&1) || { cat b1.log; echo "FAIL: 1: build failed"; exit 1; }
82+
t="$(tool_path b1.log)"
83+
[[ -x "$t" ]] || { cat b1.log; echo "FAIL: 1: no tool binary at '$t'"; exit 1; }
84+
readelf -p .comment "$t" > c1.txt
85+
grep -q 'clang version 22\.1\.8' c1.txt || {
86+
cat c1.txt; echo "FAIL: 1: the tool was not built by the consumer's llvm 22.1.8"; exit 1; }
87+
echo "ok: 1"
88+
89+
# ── 2 ── its own toolchain: that one, whatever the consumer uses
90+
write_tool 'default = "gcc@16.1.0"'
91+
rm -rf app/target
92+
(cd app && "$MCPP" build > ../b2.log 2>&1) || { cat b2.log; echo "FAIL: 2: build failed"; exit 1; }
93+
t="$(tool_path b2.log)"
94+
[[ -x "$t" ]] || { cat b2.log; echo "FAIL: 2: no tool binary at '$t'"; exit 1; }
95+
readelf -p .comment "$t" > c2.txt
96+
grep -qE 'GCC: \(.*\) 16\.1\.0' c2.txt || {
97+
cat c2.txt; echo "FAIL: 2: the tool's own [toolchain] was not used"; exit 1; }
98+
if grep -q 'clang version' c2.txt; then
99+
cat c2.txt; echo "FAIL: 2: the tool was built by the consumer's clang"; exit 1
100+
fi
101+
echo "ok: 2"
102+
103+
echo "PASS: 804_a_path_host_tool_builds_with_its_chosen_toolchain"

0 commit comments

Comments
 (0)