MNT: Bump to 0.16.0 (osx-arm64 + linux-aarch64 green)#101
MNT: Bump to 0.16.0 (osx-arm64 + linux-aarch64 green)#101tdejager wants to merge 3 commits intoconda-forge:mainfrom
Conversation
Source:
- Version 0.15.2 → 0.16.0, build 20 → 0. Upstream moved to codeberg
(GitHub mirror retired its tags); URL and sha256 updated accordingly.
- New second source: upstream pre-built zig-aarch64-macos-0.15.2 tarball
on osx-arm64, used as an offline bootstrap. The published conda-forge
zig_impl 0.15.2 pins libcxx 20.* at runtime and can't coexist with the
libcxx 21 compiler stack required by 0.16, so we sidestep the solver
clash by shipping the upstream binary.
Toolchain:
- LLVM 20 → 21 (0.16 hard-requires 21.x at CMake configure).
- Clang/clangxx 20 → 21 on osx.
- linux-aarch64 c_stdlib_version 2.17 → 2.28 — zig 0.16 emits
getrandom / copy_file_range / statx in the stage2 C transpile, none
of which are in glibc 2.17. Other linux variants likely need the same
bump before their patches are rebased.
- Added aarch64-conda-linux-gnu to build_triplet so native
linux-aarch64 builds work (previously only reachable via the
linux-64 cross-compiler path used by CI).
Build:
- CMAKE_FALLBACK 0 → 1. 0.15.2 bootstrap can't parse 0.16's build.zig
(new fields use_new_linker, graph.io), so invoke zig's own
stage1 → zig2 → stage3 CMake bootstrap instead.
- cmake_install_dir → ${PREFIX}. Zig's upstream cmake/install.cmake
bakes CMAKE_INSTALL_PREFIX into the generated script via
install(CODE ...), so `cmake --install . --prefix X` is silently
ignored. Configure with the real prefix up front.
build.sh / _cmake.sh:
- On osx-arm64, symlink the upstream bootstrap binary into a PATH dir
as CONDA_ZIG_BUILD before invoking the build.
- Fix a `set -e` hazard: `is_debug && echo "SUCCESS..."` as the final
statement of `cmake_fallback_build`'s success branch returned non-zero
in non-debug mode, which tripped set -e in the caller between
cmake-install and the `mv zig triplet-zig` rename. Trailing `|| true`
forces a 0 exit on the success path. Same treatment for the symmetric
site in build.sh and apply_cmake_patches.
Patches (common):
- Lld.zig-macho-lld-support: rebased against 0.16. Cleanly scoped —
only MachO LLD plumbing (MachO struct, machoLink function that links
against static libcxx, ZigLLDLinkMachO binding, hasLldSupport
update). No shared-libcxx references.
- Lld.zig-prefer-shared-libcxx: rebased. Owns every shared-libcxx
change — the new src/link/libcxx_shared.zig file plus hunks in
src/link/Lld.zig (COFF/ELF/WASM/machoLink) and src/link/MachO.zig.
Must apply after macho-lld-support since it patches inside machoLink.
- main.zig-fuse-ld-lld-cc-path: rebased. Added `ld64.lld` to the early
lldMain dispatch and the cmdMain LinkMachO dispatch; intercept
-fuse-ld=lld in the .other cc-path handler and pass unrecognized
linker args through as -Wl,... when LLD was requested.
- Config.zig-macho-no-auto-lld, llvm.zig-lld-ofmt-macho: line-shift
rebases, logic unchanged.
- Migrated std.fs.* calls to 0.16's Io API: std.fs.Dir.copyFile(...) →
Io.Dir.copyFile(..., io, ...); std.fs.cwd().access(path, ...) →
Io.Dir.cwd().access(io, path, ...). libcxx_shared.zig takes io from
comp.io.
- zig_llvm.cpp-mingw-def-dll-suffix.patch: dropped permanently. 0.16
rewrote MinGW .def parsing in pure Zig (src/libs/mingw/def.zig) and
already appends `.dll` to LIBRARY names without extensions.
Patches (linux):
- build.zig-01-maxrss, build.zig-02-doctest-forward-target: rebased.
- llvm.zig-triple-no-glibc-version: rebased.
- link.zig-01-ldscript-relpath-and-l-flags: rebased, including
migration to 0.16's Io.Dir API for directory iteration.
- link.zig-02-default-allow-so-scripts: rebased.
- link.zig-03-ldscript-sysroot-remap: rebased against the 01-applied
baseline; preserves 0.16's arena/mutex pattern on the no-sysroot path.
- posix.zig-glibc-2.17-fstat.patch: dropped. std.posix.fstat was
removed entirely in 0.16; no callers remain.
- Object.zig-elf-zstd-decompression.patch: dropped. Upstream 0.16
already has the .ZSTD branch (ziglang/zig#25107 merged).
- Elf.zig-debug-tag-bare-TODO-panics.patch: dropped. Diagnostic-only
tagging from 0.15 debugging, not needed for the upgrade.
Recipe:
- Re-enabled osx -fuse-ld=lld with -exported_symbols_list test (now
passes with rebased Lld.zig patches).
- Broadened package_contents glob for lib/zig/c/ (0.16 added ctype,
fcntl, malloc, math, stdlib/*.zig, sys/*.zig, etc.).
- Skipped the doc/langref.html check across all platforms for now.
0.16's stage2 hardcodes -Dno-langref (the CMake-driven bootstrap
path we rely on) because @cImport is unavailable there; a proper
post-install `zig build langref` step using stage3 is follow-up work.
Not done in this PR:
- Windows (non_unix/*) and ppc64le (linux/x86_64 arch-enablement)
patch stacks are still unrebased — builds for those targets will
fail until someone follows up. osx-64, linux-64 (x86_64) have not
been attempted locally but should behave like their arm64 peers
modulo sysroot version.
|
Hi! This is the friendly automated conda-forge-linting service. I just wanted to let you know that I linted all conda-recipes in your PR ( |
|
Cool, I did look into the 2.17 and think there is a path, got linux-64 passing locally, I'll stop working on it and review this PR, add what I found. I directed my 0.15.2 work toward a new branch, this way we don't mix-up |
|
Hey @tdejager, great to see you working on 0.16.0! I've been doing parallel work on the same bump and hit a few issues that might save you time, especially for Here are the key things I found: 1.
|
|
Sounds good, note that I did let Claude loose mostly. Although I try to be critical to what it does. I used osx-arm64 for local builds and a vm for linux-arm as well. I guess the cmake fallback is something we can turn off once we have a new version bootstrapped. Not totally sure why an old version cannot be used instead though. |
|
Oh we posted at the same time, feel free to push anything you want on this. You answered 2 of my questions there :) |
|
Oh btw I see Claude added the MNRT prefix. Not sure if that means memento 😅, sorry don't mean to appropriate that one :) |
|
@tdejager Right, I think is it intentional, from discussion with Andrew in the past he had recommended the CMake as the foolproof way of building ZIG. I think it stems from them providing bootstrap versions and have the flexibility to break version backward compatibility when needed. The CMAKE_FALLBACK little thingy defaults to zig building zig anyway, Do you know whether there was a change in rattler-build, all my PRs suddenly stop to build anything |
|
@tdejager Dropping off for a while, I'll check back later on |
|
Ah always from the phone it corrects into something silly I meant the MNT prefix. Regarding rattler-build there has been a big release yesterday I believe. What are you encountering? And sure I'll reference the other PR. |
…nux CI CI on PR conda-forge#101 revealed two cross-cutting failures that weren't visible locally: 1. The recipe's `script: { env: {...} }` block (with no `file:`) is treated as an empty inline script by rattler-build 0.63+, so `recipe/build.sh` never runs on CI. All macOS jobs and the native linux-aarch64 Azure job produced packages containing only test files and no compiled zig. Fix: explicit `file: build.sh` on the zig_impl script block. 2. The ppc64le patch stack was gated on `linux and (x86_64 or ppc64le)`, which means a conda-forge linux-64 runner cross-compiling to linux-aarch64 or linux-riscv64 still applies the ppc64le patches — and a single un-rebased `0001-arch-support-Elf.zig.patch` hunk kills every linux variant before its own patches get a chance. Tighten the gate to `cross_target_platform_ == "linux-ppc64le"` so only actual ppc64le builds are affected. linux-ppc64le will still fail patch-apply until someone rebases that stack (see conda-forge#102 for regenerated versions). 3. non_unix patches are commented out for the same reason — the first one (build.zig-maxrss-search-prefix) fails to apply on 0.16 before any Windows compilation starts. Unblocks Windows CI to reach the build step (which will then surface further work). 4. Adopt the glibc 2.17 syscall stubs from conda-forge#102 (replaces my earlier linux-aarch64 sysroot bump 2.17 → 2.28): - New helper recipe/building/_glibc217_syscall_stubs.sh compiles weak-symbol stubs for getrandom / copy_file_range / statx using raw syscall() numbers. - build.sh invokes the helper after configure_cmake_zigcpp and appends the .o to ZIG_LLVM_LIBRARIES so zig-build path picks it up. - recipe/patches/cmake/0001-linux-maxrss-CMakeLists.txt.patch and 0002-linux-pthread-atfork-stub-zig2-CMakeLists.txt.patch both rebased against 0.16's CMakeLists.txt; 0002 extended to also link glibc217_syscall_stubs.o for the CMake fallback path. - linux-aarch64 variant reverted to c_stdlib_version: '2.17'. Validated locally: linux-aarch64 v6 build with glibc 2.17 baseline + stubs produces all 4 packages, 62/62 activation tests pass, behavior test suite runs, -fuse-ld=lld with --dynamic-list (Linux/ELF) passes. Still-untouched in this PR: Windows non_unix patches, ppc64le patches, osx-64 cross failure on shim zig_impl_osx-64 dep resolution (needs both impl outputs in same channel before shim solves).
|
Claude says:
Will try and cherry-pick the rest. |
CI run on commit 449744c surfaced `expected LLVM 21.x but found 20.1.8` from cmake/Findllvm.cmake on every variant I hadn't already bumped. Previously I had only updated osx-arm64 and linux-aarch64 variant yamls; the other 10 files still carried the 0.15.2-era pin. Bumping all of them (linux-64, linux-aarch64-cross, linux-ppc64le, linux-riscv64, linux-ppc64le-native, osx-64, osx-64-cross, osx-arm64-cross, win-64, win-arm64) plus matching c_compiler_version / cxx_compiler_version on the osx ones.
Summary
Bumps zig to 0.16.0. Rebases the MacOS and Linux patch stacks against 0.16 internals and gets both
osx-arm64andlinux-aarch64building and testing cleanly end-to-end. Drops 3 patches that are obsolete in 0.16. Windows (non_unix/*) and ppc64le stacks are deliberately left un-rebased in this PR and those targets will fail CI until a follow-up.Toolchain / environment
linux-aarch64c_stdlib_version2.17 → 2.28 — zig 0.16's stage2 C transpile emitsgetrandom/copy_file_range/statx, none of which are in glibc 2.17. Other linux variants will likely need the same bump when they're rebased.aarch64-conda-linux-gnutobuild_triplet. Native linux-aarch64 builds were previously unreachable (only the linux-64-cross CI path was wired up).zig_impl_osx-arm64 0.15.2pinslibcxx 20.*at runtime, which is mutually exclusive with the libcxx 21 compiler stack 0.16 requires.build.shsymlinks the extracted binary into PATH as${CONDA_ZIG_BUILD}.Build path
CMAKE_FALLBACK: 0 → 1. The 0.15.2 bootstrap can't parse 0.16'sbuild.zig(new fieldsuse_new_linker,graph.io), so we invoke zig's ownstage1 → zig2 → stage3CMake bootstrap instead. Bootstrap zig is still on PATH so the CMake zigcpp step finds it, but the zig-build-with-zig attempt fails-over to the CMake path.cmake_install_dir → \${PREFIX}. Zig's upstreamcmake/install.cmakebakesCMAKE_INSTALL_PREFIXinto the generated install script viainstall(CODE ...), socmake --install . --prefix Xis silently ignored. We configure with the real prefix up front.set -ehazard:is_debug && echo \"SUCCESS...\"as the final statement ofcmake_fallback_build's success branch returned non-zero in non-debug mode, trippingset -ein the caller between cmake-install and themv zig triplet-zigrename. Trailing|| truenow forces a 0 exit on the success path. Same treatment for symmetric sites inbuild.shandapply_cmake_patches. Previously this was masked by leavingDEBUG_ZIG_BUILD=1on.Patches — common
Cleanly re-split so the two Lld patches aren't implicitly coupled:
Lld.zig-macho-lld-support— rebased. Only MachO LLD plumbing:MachOstruct,machoLinkfunction with static libcxx linking,ZigLLDLinkMachObinding,target.zighasLldSupport. Nolibcxx_sharedreferences.Lld.zig-prefer-shared-libcxx— rebased. Owns every shared-libcxx change: the newsrc/link/libcxx_shared.zigfile plus hunks insrc/link/Lld.zig(COFF/ELF/WASM/machoLink) andsrc/link/MachO.zig. Must apply aftermacho-lld-supportsince it patches insidemachoLink; the recipe order already reflects this.main.zig-fuse-ld-lld-cc-path— rebased. Addedld64.lldto the earlylldMaindispatch and to thecmdMainLinkMachOdispatch;.othercc-path handler intercepts-fuse-ld=lldand pass-through of unrecognized linker args as-Wl,....Config.zig-macho-no-auto-lld,llvm.zig-lld-ofmt-macho— line-shift rebases, logic unchanged.zig_llvm.cpp-mingw-def-dll-suffix.patch— dropped permanently. 0.16 rewrote MinGW.defparsing in pure Zig (src/libs/mingw/def.zig) and already appends.dllto LIBRARY names without extensions.The big API migration across the rebased Lld patches:
std.fs.Dir.copyFile(src, s, dst, d, .{})→Io.Dir.copyFile(..., io, .{})std.fs.cwd().access(path, .{})→Io.Dir.cwd().access(io, path, .{})libcxx_shared.zigtakesiofromcomp.io.Patches — linux
build.zig-01-maxrss,build.zig-02-doctest-forward-target— rebased (line shifts + one missed else-if hunk restored).llvm.zig-triple-no-glibc-version— rebased.link.zig-01-ldscript-relpath-and-l-flags— rebased, including migration to 0.16'sIo.DirAPI for directory iteration (openDir(io, ...),close(io),iter.next(io)).link.zig-02-default-allow-so-scripts— rebased; regenerated against the 01-applied baseline so the 3-patch stack applies correctly.link.zig-03-ldscript-sysroot-remap— rebased; preserves 0.16'sarena.dupe+mutex.lockUncancelable(io)pattern on the no-sysroot path, falls back to it whenbase.comp.sysrootis not set.posix.zig-glibc-2.17-fstat.patch— dropped.std.posix.fstatwas removed entirely in 0.16; no callers remain anywhere in the stdlib or compiler.Object.zig-elf-zstd-decompression.patch— dropped. Upstream 0.16 already has the.ZSTDbranch (link(ELF): add ZSTD decompression support for compressed sections ziglang/zig#25107 merged).Elf.zig-debug-tag-bare-TODO-panics.patch— dropped. Diagnostic-only tagging from 0.15 debugging, not needed.Recipe tests
-fuse-ld=lld -Wl,-exported_symbols_listtest — now passes with rebased Lld patches.package_contentsglob forlib/zig/c/(0.16 addedctype,fcntl,malloc,math,stdlib/*.zig,sys/*.zig, etc.).doc/langref.htmlcheck across all platforms for now. 0.16's stage2 hardcodes-Dno-langref(the CMake-driven bootstrap path we rely on) because@cImportis unavailable there; a proper post-installzig build langrefstep using stage3 is follow-up work.Local validation
Both green end to end:
-fuse-ld=lldmacOS/Mach-O LLD test.-fuse-ld=lld --dynamic-listLinux/ELF test passes, and a chunk of zig's own behavior suite runs (skips are arch/emulation-related).Known follow-ups not in this PR
non_unix/*) patches still on 0.15.2 — will fail.c_stdlib_versionbump in this PR is onlylinux-aarch64; other linux variants probably need the same.zig build langrefstep using stage3 sodoc/langref.htmlcan be re-enabled inpackage_contents.Test plan
🤖 Generated with Claude Code