diff --git a/projects/llvm.org/mingw-w64/package.yml b/projects/llvm.org/mingw-w64/package.yml index f5747d925c..013b37ecd8 100644 --- a/projects/llvm.org/mingw-w64/package.yml +++ b/projects/llvm.org/mingw-w64/package.yml @@ -1,181 +1,128 @@ -# llvm-mingw: LLVM-based mingw-w64 toolchain. -# Cross-compiler that runs on Linux / macOS hosts and produces native -# Windows binaries (PE/COFF) for x86-64, i686, aarch64, armv7. +# llvm.org/mingw-w64 — from-source LLVM mingw-w64 cross-compiler toolchain. # -# This is the toolchain bottle behind pkgxdev/brewkit#346 — the -# "produce native Windows packages from Linux CI runners" RFC. Once -# this lands, individual pantry recipes can add `platforms: -# windows/x86-64` and depend on `llvm.org/mingw-w64` to cross-compile. +# Builds the COMPLETE llvm-mingw toolchain from source via upstream +# mstorsjo/llvm-mingw's own build orchestration (`build-all.sh`): +# - clang + lld + the LLVM binutils-equivalents +# - the mingw-w64 runtime (headers + CRT + winpthreads) +# - the LLVM runtimes for the Windows targets: compiler-rt builtins, +# libunwind, libc++abi, libc++ +# - the per-target driver wrappers (install-wrappers.sh) +# No vendored binaries — everything is compiled here. # -# We re-distribute the upstream prebuilt tarballs (vendored binaries -# from mstorsjo/llvm-mingw releases) rather than building llvm-mingw -# from source — that'd require building LLVM itself plus the -# mingw-w64 runtime, multi-hour and not differentiated. Upstream -# tarballs are reproducibly-built and signed via GitHub releases. +# Why inline (clang and all) rather than composing pantry's llvm.org: the +# Windows-target runtimes must match the exact clang that builds them, and +# pkgx dependency constraints can't "drift" to track that. Building the whole +# toolchain from one source tree makes it internally consistent by +# construction, and versioning to mstorsjo's releases (which pin the matching +# llvm-project) means there's no LLVM-version dance to get wrong. +# +# Compiled on the builder at pkgx's glibc floor, so the host-side driver +# binaries run on old hosts with NO bklibcvenv seal. (Replaces the previous +# approach of vendoring mstorsjo's prebuilt tarball; pantry policy is +# from-source over vendored.) +# +# NOTE: this is a full LLVM build — long, by design. "Build time isn't the +# end of the world to get it right." -# Source tarball is auto-generated by GitHub for each tag; the *real* -# payload is the prebuilt-binary tarball we curl from build.script -# (same `warnings: vendored` pattern as ziglang.org). distributable: - ~ - # url: https://github.com/mstorsjo/llvm-mingw/archive/refs/tags/{{ version.raw }}.tar.gz - # strip-components: 1 + url: https://github.com/mstorsjo/llvm-mingw/archive/refs/tags/{{version.tag}}.tar.gz + strip-components: 1 versions: github: mstorsjo/llvm-mingw -warnings: - - vendored # we redistribute upstream prebuilt binaries - -# Runtime libs the LLVM toolchain itself links (host-side, not the -# Windows target). On a modern host these resolve from the system, but -# once we bundle our own glibc (below) so the toolchain runs on old CI -# hosts, the host's copies are bypassed — so pkgx must supply these via -# its runtime env. These are pkgx-built, so they're guaranteed under -# pkgx's default GLIBC_2.28 symbol floor (and are — libstdc++ 2.26, the -# rest 2.14). It's the *vendored* upstream binaries that break that floor: -# clang/libLLVM need GLIBC_2.34, which is the whole reason this bundle is -# necessary. linux-only: darwin links libSystem/libc++ from the OS. +# Runtime libs the host-side clang/lld link. Built at the 2.28 floor, so these +# pkgx-built deps (all <= 2.28) satisfy it — pkgx supplies them via its runtime +# env, no seal needed. linux-only (darwin links libSystem/libc++ from the OS). dependencies: linux: gnu.org/gcc/libstdcxx: ^14 # libstdc++.so.6 + libgcc_s.so.1 - zlib.net: "*" # libz.so.1 - facebook.com/zstd: "*" # libzstd.so.1 + zlib.net: "*" + facebook.com/zstd: "*" + gnome.org/libxml2: ~2.13 # 2.14 changes the API build: - # We bundle our own ld.so + libc.so.6 (see the seal step) and patch the - # toolchain's PT_INTERP to it. brewkit's fix-patchelf would force-rpath - # *every* ELF under lib/ — including the bundled loader — and a loader - # that parses its own RPATH at startup SIGSEGVs (pkgxdev/brewkit#345, - # reproduced on x86-64 glibc 2.43). So skip it: the upstream binaries - # already carry relative $ORIGIN rpaths, bklibcvenv prepends the bundled - # libc dir as DT_RPATH, and cross-package deps resolve via pkgx's runtime - # env (same approach as the gnu.org/glibc recipe). - skip: fix-patchelf dependencies: - curl.se: "*" - gnu.org/tar: "*" - tukaani.org/xz: "*" + cmake.org: "*" + ninja-build.org: "*" + git-scm.org: "*" # build-llvm.sh / build-mingw-w64.sh clone the sources + python.org: "~3.11" # LLVM's build tooling + zlib.net: "*" + facebook.com/zstd: "*" linux: - # The libc to bundle. ~2.34 is the *oldest* glibc that still satisfies - # the vendored toolchain's symbol versions (clang/libLLVM reference up - # to GLIBC_2.34, above pkgx's default 2.28 floor; older won't load — - # see the test's glibc<2.34 guard). Bundling replaces the host libc - # entirely, so host range is set by glibc's --enable-kernel floor - # (CentOS 7), not this version. - gnu.org/glibc: ~2.34 + gnu.org/gcc: ^14 + # no compiler dep declared on purpose: brewkit's default toolchain is + # llvm, so the host bootstrap compiler is clang (cc/c++ shims → clang). env: - linux/x86-64: - PLATFORM: ubuntu-22.04-x86_64 - linux/aarch64: - PLATFORM: ubuntu-22.04-aarch64 - darwin/x86-64: - PLATFORM: macos-universal - darwin/aarch64: - PLATFORM: macos-universal - linux: - GLIBC_DIR: $(basename "$(echo {{deps.gnu.org/glibc.prefix}}/lib/glibc-*)") - URL: https://github.com/mstorsjo/llvm-mingw/releases/download/{{version.tag}}/llvm-mingw-{{version.tag}}-ucrt - working-directory: ${{prefix}} + # llvm-mingw builds per-target; we ship the x86_64 + aarch64 Windows + # cross-compilers (the two brewkit CI cares about). + TOOLCHAIN_ARCHS: + - x86_64 + - aarch64 + # mstorsjo's orchestrator builds clang/lld, native compiler-rt, installs + # the driver wrappers, builds the mingw-w64 runtime, then the Windows-target + # compiler-rt + libunwind/libc++. Trim lldb + clang-tools-extra to the + # cross-compiler essentials (still a full clang/lld build). script: - - curl -Lf "$URL-${PLATFORM}.tar.xz" | tar Jxpf - --strip-components=1 + # architecture register reservation weirdness + - run: sed -i -f $PROP build-mingw-w64-tools.sh + if: linux/aarch64 + prop: | + 1a export CFLAGS="\${CFLAGS:-} -O2 -ffixed-x18" - # Linux: bundle our own libc + seal the toolchain so it runs on hosts - # whose system glibc is older than the toolchain needs (the CI-runner - # case behind pkgxdev/brewkit#346). darwin uses dyld/libSystem — n/a. - - run: - # The glibc dep installs its loader + libc into lib/glibc-/; - # copy that whole dir in so the bottle ships its own loader. - - cp -a "{{deps.gnu.org/glibc.prefix}}/lib/$GLIBC_DIR" "{{prefix}}/lib/$GLIBC_DIR" - - # Force compiler-rt. After the seal moves clang to libexec/, clang's - # MinGW runtime auto-detection (which keys off its bin/ siblings) - # falls back to libgcc and emits -lgcc/-lgcc_eh, which this toolchain - # doesn't ship. llvm-mingw is always compiler-rt + libunwind, so make - # it explicit — also fixes a latent location-sensitivity bug. - - sed -i 's|FLAGS="$FLAGS -target $TARGET"|FLAGS="$FLAGS -rtlib=compiler-rt -unwindlib=libunwind -target $TARGET"|' bin/clang-target-wrapper.sh - - # Seal: patch each toolchain binary's PT_INTERP to the bundled loader - # via a load-time fixup stub, keeping /proc/self/exe pointing at the - # real binary (so clang -> cc1 works) while staying relocatable. - - bklibcvenv seal "{{prefix}}" "$GLIBC_DIR" - if: linux + - ./build-all.sh "{{prefix}}" + --disable-lldb + --disable-lldb-mi + --disable-clang-tools-extra || (find . -name config.log -exec echo {} \; -exec cat {} \; ; false) test: - # winehq.org/wine is a soft dep — if present, we actually run the - # cross-compiled .exe through wine and verify the output. If not, - # we fall back to a PE magic-byte check. See pkgxdev/brewkit#346 - # discussion: wine in pantry would let us validate the cross-compile - # chain end-to-end without GitHub Windows runners. - - # TODO: enable after #12986 is merged # dependencies: # winehq.org: "*" - env: - WINEDEBUG: -all - WINEDLLOVERRIDES: "mscoree=;mshtml=" - WINEPREFIX: $PWD/.wine + # env: + # WINEDEBUG: -all + # WINEDLLOVERRIDES: "mscoree=;mshtml=" + # WINEPREFIX: $PWD/.wine script: - # Diagnostics first — surface env + filesystem state so the - # darwin self-hosted-runner failure (logs not externally - # accessible) becomes visible to maintainers. - - command -v aarch64-w64-mingw32-clang - - command -v x86_64-w64-mingw32-clang - - # Cross-compile a trivial Windows binary for x86-64 and aarch64. + - x86_64-w64-mingw32-clang --version - run: cp $FIXTURE hello.c fixture: | #include - int main(void) { - printf("Hello from native Windows cross-compile.\n"); - return 0; - } - - x86_64-w64-mingw32-clang -o hello-x86_64.exe hello.c + int main(void) { printf("Hello from native Windows cross-compile.\n"); return 0; } + - x86_64-w64-mingw32-clang -o hello-x86_64.exe hello.c - aarch64-w64-mingw32-clang -o hello-aarch64.exe hello.c - - # Static signature check: PE32+ starts with "MZ" at offset 0. - # head -c 2 reads the raw bytes; "MZ" are printable so the shell - # capture works without any od/tr/sed gymnastics (which had subtle - # BSD-vs-GNU output-format differences and broke on darwin). - test "$(head -c 2 hello-x86_64.exe)" = "MZ" - test "$(head -c 2 hello-aarch64.exe)" = "MZ" - - # Dynamic check: actually run the .exe through wine. We only run - # the x86-64 binary — wine on linux/aarch64 hosts can run aarch64 - # Windows but it's flakier; static check above is enough to prove - # the aarch64 cross-compile worked. - # - # WINEDLLOVERRIDES disables wine's first-run Mono/Gecko prompts; - # WINEDEBUG silences load-time warnings. Both standard for headless. - - # TODO: enable after #12986 is merged - - exit 0 - - if command -v wine64 >/dev/null 2>&1; then - - WINE=wine64 - - else - - WINE=wine - - fi - - - test "$($WINE hello-x86_64.exe)" = "Hello from native Windows cross-compile." - - test "$($WINE hello-aarch64.exe)" = "Hello from native Windows cross-compile." + - if ! command -v wine64 >/dev/null 2>&1; then exit 0; fi + - test "$(wine64 hello-x86_64.exe | tr -d '\r')" = "Hello from native Windows cross-compile." provides: - # x86_64 cross drivers - bin/x86_64-w64-mingw32-clang - bin/x86_64-w64-mingw32-clang++ - bin/x86_64-w64-mingw32-gcc - bin/x86_64-w64-mingw32-g++ - # aarch64 cross drivers + - bin/x86_64-w64-mingw32-ar + - bin/x86_64-w64-mingw32-ranlib + - bin/x86_64-w64-mingw32-strip + - bin/x86_64-w64-mingw32-nm + - bin/x86_64-w64-mingw32-objdump + - bin/x86_64-w64-mingw32-objcopy + - bin/x86_64-w64-mingw32-windres + - bin/x86_64-w64-mingw32-dlltool - bin/aarch64-w64-mingw32-clang - bin/aarch64-w64-mingw32-clang++ - bin/aarch64-w64-mingw32-gcc - bin/aarch64-w64-mingw32-g++ - # i686 cross drivers - - bin/i686-w64-mingw32-clang - - bin/i686-w64-mingw32-clang++ - # PE-aware tooling (analog of binutils for ELF). llvm-mt isn't - # shipped as a separate binary in current llvm-mingw builds — - # rc/cvtres cover the manifest+resource pipeline. - - bin/llvm-rc # resource compiler (rc.exe) - - bin/llvm-cvtres # COFF tooling - - bin/lld-link # MSVC-compat linker (link.exe) + - bin/aarch64-w64-mingw32-ar + - bin/aarch64-w64-mingw32-ranlib + - bin/aarch64-w64-mingw32-strip + - bin/aarch64-w64-mingw32-nm + - bin/aarch64-w64-mingw32-objdump + - bin/aarch64-w64-mingw32-objcopy + - bin/aarch64-w64-mingw32-windres + - bin/aarch64-w64-mingw32-dlltool + # don't want to grab these. + # - bin/clang + # - bin/clang++ + - bin/lld-link + - bin/llvm-rc + - bin/llvm-cvtres