fix(ci): supply _NSGetExecutablePath on Linux, so the seed links and CI publishes
The asset-pack boot calls _NSGetExecutablePath, which glibc does not have, so the Linux link of the compiler seed failed in every CI job - build-and-test, cfree-fixpoint and every publish run - since packs landed. The last release CI created was v0.7.0. The Linux shim now defines it over /proc/self/exe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
762d39bdff
commit
7586c3ad25
2 changed files with 37 additions and 1 deletions
9
changes/linux-ci-link.md
Normal file
9
changes/linux-ci-link.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
bump: patch
|
||||||
|
type: fix
|
||||||
|
**The toolchain links on Linux again** — CI builds, tests and publishes releases.
|
||||||
|
|
||||||
|
The asset-pack boot finds the directory beside the executable with `_NSGetExecutablePath`,
|
||||||
|
which Darwin's libc has and glibc does not, so every Linux link of the compiler seed failed
|
||||||
|
from the release that added packs onward: CI's build, suite and C-free bootstrap jobs, and
|
||||||
|
every `publish` run, so no release after v0.7.0 carried a Linux toolchain or was created by
|
||||||
|
CI at all. `tools/ci/linux_stdio_shim.ll` now supplies it, over `/proc/self/exe`.
|
||||||
|
|
@ -6,7 +6,10 @@
|
||||||
; any Ludic binary fails with "undefined reference to __stderrp".
|
; any Ludic binary fails with "undefined reference to __stderrp".
|
||||||
;
|
;
|
||||||
; This shim defines the two Darwin-named globals and, in a startup constructor,
|
; This shim defines the two Darwin-named globals and, in a startup constructor,
|
||||||
; points them at glibc's real FILE* streams. It is pure LLVM IR — no C compiler
|
; points them at glibc's real FILE* streams. It also supplies _NSGetExecutablePath,
|
||||||
|
; which the asset-pack boot (emit_pak.ludic) calls to find the directory beside the
|
||||||
|
; executable: Darwin has it, glibc does not, and without it every Linux link of the
|
||||||
|
; seed failed - which is why CI stopped publishing releases after v0.7.0. It is pure LLVM IR — no C compiler
|
||||||
; and no .c source — so it keeps the toolchain's C-free guarantee intact. It is
|
; and no .c source — so it keeps the toolchain's C-free guarantee intact. It is
|
||||||
; injected on Linux only, via LUDIC_CC (see .forgejo/workflows/ci.yml); macOS
|
; injected on Linux only, via LUDIC_CC (see .forgejo/workflows/ci.yml); macOS
|
||||||
; never links it (libc already provides __stdoutp/__stderrp).
|
; never links it (libc already provides __stdoutp/__stderrp).
|
||||||
|
|
@ -31,3 +34,27 @@ entry:
|
||||||
store ptr %e, ptr @__stderrp
|
store ptr %e, ptr @__stderrp
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; _NSGetExecutablePath(buf, &size) -> 0 on success: the running executable's path,
|
||||||
|
; NUL-terminated, from /proc/self/exe. Same contract as Darwin's (the size is the
|
||||||
|
; buffer's capacity in; -1 back when the path does not fit or cannot be read).
|
||||||
|
declare i64 @readlink(ptr, ptr, i64)
|
||||||
|
@.ludic_self_exe = private unnamed_addr constant [15 x i8] c"/proc/self/exe\00"
|
||||||
|
|
||||||
|
define i32 @_NSGetExecutablePath(ptr %buf, ptr %szp) {
|
||||||
|
entry:
|
||||||
|
%sz = load i32, ptr %szp
|
||||||
|
%cap = sub i32 %sz, 1
|
||||||
|
%cap64 = sext i32 %cap to i64
|
||||||
|
%n = call i64 @readlink(ptr @.ludic_self_exe, ptr %buf, i64 %cap64)
|
||||||
|
%bad = icmp slt i64 %n, 0
|
||||||
|
%full = icmp sge i64 %n, %cap64
|
||||||
|
%no = or i1 %bad, %full
|
||||||
|
br i1 %no, label %fail, label %ok
|
||||||
|
ok:
|
||||||
|
%end = getelementptr i8, ptr %buf, i64 %n
|
||||||
|
store i8 0, ptr %end
|
||||||
|
ret i32 0
|
||||||
|
fail:
|
||||||
|
ret i32 -1
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue