Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions projects/llvm.org/mingw-w64/package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# llvm-mingw: LLVM-based mingw-w64 cross-compiler toolchain.
#
# **Composition recipe** — wraps pantry's `llvm.org` (clang + lld
# + LLVM tools) with `mingw-w64.org` (Windows runtime: headers + CRT
# + winpthreads) to produce a self-contained from-source Windows
# cross-compiler.
#
# Build is trivial — just generates per-target driver scripts that
# shim clang with `--target=<target>` + `--sysroot=<mingw-w64.org>`.
# All real compilation work happens upstream in the two component
# recipes.
#
# Previously this recipe vendored upstream mstorsjo/llvm-mingw's
# prebuilt tarballs. pkgx pantry policy is from-source over
# vendored — so we now compose pantry's own builds. See
# pkgxdev/pantry#13047 (mingw-w64.org runtime) for the runtime side.

distributable:
url: https://github.com/mstorsjo/llvm-mingw/archive/refs/tags/{{ version.raw }}.tar.gz
strip-components: 1

versions:
github: mstorsjo/llvm-mingw

platforms:
- linux/x86-64
- linux/aarch64
- darwin/x86-64
- darwin/aarch64

dependencies:
llvm.org: '*' # clang + clang++ + lld-link + LLVM tools
mingw-w64.org: '*' # Windows runtime (headers + CRT + winpthreads)

build:
dependencies:
gnu.org/coreutils: '*' # install(1), basename(1)
script:
# Generate per-target driver wrappers. Each <target>-<tool>
# script is a thin shim around pantry's llvm.org tools,
# configured for the Windows target via `--target=` and pointed
# at mingw-w64.org's install for headers + libs.
- run: |
set -e
mkdir -p "{{prefix}}/bin"
MINGW="{{deps.mingw-w64.org.prefix}}"
LLVM="{{deps.llvm.org.prefix}}"

for T in x86_64-w64-mingw32 aarch64-w64-mingw32; do
echo "── generating driver wrappers for $T ──"

# Compiler drivers. clang/clang++/cpp are clang frontends;
# gcc/g++ are aliases that autotools / Makefiles often
# hardcode.
for ENTRY in "clang:clang" "clang++:clang++" "cpp:clang" \
"gcc:clang" "g++:clang++"; do
DRIVER="${ENTRY%:*}"
REAL="${ENTRY#*:}"
cat > "{{prefix}}/bin/$T-$DRIVER" <<EOF
#!/bin/sh
exec "$LLVM/bin/$REAL" --target=$T --sysroot="$MINGW/$T" -fuse-ld=lld "\$@"
EOF
chmod 755 "{{prefix}}/bin/$T-$DRIVER"
done

# Binutils-equivalent tools — LLVM ships replacements.
# Per-target aliases for autotools / Makefile compat.
for ENTRY in "ar:llvm-ar" "ranlib:llvm-ranlib" "strip:llvm-strip" \
"nm:llvm-nm" "objdump:llvm-objdump" "objcopy:llvm-objcopy" \
"windres:llvm-windres" "dlltool:llvm-dlltool" \
"ld:lld-link"; do
DRIVER="${ENTRY%:*}"
REAL="${ENTRY#*:}"
cat > "{{prefix}}/bin/$T-$DRIVER" <<EOF
#!/bin/sh
exec "$LLVM/bin/$REAL" "\$@"
EOF
chmod 755 "{{prefix}}/bin/$T-$DRIVER"
done
done

# Top-level convenience symlinks for format-specific LLVM tools.
# Build systems sometimes invoke these without a target prefix.
for TOOL in lld-link llvm-rc llvm-cvtres llvm-windres llvm-dlltool; do
if [ -e "$LLVM/bin/$TOOL" ]; then
ln -sf "$LLVM/bin/$TOOL" "{{prefix}}/bin/$TOOL"
fi
done

test:
# Same end-to-end test as before: cross-compile hello.c for both
# target arches, verify PE/COFF magic, run x86_64 binary via wine.
dependencies:
winehq.org: '*'
env:
WINEDEBUG: -all
WINEDLLOVERRIDES: "mscoree=;mshtml="
WINEPREFIX: $PWD/.wine
CLANG_X86_64: "{{prefix}}/bin/x86_64-w64-mingw32-clang"
CLANG_AARCH64: "{{prefix}}/bin/aarch64-w64-mingw32-clang"
script:
# Diagnostics: confirm wrappers were generated + are executable.
- |
echo "── wrapper diagnostics ──"
ls -la "$CLANG_X86_64" 2>&1 || echo "(missing)"
ls -la "$CLANG_AARCH64" 2>&1 || echo "(missing)"
echo "── wrapper content ──"
cat "$CLANG_X86_64"

# Cross-compile hello.c for both target arches.
- run: cp $FIXTURE hello.c
fixture: |
#include <stdio.h>
int main(void) {
printf("Hello from native Windows cross-compile.\n");
return 0;
}
- $CLANG_X86_64 -o hello-x86_64.exe hello.c
- $CLANG_AARCH64 -o hello-aarch64.exe hello.c

# PE/COFF magic-byte check.
- |
for f in hello-x86_64.exe hello-aarch64.exe; do
case "$(head -c 2 "$f")" in
MZ) echo "$f: PE/COFF DOS header OK" ;;
*) echo "$f: NOT a PE binary"; exit 1 ;;
esac
done

# Runtime check via wine — soft-skip when wine isn't on PATH.
- |
if command -v wine64 >/dev/null 2>&1; then
WINE=wine64
elif command -v wine >/dev/null 2>&1; then
WINE=wine
else
echo "wine not available — compile + magic-check passed; skipping runtime test"
exit 0
fi

- echo "running hello-x86_64.exe under $($WINE --version)"
- out=$($WINE hello-x86_64.exe)
- 'echo "wine stdout: $out"'
- |
case "$out" in
"Hello from native Windows cross-compile.") echo "RUN PASS" ;;
*) echo "RUN FAIL: unexpected output"; exit 1 ;;
esac

provides:
# x86_64 cross drivers
- bin/x86_64-w64-mingw32-clang
- bin/x86_64-w64-mingw32-clang++
- bin/x86_64-w64-mingw32-cpp
- bin/x86_64-w64-mingw32-gcc
- bin/x86_64-w64-mingw32-g++
- bin/x86_64-w64-mingw32-ld
- 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
# aarch64 cross drivers (same set)
- bin/aarch64-w64-mingw32-clang
- bin/aarch64-w64-mingw32-clang++
- bin/aarch64-w64-mingw32-cpp
- bin/aarch64-w64-mingw32-gcc
- bin/aarch64-w64-mingw32-g++
- bin/aarch64-w64-mingw32-ld
- 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
# Top-level PE-aware tooling (symlinks to llvm.org's tools)
- bin/lld-link
- bin/llvm-rc
- bin/llvm-cvtres
Loading