diff --git a/AGENTS.md b/AGENTS.md index 7995850e351..d7b017f723e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,11 +33,28 @@ Do not use `bash -l` or `bash --login`; login shells may hang in Git for Windows SDK environments. Use `makepkg -s` to install missing dependencies automatically. -Use `--nocheck` to skip the test suite, `--cleanbuild` to force a -clean rebuild, and `--skippgpcheck` to skip GPG signature -verification. Use `makepkg -o` (extract and prepare only) to -validate that patches apply cleanly without waiting for a full -compile. +Use `--nocheck` to skip the test suite and `--skippgpcheck` to skip +GPG signature verification. Never use `--cleanbuild` when `src/` +contains a retained playground or other working source tree: it +deletes the entire directory. Use `makepkg -o` (extract and prepare +only) to validate that patches apply cleanly without waiting for a +full compile. + +### Test-building the MSYS2 runtime + +For an already-prepared `msys2-runtime/src/msys2-runtime` source tree, +test-build the runtime DLL without packaging it: + + cd msys2-runtime + ./test-build-msys2-runtime.sh -j15 + +The helper resets inherited MINGW environment variables, selects the +MSYS toolchain, and builds `new-msys-2.0.dll` in a private incremental +build tree under `src/`. Complete logs are written below that build +tree. Use `--reconfigure` after build-system changes, `--full` to +continue with the aggregate build, and `--source-dir` when testing an +external or linked source tree. The helper never cleans or removes an +existing build tree. When a package uses git sources, `updpkgsums` must be run with `core.autoCRLF=false` in the Git configuration. Otherwise the diff --git a/msys2-runtime/test-build-msys2-runtime.sh b/msys2-runtime/test-build-msys2-runtime.sh new file mode 100755 index 00000000000..8c4bb87d368 --- /dev/null +++ b/msys2-runtime/test-build-msys2-runtime.sh @@ -0,0 +1,248 @@ +#!/usr/bin/env bash + +set -euo pipefail + +usage () { + cat <<-EOF + usage: $0 [--source-dir ] [--build-dir ] [--full] + [--reconfigure] [-j ] + + Configure and test-build the MSYS2 runtime without deleting any existing + build tree. The default source is src/msys2-runtime next to this script. + The default target is new-msys-2.0.dll. --full continues with the + complete build after the runtime DLL succeeds. --reconfigure forces + autogen and configure even when the cached configuration matches. + EOF +} + +summarize_output () { + sed -n \ + -e '/warning:/p' \ + -e '/error:/p' \ + -e '/\*\*\* \[/p' \ + -e '/new-msys-2\.0\.dll/p' +} + +jobs=${JOBS:-$(nproc)} +source_dir= +build_dir= +full_build= +reconfigure= + +while test $# -gt 0 +do + case "$1" in + --source-dir) + test $# -ge 2 || { + echo "error: --source-dir requires a value" >&2 + exit 2 + } + source_dir=$2 + shift 2 + ;; + --build-dir) + test $# -ge 2 || { + echo "error: --build-dir requires a value" >&2 + exit 2 + } + build_dir=$2 + shift 2 + ;; + --full) + full_build=t + shift + ;; + --reconfigure) + reconfigure=t + shift + ;; + -j|--jobs) + test $# -ge 2 || { + echo "error: $1 requires a value" >&2 + exit 2 + } + jobs=$2 + shift 2 + ;; + -j[0-9]*) + jobs=${1#-j} + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "error: unknown option: $1" >&2 + usage >&2 + exit 2 + ;; + esac +done + +case "$jobs" in +''|*[!0-9]*|0) + echo "error: job count must be a positive integer: $jobs" >&2 + exit 2 + ;; +esac + +package_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P) +if test -z "$source_dir" +then + source_dir=$package_dir/src/msys2-runtime +fi +test -d "$source_dir/winsup" || { + echo "error: MSYS2 runtime source not found at $source_dir" >&2 + exit 1 +} +source_dir=$(cd "$source_dir" && pwd -P) + +# PowerShell may have inherited a MINGW64 environment. Reset all related +# variables together; changing MSYSTEM alone leaves stale tool paths behind. +export MSYSTEM=MSYS +. /etc/msystem +export ACLOCAL_PATH=/usr/share/aclocal +export PATH=/usr/bin:/mingw64/bin:/mingw32/bin:$PATH + +gcc=$(command -v gcc) +gcc_target=$(gcc -dumpmachine) +test "$gcc" = /usr/bin/gcc || { + echo "error: expected /usr/bin/gcc, found $gcc" >&2 + exit 1 +} +test "$gcc_target" = "$MSYSTEM_CHOST" || { + echo "error: gcc targets $gcc_target, expected $MSYSTEM_CHOST" >&2 + exit 1 +} + +if test -z "$build_dir" +then + build_dir="$(dirname "$source_dir")/build-test-$MSYSTEM_CHOST" +fi +mkdir -p "$build_dir/logs" +build_dir=$(cd "$build_dir" && pwd -P) + +pkgver=$(sed -n 's/^pkgver=//p' "$package_dir/PKGBUILD") +test -n "$pkgver" || { + echo "error: could not read pkgver from $package_dir/PKGBUILD" >&2 + exit 1 +} + +runtime_commit=$(git -C "$source_dir" rev-parse HEAD) +export CFLAGS="-O2 -pipe -ggdb -DCYGPORT_RELEASE_INFO=$pkgver" +export CXXFLAGS="-O2 -pipe -ggdb" + +config_stamp=$build_dir/.test-build-config +config_key="$MSYSTEM_CHOST|$runtime_commit|$CFLAGS|$CXXFLAGS" +configure_needed=$reconfigure +autogen_needed=$reconfigure + +if ! test -f "$build_dir/Makefile" || ! test -f "$config_stamp" +then + configure_needed=t + test -f "$build_dir/Makefile" || autogen_needed=t +else + test "$(cat "$config_stamp")" = "$config_key" || + configure_needed=t + + build_system_change=$(find "$source_dir/winsup" -type f \ + \( -name configure.ac -o -name Makefile.am -o -name '*.m4' \) \ + -newer "$config_stamp" -print -quit) + if test -n "$build_system_change" + then + autogen_needed=t + configure_needed=t + fi + test "$source_dir/configure" -nt "$build_dir/Makefile" && + configure_needed=t +fi + +timestamp=$(date +%Y%m%d-%H%M%S) +log=$build_dir/logs/build-$timestamp.log + +echo "MSYSTEM=$MSYSTEM" +echo "MSYSTEM_CHOST=$MSYSTEM_CHOST" +echo "gcc=$gcc ($gcc_target)" +echo "source=$source_dir" +echo "build=$build_dir" +echo "log=$log" +if test -n "$configure_needed" +then + echo "configuration=refresh" +else + echo "configuration=reuse" +fi + +{ + if test -n "$autogen_needed" + then + ( + cd "$source_dir/winsup" + ./autogen.sh + ) + fi + + if test -n "$configure_needed" + then + ( + cd "$build_dir" + "$source_dir/configure" \ + --with-msys2-runtime-commit="$runtime_commit" \ + --prefix=/usr \ + --build="$MSYSTEM_CHOST" \ + --sysconfdir=/etc + printf '%s\n' "$config_key" >"$config_stamp" + ) + fi + + ( + cd "$build_dir" + LC_ALL=C make -j"$jobs" all-target-newlib + LC_ALL=C make configure-target-winsup + ) + + LC_ALL=C make \ + -C "$build_dir/$MSYSTEM_CHOST/winsup/cygwin" \ + -j"$jobs" \ + child_info_magic.h \ + shared_info_magic.h \ + globals.h \ + localtime.patched.c + + LC_ALL=C make \ + -C "$build_dir/$MSYSTEM_CHOST/winsup/cygwin" \ + -j"$jobs" \ + new-msys-2.0.dll +} 2>&1 | tee "$log" | summarize_output + +dll=$build_dir/$MSYSTEM_CHOST/winsup/cygwin/new-msys-2.0.dll +test -f "$dll" || { + echo "error: runtime build did not produce $dll" >&2 + exit 1 +} + +newer_source=$(find "$source_dir/winsup/cygwin" -type f \ + \( -name '*.c' -o -name '*.cc' -o -name '*.h' -o -name '*.S' \) \ + -newer "$dll" -print -quit) +test -z "$newer_source" || { + echo "error: runtime DLL is older than $newer_source" >&2 + exit 1 +} + +echo "runtime DLL built successfully: $dll" | tee -a "$log" + +if test -n "$full_build" +then + if ! LC_ALL=C make -C "$build_dir" -j"$jobs" 2>&1 | + tee -a "$log" | + summarize_output + then + echo "error: runtime DLL succeeded, but the full build failed" >&2 + if grep -q 'undefined reference to `ZSTD_' "$log" + then + echo "hint: PKGBUILD lists libzstd-devel as a build dependency" >&2 + fi + exit 1 + fi +fi