1
0
mirror of https://github.com/skeeto/w64devkit.git synced 2026-10-23 06:08:56 +03:00

Replace variant arguments with build profiles

Replace the loosely coordinated collection of x86 build arguments with
a single VARIANT selector. Define x64, x86, and multilib configuration
stages, then select the requested stage as the common cross-compiler
base. This keeps each supported configuration closed and prevents
callers from combining incompatible architecture settings.

Make x64 the default standalone profile. It targets
x86_64-w64-mingw32, disables GCC multilib support, builds only the
64-bit CRT, and omits the secondary 32-bit libraries and aliases.

Keep the standalone x86 behavior in its own profile. It targets
i686-w64-mingw32, retains the Pentium 4 default, enables only the
32-bit CRT, preserves the Windows XP header default and manifest
behavior, selects the 32-bit BusyBox and NSIS configurations, disables
zstd threading, and raises _WIN32_WINNT only while building CMake.
CMake and its bundled curl require at least Windows Vista APIs, so the
C and C++ flags continue to target Windows 7 without changing the
XP-oriented default of the installed toolchain.

Define multilib as an x86_64 compiler with GCC multilib enabled, both
CRT library sets installed, and the existing i686 forwarding aliases.
Use a dedicated EXTRA_32 setting for the secondary lib32 libraries,
winpthreads builds, thread support object, and aliases instead of
inferring that work from the spelling of a GCC configure option.
Expose independent CRT_LIB32 and CRT_LIB64 settings so each profile
selects exactly the runtime libraries it needs.

Pass the profile's CMake C and C++ flags directly rather than building
an optional argument list through shell positional parameters. Keep all
other profile-specific values next to the selected base stage, including
GCC architecture and manifest flags, BusyBox configuration, zstd
options, and NSIS target architecture.

Simplify multibuild.sh to pass only VARIANT to Docker. Add -m for the
multilib flavor, make -a build all three profiles, and remove the old
argument-file and Dockerfile-patch fallback paths. Update unsigned and
signed CI builds to select x64 or x86 directly, remove the obsolete
variant-x86.args bundle, and document the new build interface.

Verify all three profiles with docker build --check and complete cross
toolchain builds. Smoke-test x64 and x86 compilation, plus both the
64-bit compiler and i686 alias in the multilib profile. Also build the
x64 and x86 CMake targets to exercise both the empty and Windows 7
CMake flag configurations.
This commit is contained in:
Peter0x44
2026-08-29 18:10:31 -05:00
committed by Christopher Wellons
parent c308f151ef
commit 2e424d7941
5 changed files with 80 additions and 89 deletions

View File

@@ -40,6 +40,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
build-args: VARIANT=x64
tags: w64devkit:${{ env.ARCH }}
load: true
cache-from: type=gha,scope=w64devkit-${{ env.ARCH }}
@@ -97,15 +98,6 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Load x86 build args
id: variant
run: |
{
echo 'args<<EOF'
cat src/variant-x86.args
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Generate archive name and version string
id: filename
run: |
@@ -118,7 +110,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
build-args: ${{ steps.variant.outputs.args }}
build-args: VARIANT=x86
tags: w64devkit:${{ env.ARCH }}
load: true
cache-from: type=gha,scope=w64devkit-${{ env.ARCH }}
@@ -166,6 +158,7 @@ jobs:
uses: docker/build-push-action@v7
with:
context: .
build-args: VARIANT=x64
target: signed
tags: w64devkit:x64-signed
load: true
@@ -182,20 +175,11 @@ jobs:
> w64devkit-x64-${{ steps.filename.outputs.version }}.7z.exe
ls -lh w64devkit-x64-${{ steps.filename.outputs.version }}.7z.exe
- name: Load x86 build args
id: variant
run: |
{
echo 'args<<EOF'
cat src/variant-x86.args
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Build signed image (x86)
uses: docker/build-push-action@v7
with:
context: .
build-args: ${{ steps.variant.outputs.args }}
build-args: VARIANT=x86
target: signed
tags: w64devkit:x86-signed
load: true

View File

@@ -1,5 +1,6 @@
ARG VERSION=2.9.1 \
PREFIX=/w64devkit
ARG VARIANT=x64
FROM debian:trixie-slim AS base
ARG PREFIX
@@ -207,30 +208,52 @@ RUN mkdir nsis \
# Build cross-compiler
FROM dl-cross AS cross
FROM dl-cross AS variant-x64
ENV ARCH=x86_64-w64-mingw32 \
ARCH_FLAGS="" \
MULTILIB=--disable-multilib \
CRT_LIB32=--disable-lib32 \
CRT_LIB64=--enable-lib64 \
WINNT_FLAGS="" \
MANIFEST_FLAGS="" \
EXTRA_32=0 \
BUSYBOX_CONFIG=mingw64u_defconfig \
ZSTD_FLAGS="" \
CMAKE_C_FLAGS="" \
CMAKE_CXX_FLAGS="" \
NSIS_ARCH=amd64
# Variant configuration. The defaults produce the x64 kit, and a variant
# is a coherent set of overrides (see src/variant-x86.args). Stages
# before this point are shared between variants.
ARG ARCH=x86_64-w64-mingw32
ARG MULTILIB=--enable-multilib
ARG ARCH_FLAGS=--with-arch-32=pentium4
# Not named "LIB64": mingw-w64-crt's configure tests whether a shell
# variable LIB64 (or LIB32) is set, and ARGs leak into the environment
# of every RUN, which would force the Win64 runtime on regardless of
# the --{enable,disable}-lib64 flag.
ARG CRT_LIB64=--enable-lib64
ARG WINNT_FLAGS=
ARG MANIFEST_FLAGS=
ARG BUSYBOX_CONFIG=mingw64u_defconfig
ARG ZSTD_FLAGS=
ARG CMAKE_WINNT=
ARG NSIS_ARCH=amd64
ENV ARCH=$ARCH \
BUSYBOX_CONFIG=$BUSYBOX_CONFIG \
ZSTD_FLAGS=$ZSTD_FLAGS \
CMAKE_WINNT=$CMAKE_WINNT \
NSIS_ARCH=$NSIS_ARCH
FROM dl-cross AS variant-x86
ENV ARCH=i686-w64-mingw32 \
ARCH_FLAGS=--with-arch=pentium4 \
MULTILIB=--disable-multilib \
CRT_LIB32=--enable-lib32 \
CRT_LIB64=--disable-lib64 \
WINNT_FLAGS=--with-default-win32-winnt=0x0501 \
MANIFEST_FLAGS=--disable-win32-utf8-manifest \
EXTRA_32=0 \
BUSYBOX_CONFIG=mingw32w_defconfig \
ZSTD_FLAGS=HAVE_THREAD=0 \
CMAKE_C_FLAGS="-O2 -D_WIN32_WINNT=0x0601" \
CMAKE_CXX_FLAGS="-O2 -D_WIN32_WINNT=0x0601" \
NSIS_ARCH=x86
FROM dl-cross AS variant-multilib
ENV ARCH=x86_64-w64-mingw32 \
ARCH_FLAGS=--with-arch-32=pentium4 \
MULTILIB=--enable-multilib \
CRT_LIB32=--enable-lib32 \
CRT_LIB64=--enable-lib64 \
WINNT_FLAGS="" \
MANIFEST_FLAGS="" \
EXTRA_32=1 \
BUSYBOX_CONFIG=mingw64u_defconfig \
ZSTD_FLAGS="" \
CMAKE_C_FLAGS="" \
CMAKE_CXX_FLAGS="" \
NSIS_ARCH=amd64
FROM variant-${VARIANT} AS cross
WORKDIR /dl/binutils
COPY src/binutils-*.patch $PREFIX/src/
@@ -309,7 +332,7 @@ RUN mkdir -p $PREFIX/lib \
&& CC=$ARCH-gcc AR=$ARCH-ar DESTDIR=$PREFIX/lib/ \
sh $PREFIX/src/libchkstk.S \
&& ln $PREFIX/lib/libchkstk.a /bootstrap/lib/ \
&& if [ "$MULTILIB" = --enable-multilib ]; then \
&& if [ "$EXTRA_32" = 1 ]; then \
mkdir -p $PREFIX/lib32 /bootstrap/lib32 \
&& CC="$ARCH-gcc -m32" AR=$ARCH-ar DESTDIR=$PREFIX/lib32/ \
sh $PREFIX/src/libmemory.c \
@@ -326,7 +349,7 @@ RUN /dl/mingw/mingw-w64-crt/configure \
--host=$ARCH \
--with-default-msvcrt=msvcrt-os \
--disable-dependency-tracking \
--enable-lib32 \
$CRT_LIB32 \
$CRT_LIB64 \
CFLAGS="-O2" \
LDFLAGS="-s" \
@@ -346,7 +369,7 @@ RUN /dl/mingw/mingw-w64-libraries/winpthreads/configure \
&& make install
WORKDIR /x-winpthreads32
RUN if [ "$MULTILIB" = --enable-multilib ]; then \
RUN if [ "$EXTRA_32" = 1 ]; then \
/dl/mingw/mingw-w64-libraries/winpthreads/configure \
--prefix=/bootstrap \
--libdir=/bootstrap/lib32 \
@@ -447,7 +470,7 @@ RUN /dl/mingw/mingw-w64-crt/configure \
--host=$ARCH \
--with-default-msvcrt=msvcrt-os \
--disable-dependency-tracking \
--enable-lib32 \
$CRT_LIB32 \
$CRT_LIB64 \
CFLAGS="-O2" \
LDFLAGS="-s" \
@@ -459,7 +482,7 @@ COPY src/threads.h $PREFIX/include/
RUN $ARCH-gcc -c -Oz -I$PREFIX/include/ \
-ffunction-sections -Wa,--no-pad-sections $PREFIX/src/threads.c \
&& $ARCH-ar r $PREFIX/lib/libmingwex.a threads.o \
&& if [ "$MULTILIB" = --enable-multilib ]; then \
&& if [ "$EXTRA_32" = 1 ]; then \
$ARCH-gcc -m32 -c -Oz -I$PREFIX/include/ \
-ffunction-sections -Wa,--no-pad-sections \
-o threads32.o $PREFIX/src/threads.c \
@@ -479,7 +502,7 @@ RUN /dl/mingw/mingw-w64-libraries/winpthreads/configure \
&& make install
WORKDIR /winpthreads32
RUN if [ "$MULTILIB" = --enable-multilib ]; then \
RUN if [ "$EXTRA_32" = 1 ]; then \
/dl/mingw/mingw-w64-libraries/winpthreads/configure \
--prefix=$PREFIX \
--libdir=$PREFIX/lib32 \
@@ -559,7 +582,7 @@ RUN $ARCH-gcc -DEXE=gcc.exe -DCMD=cc \
-o $PREFIX/bin/$ARCH-{}.exe $PREFIX/src/alias.c -lkernel32
# Create i686 tool aliases
RUN if [ "$MULTILIB" = --enable-multilib ]; then \
RUN if [ "$EXTRA_32" = 1 ]; then \
printf '%s\n' addr2line ar c++filt gcc-ar gcc-nm gcc-ranlib gcov \
gcov-dump gcov-tool gendef nm objcopy objdump ranlib size strings \
strip uuidgen windmc \
@@ -904,11 +927,9 @@ COPY --from=build-pdcurses /deps/include/curses.h /deps/include/
WORKDIR /cmake
COPY src/cmake-*.patch $PREFIX/src/
RUN cat $PREFIX/src/cmake-*.patch | patch -d/dl/cmake -p1 \
&& if [ -n "$CMAKE_WINNT" ]; then \
set -- -DCMAKE_C_FLAGS="-O2 -D_WIN32_WINNT=$CMAKE_WINNT" \
-DCMAKE_CXX_FLAGS="-O2 -D_WIN32_WINNT=$CMAKE_WINNT" ; \
fi \
&& cmake "$@" -DCMAKE_BUILD_TYPE=Release \
&& cmake -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" \
-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_C_COMPILER=$ARCH-gcc \
-DCMAKE_CXX_COMPILER=$ARCH-g++ \

View File

@@ -31,6 +31,14 @@ Build the image, then run it to produce a self-extracting 7z archive:
docker build -t w64devkit .
docker run --rm w64devkit >w64devkit-x64.exe
The default variant is `x64`. Select a standalone x86 or combined multilib
toolchain with a build argument:
docker build --build-arg VARIANT=x86 -t w64devkit .
docker build --build-arg VARIANT=multilib -t w64devkit .
`multibuild.sh -a` builds all three variants.
This takes about 15 minutes on modern systems. You will need an internet
connection during the first few minutes of the build. **Note:** Do not use
PowerShell because it lacks file redirection.

View File

@@ -8,27 +8,29 @@
# $ ./multibuild.sh -as "$(git describe | tr v -)"
set -e
arch=
variants=
dryrun=
suffix="$(git describe --exact-match 2>/dev/null | tr v - || true)"
usage() {
cat <<EOF
usage: multibuild.sh [-48ahn] [-s SUFFIX]
usage: multibuild.sh [-48ahmn] [-s SUFFIX]
-4 Enable x86 build
-8 Enable x64 build
-a All architectures
-a All variants
-m Enable multilib build
-h Print this help message
-n Dry run, print commands but do nothing
-s SUFFIX Append a version suffix (default: auto from git tag)
EOF
}
while getopts 48ahns: opt; do
while getopts 48ahmns: opt; do
case $opt in
4) arch="$arch x86";;
8) arch="$arch x64";;
a) arch="x64 x86";;
4) variants="$variants x86";;
8) variants="$variants x64";;
a) variants="x64 x86 multilib";;
m) variants="$variants multilib";;
h) usage; exit 0;;
n) dryrun=echo;;
s) suffix="$OPTARG";;
@@ -43,29 +45,15 @@ if [ $# -gt 0 ]; then
exit 1
fi
: ${arch:=x64}
tmp=
: ${variants:=x64}
target="tmp-w64-$$"
cleanup() {
rm -rf -- "$tmp"
$dryrun docker rmi --no-prune $target 2>/dev/null || true
}
trap cleanup EXIT
for variant in $arch; do
if [ -e "src/variant-$variant.args" ]; then
$dryrun docker build \
$(sed 's/^/--build-arg /' "src/variant-$variant.args") \
-t $target .
elif [ -e "src/variant-$variant.patch" ]; then
tmp=$(mktemp -d)
$dryrun cp Dockerfile "$tmp/"
$dryrun patch "$tmp/Dockerfile" "src/variant-$variant.patch"
$dryrun docker build -f "$tmp/Dockerfile" -t $target .
rm -rf -- "$tmp"
else
$dryrun docker build -t $target .
fi
for variant in $variants; do
$dryrun docker build --build-arg VARIANT=$variant -t $target .
out="w64devkit-$variant$suffix.7z.exe"
if [ -n "$dryrun" ]; then
$dryrun docker run --rm $target ">$out"

View File

@@ -1,10 +0,0 @@
ARCH=i686-w64-mingw32
MULTILIB=--disable-multilib
ARCH_FLAGS=--with-arch=pentium4
CRT_LIB64=--disable-lib64
WINNT_FLAGS=--with-default-win32-winnt=0x0501
MANIFEST_FLAGS=--disable-win32-utf8-manifest
BUSYBOX_CONFIG=mingw32w_defconfig
ZSTD_FLAGS=HAVE_THREAD=0
CMAKE_WINNT=0x0601
NSIS_ARCH=x86