Skip to content

Commit b67e928

Browse files
committed
fix: keep the explicit ELF unwinder selection self-contained
1 parent 6612505 commit b67e928

6 files changed

Lines changed: 381 additions & 11 deletions

File tree

‎.agents/docs/2026-10-08-llvm-2313-part2-execution-and-dependencies.md‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,35 @@ ARM64 与 x86_64 的 libunwind.a 都具有默认可见的全局符号。
265265
31 个并增加对应 DT_NEEDED。这是定位对照,不能替代原生消费证明。
266266
失败门补存实际测试 ELF、readelf 结果与 build.ninja,再根据链接
267267
闭包判断原因;尚不调整资产、不隐藏导出以替代动态依赖诊断。
268+
269+
## 13. 2026-10-08 静态 unwinder 的驱动追加项更正
270+
271+
第 12 节的强化对照使用同一 ARM64 候选 glibc、libc++、libc++abi
272+
与 libunwind,加入 filesystem、thread、exception_ptr 和 runtime_error。
273+
静态链接组合导出零个 unwind 符号;按驱动顺序追加
274+
`--as-needed libunwind.so --no-as-needed` 后导出 31 个,两者均在
275+
QEMU 下运行成功,DT_NEEDED 均仅为 libc.so.6 与 libm.so.6。
276+
因此,额外动态库即使最终被丢弃,LLD 扫描时对静态定义的导出提升
277+
仍会保留;第 12 节简单对照中的额外 DT_NEEDED 不是必要条件。
278+
279+
distribution 的 ELF self-contained 分支已经显式链接 libunwind.a,
280+
现以末尾 `--unwindlib=none` 停止 Clang 再追加动态 unwinder。该更正
281+
保留显式静态归档;foreign C++ runtime 分支仍用 libgcc,未提供
282+
静态归档时仍报告运行依赖,toolchain-coupled 分支仍由驱动选择。
283+
资产摘要与符号可见性不变,不以隐藏导出替代运行时闭包验证。
284+
原生完整单测和后续消费门仍须在新提交执行;QEMU 对照只作为根因
285+
与链接机制的聚焦证据。
286+
287+
修正后的 distribution 单测 43/43 通过,新引擎自举通过,使用新引擎
288+
构建的 ELF 单测 22 项通过,另有一项非 Linux 分支按既有条件跳过。
289+
实际 Ninja 链接行包含 `--unwindlib=none`。同一 ARM64 Clang 驱动的
290+
对照显示自动 `-lunwind` 消失,unwind 导出从 31 个降至零,两个
291+
程序在 QEMU 下均运行成功且仅依赖 libc/libm。随后提交仍须完成
292+
原生全量消费及最终 CI,未将聚焦测试计作发布准入。
293+
294+
发布后的原生 ARM64 CN SubOS 验证另有手动工作流,直接下载并
295+
核对公开 CN 的精确客户端与 mcpp 归档,在冷 home 中实际执行
296+
SubOS、GNU 默认构建、打包部署、四个索引成员及 openkal;三个
297+
交叉产物由对应目标 runner 实际运行。sandbox backend 明确记录
298+
为发行版 CI 基础设施,不冒充索引尚未交付的 ARM64 backend 包。
299+
该工作流须待正式发布、镜像与索引就绪后执行。
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/usr/bin/env bash
2+
# Run only the exact public release inside the real native ARM64 SubOS.
3+
set -euo pipefail
4+
phase="${1:?usage: ecosystem-cn.sh release VERSION}"
5+
version="${2:?mcpp version under test required}"
6+
base="${XLINGS_HOME:?explicit isolated XLINGS_HOME required}"
7+
[[ "$(uname -m)" == aarch64 ]] || { echo "native ARM64 required"; exit 1; }
8+
[[ "$phase" == release ]] || { echo "published release only"; exit 1; }
9+
[[ ! -d "${CN_HOST_CHECKOUT:?host checkout path required}" ]] || {
10+
echo 'host checkout must not be visible in the SubOS'; exit 1;
11+
}
12+
xl="${CN_PUBLISHED_XLINGS:?published client path required}"
13+
work="${CN_PROBE_RUN_DIR:-$base/probes/runs/$phase-$version-$(date +%Y%m%dT%H%M%S)}"
14+
[[ "$work" == "$base/probes/runs/"* ]] || exit 1
15+
mkdir -p "$work"
16+
exec > >(tee -a "$work/probe.log") 2>&1
17+
printf 'phase=%s version=%s XLINGS_HOME=%s sandbox_HOME=%s\n' "$phase" "$version" "$base" "$HOME"
18+
cat /proc/self/mountinfo > "$work/subos-mountinfo.txt"
19+
export MCPP_HOME="$work/mcpp-home"
20+
export MCPP_VENDORED_XLINGS="$xl"
21+
export MCPP_E2E_MIRROR=CN MCPP_E2E_LLVM_VERSION=23.1.3 MCPP_E2E_EXPECT_ARCH=aarch64
22+
unset LD_LIBRARY_PATH LD_PRELOAD MCPP_TOOLCHAIN
23+
"$xl" config --mirror CN
24+
"$xl" install "mcpp@$version" -y -u
25+
MCPP="$base/data/xpkgs/xim-x-mcpp/$version/bin/mcpp"
26+
[[ -x "$MCPP" ]] || { echo "mcpp not executable: $MCPP"; exit 1; }
27+
export MCPP
28+
"$MCPP" --version | tee "$work/mcpp-version.txt"
29+
got=$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "$work/mcpp-version.txt" | head -1)
30+
[[ "$got" == "$version" ]] || { echo "unexpected mcpp version $got"; exit 1; }
31+
sha256sum "$MCPP" > "$work/mcpp-binary.sha256"
32+
[[ "$(sha256sum "$MCPP" | cut -d ' ' -f 1)" == "${CN_EXPECTED_BINARY_SHA:?CN archive identity required}" ]] || exit 1
33+
"$MCPP" self config --mirror CN
34+
# No default setter or explicit install may conceal the engine's ARM64 default.
35+
[[ "$(file -b "$MCPP")" == *"ARM aarch64"* ]] || exit 1
36+
case "$(uname -m)" in
37+
x86_64) native=x86_64-linux-gnu ;;
38+
aarch64) native=aarch64-linux-gnu ;;
39+
*) echo 'unsupported native host'; exit 1 ;;
40+
esac
41+
cd "$work"
42+
project="${CN_PROBE_PROJECT:-hello}"
43+
"$MCPP" new "$project"
44+
cd "$work/$project"
45+
"$MCPP" build 2>&1 | tee "$work/native-default-build.log"
46+
grep -q 'Resolved llvm@23.1.3' "$work/native-default-build.log"
47+
grep -Eq 'aarch64-(unknown-)?linux-gnu' "$work/native-default-build.log"
48+
mapfile -t native_bins < <(find target -type f -path "*/bin/$project")
49+
[[ "${#native_bins[@]}" == 1 ]] || exit 1
50+
readelf -hW "${native_bins[0]}" | tee "$work/native-header.txt"
51+
grep -q 'Machine:.*AArch64' "$work/native-header.txt"
52+
readelf -lW "${native_bins[0]}" > "$work/native-program-headers.txt"
53+
python3 - "$MCPP_HOME" "$work/native-program-headers.txt" <<'PYLOADER'
54+
import pathlib,re,sys
55+
home=pathlib.Path(sys.argv[1]).resolve()
56+
text=pathlib.Path(sys.argv[2]).read_text()
57+
m=re.search(r'Requesting program interpreter: ([^\]]+)',text)
58+
assert m,text
59+
loader=pathlib.Path(m[1]).resolve()
60+
loader.relative_to(home/'registry/data/xpkgs/xim-x-glibc')
61+
assert loader.name=='ld-linux-aarch64.so.1',loader
62+
PYLOADER
63+
"$MCPP" run | tee "$work/native-run.log"
64+
grep -q "Hello from $project!" "$work/native-run.log"
65+
"$MCPP" pack --mode self-contained --format dir --message-format json > "$work/pack.json"
66+
bundle=$(python3 - "$work/pack.json" <<'PY'
67+
import json, sys
68+
artifact=json.load(open(sys.argv[1]))['data']['artifacts'][0]
69+
assert artifact['type']=='directory', artifact
70+
print(artifact['path'])
71+
PY
72+
)
73+
cp -a "$bundle" "$work/deployed"
74+
(cd / && env -u LD_LIBRARY_PATH "$work/deployed/$project") | tee "$work/deployed.log"
75+
grep -q "Hello from $project!" "$work/deployed.log"
76+
cd "$work"
77+
git clone --depth 1 --branch "v$version" https://github.com/mcpp-community/mcpp mcpp-source
78+
git -C mcpp-source rev-parse HEAD | tee "$work/mcpp-source-sha.txt"
79+
cd mcpp-source
80+
bash tests/e2e/286_the_openkal_stack_still_builds.sh | tee "$work/openkal-native.log"
81+
! grep -q 'SKIP' "$work/openkal-native.log"
82+
grep -qF 'OK: the openkal stack builds, links statically and runs' "$work/openkal-native.log"
83+
cd "$work"
84+
git clone --depth 1 https://github.com/mcpp-community/mcpp-index index-source
85+
git -C index-source rev-parse HEAD | tee "$work/index-source-sha.txt"
86+
export CN_PROBE_MCPP="$MCPP" CN_PROBE_TARGET="$native" CN_PROBE_WORK="$work"
87+
cat > "$work/llvm-consumer" <<'ADAPTER'
88+
#!/usr/bin/env bash
89+
set -euo pipefail
90+
case "${1:-}" in build|test|run) set -- "$@" --toolchain llvm@23.1.3 --target "$CN_PROBE_TARGET" ;; esac
91+
{ printf 'argv:'; printf ' %q' "$@"; printf '\n'; } >> "$CN_PROBE_WORK/consumer-argv.log"
92+
exec "$CN_PROBE_MCPP" "$@"
93+
ADAPTER
94+
chmod +x "$work/llvm-consumer"
95+
cd "$work/index-source"
96+
MCPP="$work/llvm-consumer" MCPP_VERBOSE=1 MCPP_TIMINGS="$work/members.tsv" \
97+
bash tests/run_members.sh cjson sqlite3 fmtlib.fmt nlohmann.json | tee "$work/members.log"
98+
python3 - "$work/members.tsv" <<'PY'
99+
import pathlib,sys
100+
rows=[line.split('\t') for line in pathlib.Path(sys.argv[1]).read_text().splitlines()]
101+
assert len(rows)==4 and {r[1] for r in rows}=={'cjson','sqlite3','fmtlib.fmt','nlohmann.json'},rows
102+
assert all(r[2]=='ok' for r in rows),rows
103+
PY
104+
# The ecosystem's own same-source example generates its target runtimes from
105+
# the graph. Foreign artifacts are inspected here; target OS execution is a
106+
# separate acceptance gate, never implied by this Linux sandbox.
107+
cd "$work"
108+
git clone --depth 1 --branch "${OPENKAL_SOURCE_REF:-main}" https://github.com/mcpplibs/openkal-llvm-runtime openkal-source
109+
git -C openkal-source rev-parse HEAD | tee "$work/openkal-source-sha.txt"
110+
cp "$work/openkal-source-sha.txt" "$work/source-sha.txt"
111+
cd "$work/openkal-source/examples/same-source"
112+
readobj="$MCPP_HOME/registry/data/xpkgs/xim-x-llvm/23.1.3/bin/llvm-readobj"
113+
[[ -x "$readobj" ]] || { echo 'LLVM readobj unavailable'; exit 1; }
114+
mkdir -p "$work/cross"
115+
for target in x86_64-linux-gnu aarch64-macos x86_64-windows-gnu; do
116+
rm -rf target
117+
"$MCPP" build --target "$target" --toolchain llvm@23.1.3 | tee "$work/cross/$target.build.log"
118+
mapfile -t artifacts < <(find target -type f \( -name openkal-same-source -o -name openkal-same-source.exe \))
119+
[[ "${#artifacts[@]}" == 1 ]] || { echo 'cross artifact missing or ambiguous'; exit 1; }
120+
"$readobj" --file-headers "${artifacts[0]}" > "$work/cross/$target.headers.txt"
121+
case "$target" in
122+
x86_64-linux-gnu) grep -q 'Format: elf64-x86-64' "$work/cross/$target.headers.txt"; grep -q 'Arch: x86_64' "$work/cross/$target.headers.txt" ;;
123+
aarch64-macos) grep -q 'Format: Mach-O' "$work/cross/$target.headers.txt"; grep -q 'Arch: aarch64' "$work/cross/$target.headers.txt" ;;
124+
x86_64-windows-gnu) grep -q 'Format: COFF' "$work/cross/$target.headers.txt"; grep -q 'Arch: x86_64' "$work/cross/$target.headers.txt" ;;
125+
*) echo "unreviewed selected target: $target"; exit 1 ;;
126+
esac
127+
case "$target" in
128+
x86_64-linux-gnu) output=linux ;;
129+
aarch64-macos) output=macos ;;
130+
x86_64-windows-gnu) output=windows.exe ;;
131+
esac
132+
cp "${artifacts[0]}" "$work/cross/$output"
133+
(cd "$work/cross" && sha256sum "$output") >> "$work/cross/SHA256SUMS"
134+
done
135+
echo 'RELEASE BUILD PASS: CN install/default/new/build/run/pack, native openkal, four consumers and three target artifacts.'
136+
cp "$work/openkal-source-sha.txt" "$work/cross/source-sha.txt"
137+
printf '%s\n' "$work" > "$base/probes/last-run.txt"
138+
echo 'Foreign target execution is pending the three target-system jobs.'
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env bash
2+
# Only released bytes from public CN; backend packages are CI infrastructure.
3+
set -euo pipefail
4+
version=${1:?exact published mcpp version}
5+
repo=${2:?checkout holding these tools and the canonical client pin}
6+
backend=${3:-proot}
7+
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || exit 2
8+
[[ "$(uname -m)" == aarch64 ]] || exit 2
9+
[[ "$backend" == proot || "$backend" == bwrap ]] || exit 2
10+
base=${XLINGS_HOME:?cold isolated home required}
11+
[[ ! -e "$base" ]] || { echo 'home must be cold'; exit 1; }
12+
mkdir -p "$base/bootstrap" "$base/probes" "$base/reports"
13+
cd "$base"
14+
# Derive the client version from the repository's existing single pin.
15+
xl_version=$(python3 - "$repo/src/xlings/xlings.cppm" <<'PY'
16+
import pathlib,re,sys
17+
s=pathlib.Path(sys.argv[1]).read_text()
18+
m=re.search(r'kXlingsVersion\s*=\s*"([0-9.]+)"',s)
19+
assert m,s[:100]
20+
print(m[1])
21+
PY
22+
)
23+
gh api "repos/mcpp-community/mcpp/releases/tags/v$version" > "$base/reports/release.json"
24+
python3 - "$base/reports/release.json" "$version" <<'PY'
25+
import json,sys
26+
r=json.load(open(sys.argv[1])); assert not r['draft'] and r['published_at']
27+
assert r['tag_name']=='v'+sys.argv[2]
28+
PY
29+
# Exact tag source is evidence and supplies the existing real e2e test.
30+
git init -q "$base/reports/release-tag"
31+
git -C "$base/reports/release-tag" remote add origin https://github.com/mcpp-community/mcpp
32+
git -C "$base/reports/release-tag" fetch --depth 1 origin "refs/tags/v$version"
33+
git -C "$base/reports/release-tag" rev-parse 'FETCH_HEAD^{commit}' | tee "$base/reports/release-tag-sha.txt"
34+
archive="xlings-$xl_version-linux-aarch64.tar.gz"
35+
expected=$(gh api "repos/xlings-res/xlings/releases/tags/$xl_version" --jq ".assets[] | select(.name==\"$archive\") | .digest")
36+
[[ "$expected" == sha256:* ]] || { echo 'published client digest absent'; exit 1; }
37+
curl -fL "https://gitcode.com/xlings-res/xlings/releases/download/$xl_version/$archive" -o "$base/bootstrap/$archive"
38+
printf '%s %s\n' "${expected#sha256:}" "$base/bootstrap/$archive" | sha256sum -c -
39+
tar -xzf "$base/bootstrap/$archive" -C "$base/bootstrap"
40+
xl="$base/bootstrap/xlings-$xl_version-linux-aarch64/bin/xlings"
41+
"$xl" --version | tee "$base/reports/xlings-version.txt"
42+
"$xl" config --mirror CN
43+
"$xl" update
44+
cp "$base/data/xim-pkgindex/.xlings-index-cache.json" "$base/reports/outer-published-index.json"
45+
# Native backend is provided by distro infrastructure, never labeled an xim
46+
# ARM package. The published bwrap package is x86-only. The client locates the
47+
# system proot directly; bwrap's current locator needs this explicit private
48+
# system-backend directory. Record the symlink and actual distro version.
49+
dpkg-query -W "$backend" | tee "$base/reports/backend-version.txt"
50+
command -v "$backend" | tee "$base/reports/backend-path.txt"
51+
sha256sum "$(command -v "$backend")" > "$base/reports/backend.sha256"
52+
if [[ "$backend" == bwrap ]]; then
53+
mkdir -p "$base/data/xpkgs/xim-x-bwrap/ci-system-backend/bin"
54+
ln -s /usr/bin/bwrap "$base/data/xpkgs/xim-x-bwrap/ci-system-backend/bin/bwrap"
55+
fi
56+
# Independently prove the exact mcpp archive is available through public CN.
57+
mcpp_archive="mcpp-$version-linux-aarch64.tar.gz"
58+
mcpp_digest=$(gh api "repos/xlings-res/mcpp/releases/tags/$version" --jq ".assets[] | select(.name==\"$mcpp_archive\") | .digest")
59+
[[ "$mcpp_digest" == sha256:* ]] || exit 1
60+
curl -fL "https://gitcode.com/xlings-res/mcpp/releases/download/$version/$mcpp_archive" -o "$base/reports/$mcpp_archive"
61+
printf '%s %s\n' "${mcpp_digest#sha256:}" "$base/reports/$mcpp_archive" | sha256sum -c -
62+
mkdir "$base/reports/mcpp-cn-archive"
63+
tar -xzf "$base/reports/$mcpp_archive" -C "$base/reports/mcpp-cn-archive"
64+
mapfile -t archive_binaries < <(find "$base/reports/mcpp-cn-archive" -path '*/bin/mcpp' -type f)
65+
[[ "${#archive_binaries[@]}" == 1 ]] || exit 1
66+
mcpp_binary_sha=$(sha256sum "${archive_binaries[0]}" | cut -d ' ' -f 1)
67+
printf '%s\n' "$mcpp_binary_sha" > "$base/reports/mcpp-cn-binary.sha256"
68+
"$xl" subos new cn-arm64-published
69+
"$xl" subos runtime glibc@2.44.3 cn-arm64-published
70+
cp "$repo/.github/tools/check_published_arm64_cn_ecosystem.sh" "$base/probes/ecosystem.sh"
71+
printf -v command 'CN_HOST_CHECKOUT=%q CN_EXPECTED_BINARY_SHA=%q CN_PUBLISHED_XLINGS=%q bash %q release %q' "$repo" "$mcpp_binary_sha" "$xl" "$base/probes/ecosystem.sh" "$version"
72+
"$xl" subos use cn-arm64-published --sandbox "$backend" --cmd "$command"
73+
work=$(cat "$base/probes/last-run.txt")
74+
[[ "$work" == "$base/probes/runs/"* ]] || exit 1
75+
cmp "$base/reports/release-tag-sha.txt" "$work/mcpp-source-sha.txt"
76+
cp "$base/reports/release-tag-sha.txt" "$work/cross/engine-release-sha.txt"
77+
cp "$work/mcpp-home/registry/data/xim-pkgindex/.xlings-index-cache.json" "$base/reports/inner-published-index.json"
78+
cp "$work/mcpp-home/registry/.xlings.json" "$base/reports/inner-config.json"
79+
cp "$base/.xlings.json" "$base/reports/outer-config.json"
80+
echo "CN_REPORT=$base/reports" >> "$GITHUB_ENV"
81+
echo "CN_CONSUMER_REPORT=$work" >> "$GITHUB_ENV"
82+
echo "CN_CROSS_ARTIFACTS=$work/cross" >> "$GITHUB_ENV"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: released ARM64 CN SubOS ecosystem
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
release_version:
6+
description: Exact published mcpp version (without v)
7+
required: true
8+
type: string
9+
sandbox_backend:
10+
description: Native distro backend used only as CI isolation infrastructure
11+
required: true
12+
type: choice
13+
default: proot
14+
options: [proot, bwrap]
15+
permissions:
16+
contents: read
17+
concurrency:
18+
group: released-arm64-cn-${{ inputs.release_version }}
19+
cancel-in-progress: false
20+
jobs:
21+
consume:
22+
runs-on: ubuntu-24.04-arm
23+
timeout-minutes: 90
24+
env:
25+
RELEASE_VERSION: ${{ inputs.release_version }}
26+
SANDBOX_BACKEND: ${{ inputs.sandbox_backend }}
27+
GH_TOKEN: ${{ github.token }}
28+
XLINGS_NON_INTERACTIVE: '1'
29+
steps:
30+
- uses: actions/checkout@v4
31+
with:
32+
persist-credentials: false
33+
- name: Initialize the cold runtime home
34+
run: echo "XLINGS_HOME=$RUNNER_TEMP/arm64-published-cn" >> "$GITHUB_ENV"
35+
- name: Native distro sandbox infrastructure (not an ARM xim package)
36+
run: |
37+
set -euo pipefail
38+
test "$(uname -m)" = aarch64
39+
sudo apt-get update
40+
sudo apt-get install -y "$SANDBOX_BACKEND"
41+
dpkg-query -W "$SANDBOX_BACKEND"
42+
- name: Exact public CN release in a cold real SubOS
43+
run: bash .github/tools/run_published_arm64_cn.sh "$RELEASE_VERSION" "$GITHUB_WORKSPACE" "$SANDBOX_BACKEND"
44+
- uses: actions/upload-artifact@v4
45+
with:
46+
name: published-cn-arm64-openkal-targets
47+
path: ${{ env.CN_CROSS_ARTIFACTS }}
48+
if-no-files-found: error
49+
- uses: actions/upload-artifact@v4
50+
if: always()
51+
with:
52+
name: published-cn-arm64-consumer-evidence
53+
path: |
54+
${{ env.XLINGS_HOME }}/reports/*.json
55+
${{ env.XLINGS_HOME }}/reports/*.txt
56+
${{ env.XLINGS_HOME }}/reports/*.sha256
57+
${{ env.XLINGS_HOME }}/probes/runs/*/probe.log
58+
${{ env.XLINGS_HOME }}/probes/runs/*/*.txt
59+
${{ env.XLINGS_HOME }}/probes/runs/*/*.sha256
60+
${{ env.XLINGS_HOME }}/probes/runs/*/*.log
61+
${{ env.XLINGS_HOME }}/probes/runs/*/members.tsv
62+
if-no-files-found: warn
63+
target-run:
64+
needs: consume
65+
name: Run ARM-host CN artifacts on ${{ matrix.system }}
66+
strategy:
67+
fail-fast: false
68+
matrix:
69+
include:
70+
- {system: linux, runner: ubuntu-24.04, file: linux}
71+
- {system: macos, runner: macos-14, file: macos}
72+
- {system: windows, runner: windows-2022, file: windows.exe}
73+
runs-on: ${{ matrix.runner }}
74+
timeout-minutes: 10
75+
defaults:
76+
run:
77+
shell: bash
78+
steps:
79+
# No checkout, compiler, mcpp or runtime install: run these exact bytes.
80+
- uses: actions/download-artifact@v4
81+
with:
82+
name: published-cn-arm64-openkal-targets
83+
path: art
84+
- name: Validate artifact identity and real target execution
85+
env:
86+
TARGET_SYSTEM: ${{ matrix.system }}
87+
TARGET_FILE: ${{ matrix.file }}
88+
run: |
89+
set -euo pipefail
90+
cd art
91+
sha256sum -c SHA256SUMS
92+
grep -Eq '^[0-9a-f]{40}$' source-sha.txt
93+
grep -Eq '^[0-9a-f]{40}$' engine-release-sha.txt
94+
chmod +x "$TARGET_FILE"
95+
if [ "$TARGET_SYSTEM" = macos ]; then
96+
codesign -dv "$TARGET_FILE" 2>&1 | grep -q 'adhoc\|Signature'
97+
fi
98+
"./$TARGET_FILE" > output.log 2>&1
99+
cat output.log
100+
grep -q 'sorted: 2 4 7' output.log
101+
grep -q 'caught: 42' output.log
102+
grep -q 'unwound: true' output.log
103+
grep -q 'import std over openkal: ok' output.log
104+
- uses: actions/upload-artifact@v4
105+
if: always()
106+
with:
107+
name: published-cn-arm64-target-run-${{ matrix.system }}
108+
path: art/output.log
109+
if-no-files-found: warn

‎src/build/distribution.cppm‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,10 @@ Mechanism resolve(const MechanismInput& in) {
910910
// because the process already had libstdc++'s.
911911
m.unitFlags += " --unwindlib=libgcc";
912912
} else if (!in.libunwindArchive.empty()) {
913-
m.unitFlags += " " + in.libunwindArchive;
913+
// The archive supplies the unwinder. An automatic -lunwind
914+
// makes lld export its public definitions even when as-needed
915+
// drops the shared library; suppress that second selection.
916+
m.unitFlags += " " + in.libunwindArchive + " --unwindlib=none";
914917
m.unitFlags += detail::hide_static_cxx_runtime(
915918
in.role, in.foreignCxxRuntime, {"libunwind.a"});
916919
} else {

0 commit comments

Comments
 (0)