One-word bugfix: re-enable custom ERTS compilation by adding comptime - #237
Open
JamesLavin wants to merge 1 commit into
Open
One-word bugfix: re-enable custom ERTS compilation by adding comptime#237JamesLavin wants to merge 1 commit into
comptime#237JamesLavin wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I have tested this one-word fix on my project and it fixed the regression that blocked me from upgrading from burrito 1.5.0 to 1.6.0.
The following explanation was generated by Claude, and I am not a Zig developer.
--James
Burrito 1.6.0 blocks builds that use a non‑precompiled (
custom_erts) ERTS on LinuxTL;DR — In Burrito 1.6.0, the Linux wrapper unconditionally compiles
@embedFile("musl-runtime.so"), but themusl-runtime.sofile is only produced by theFetchMuslstep when the target uses a
{:precompiled, _}ERTS. Any Linux target that supplies its own ERTS(
custom_erts:→{:local, _}/{:local_unpacked, _}) therefore fails to compile the wrapper:This is a regression from 1.5.0, which builds the same configuration cleanly. The cause is a
lost
comptimequalifier on the guard around the@embedFile. This document is intended as a reportfor the Burrito maintainers.
Environment
os: :linux, cpu: :x86_64(also:aarch64)custom_erts:pointing at a local glibc ERTS — not a Burrito‑downloadedprecompiled (musl) ERTS. We do this deliberately because our NIFs (
vix,exqlite,bcrypt_elixir) are compiled against glibc on the build host and bundled with their glibcdependencies; a musl ERTS would be ABI‑incompatible with them.
Representative target definition:
Root cause
Two pieces interact.
1.
FetchMuslonly runs for{:precompiled, _}ERTSlib/steps/fetch/fetch_musl.exmatches only the precompiled‑ERTS case and no‑ops otherwise:So for a
custom_erts(local) ERTS:src/musl-runtime.sois never written, and__BURRITO_MUSL_RUNTIME_PATHis never set, sobuild.zigfalls back to the empty default:build_options.MUSL_RUNTIME_PATH == ""(a comptime‑known constant).2. The wrapper embeds the file behind a runtime guard (regression)
@embedFileis a compile‑time builtin: Zig evaluates it whenever the enclosing code is semanticallyanalyzed. A runtime
ifdoes not prevent that analysis — only acomptime‑false conditionelides the block.
1.5.0 —
src/wrapper.zig:203(works): the guard iscomptime, so whenMUSL_RUNTIME_PATH == ""the whole block — including the@embedFile— is eliminated at compiletime:
1.6.0 — same function, guard lost its
comptime(fails): the guard is now a runtime condition,so Zig analyzes the body regardless and evaluates the
@embedFile(thewrapper.zig:241in theerror above), which fails because the file is absent:
The call site is compiled for every Linux build:
(Line numbers cited for 1.6.0 are approximate — take the failing
@embedFileline from your ownbuild output; the essential point is that the enclosing
ifis a runtime condition, whereas in1.5.0 it was
comptime.)Because
IS_LINUXis true,maybe_install_musl_runtimeis analyzed, and its now‑runtimeifnolonger shields the
@embedFile. Result: any Linux target whose ERTS is not{:precompiled, _}fails to compile the wrapper.
Minimal reproduction
custom_erts: :code.root_dir() |> to_string()(soerts_sourceresolves to{:local, _}/{:local_unpacked, _}, not{:precompiled, _}).MIX_ENV=prod mix releasewith Burrito 1.6.0 + Zig 0.16.0.Expected: a wrapped executable. Actual:
error: unable to open 'musl-runtime.so': FileNotFound.The same project on Burrito 1.5.0 + Zig 0.15.2 builds successfully.
Suggested fix
Restore the compile‑time elision so the
musl-runtime.soembed is only compiled when a musl runtimepath was actually provided.
build_options.MUSL_RUNTIME_PATHis a comptime‑known constant, so aone‑word change suffices:
Alternatives that would also work:
FetchMuslprovidemusl-runtime.sofor all Linux targets (but embedding a musl runtime intoa glibc/custom‑ERTS wrapper is unnecessary), or
@embedFileitself in anif (comptime ...)block so it is never analyzed unless needed.The
comptime‑guard approach matches 1.5.0's behavior and keepscustom_ertsLinux builds working.Workaround (what we did)
Pin to the last Zig‑0.15 release, which still has the comptime guard:
We would prefer to move to 1.6.0 / Zig 0.16.0 once the wrapper only embeds
musl-runtime.sowhen amusl runtime is actually fetched.
My project ships desktop builds via Burrito for macOS/Windows/Linux (deb + rpm, x86_64 + aarch64),
each built on native‑arch runners with host‑compiled glibc NIFs and
skip_nifs: true.