155 lines
5.6 KiB
Bash
Executable File
155 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build pinned third-party deps for Windows x86_64 (mingw-w64, UCRT) into
|
|
# third_party/prefix-mingw, plus busybox-w32 into third_party/busybox.
|
|
# nix-shell shell-win.nix --run 'scripts/build_third_party_mingw.sh [all|curl|pdcurses|ncurses|busybox-w32]'
|
|
# Works the same from an MSYS2 UCRT64 shell (MINGW_HOST= uses unprefixed tools).
|
|
set -euo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
TP="$ROOT/third_party"
|
|
PREFIX="$TP/prefix-mingw"
|
|
HOST="${MINGW_HOST-x86_64-w64-mingw32}"
|
|
T="${HOST:+$HOST-}"
|
|
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}"
|
|
|
|
CURL_TAG=curl-8_22_0
|
|
PDCURSES_TAG=3.9
|
|
NCURSES_VER=6.6
|
|
BUSYBOX_W32_REV=9b50a1e
|
|
|
|
mkdir -p "$TP" "$PREFIX"
|
|
need_cmd() { command -v "$1" >/dev/null || { echo "missing: $1" >&2; exit 1; }; }
|
|
need_cmd git
|
|
need_cmd make
|
|
need_cmd "${T}gcc"
|
|
|
|
# Clone a GitHub repo with CN-friendly mirrors; fall back if one proxy 502s.
|
|
github_mirrors() { # https://github.com/org/repo[.git] -> print candidate clone URLs
|
|
local url="$1" path
|
|
path="${url#https://github.com/}"
|
|
path="${path%.git}"
|
|
printf '%s\n' \
|
|
"https://ghfast.top/https://github.com/${path}.git" \
|
|
"https://ghproxy.net/https://github.com/${path}.git" \
|
|
"https://gitclone.com/github.com/${path}.git" \
|
|
"https://github.com/${path}.git"
|
|
}
|
|
|
|
checkout() { # url dir rev
|
|
local url="$1" dir="$2" rev="$3" m
|
|
if [[ ! -d "$dir/.git" ]]; then
|
|
local ok=0
|
|
while IFS= read -r m; do
|
|
echo " clone $m"
|
|
rm -rf "$dir"
|
|
if git clone -q --filter=blob:none "$m" "$dir"; then
|
|
ok=1
|
|
break
|
|
fi
|
|
done < <(github_mirrors "$url")
|
|
[[ $ok -eq 1 ]] || { echo "clone failed: $url" >&2; exit 1; }
|
|
fi
|
|
if ! git -C "$dir" rev-parse -q --verify "$rev^{commit}" >/dev/null; then
|
|
git -C "$dir" fetch -q --tags origin || true
|
|
git -C "$dir" fetch -q origin "$rev" || true
|
|
fi
|
|
git -C "$dir" checkout -q --detach "$rev"
|
|
}
|
|
|
|
build_curl() {
|
|
checkout https://github.com/curl/curl.git "$TP/curl" "$CURL_TAG"
|
|
rm -rf "$TP/curl/build-mingw"
|
|
local tc=()
|
|
[[ -n "$HOST" ]] && tc=(-DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER="${T}gcc" -DCMAKE_RC_COMPILER="${T}windres")
|
|
cmake -S "$TP/curl" -B "$TP/curl/build-mingw" -G Ninja "${tc[@]}" \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
|
|
-DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON \
|
|
-DCURL_USE_SCHANNEL=ON -DCURL_USE_OPENSSL=OFF \
|
|
-DCURL_WINDOWS_SSPI=ON -DENABLE_UNICODE=ON \
|
|
-DCURL_DISABLE_LDAP=ON -DCURL_USE_LIBPSL=OFF -DCURL_USE_LIBSSH2=OFF \
|
|
-DUSE_LIBIDN2=OFF -DUSE_NGHTTP2=OFF \
|
|
-DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF \
|
|
-DBUILD_CURL_EXE=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF \
|
|
-DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF
|
|
cmake --build "$TP/curl/build-mingw" -j"$JOBS"
|
|
cmake --install "$TP/curl/build-mingw"
|
|
echo "curl $CURL_TAG -> $PREFIX"
|
|
}
|
|
|
|
build_pdcurses() {
|
|
checkout https://github.com/wmcbrine/PDCurses.git "$TP/PDCurses" "$PDCURSES_TAG"
|
|
cd "$TP/PDCurses/wincon"
|
|
make clean >/dev/null 2>&1 || true
|
|
make -j"$JOBS" CC="${T}gcc" AR="${T}ar" STRIP="${T}strip" WIDE=Y UTF8=Y pdcurses.a
|
|
mkdir -p "$PREFIX/include/pdcurses" "$PREFIX/lib"
|
|
cp -f ../curses.h ../panel.h "$PREFIX/include/pdcurses/"
|
|
cp -f pdcurses.a "$PREFIX/lib/libpdcurses.a"
|
|
echo "PDCurses $PDCURSES_TAG -> $PREFIX"
|
|
}
|
|
|
|
build_ncurses() {
|
|
local src="$TP/ncurses-$NCURSES_VER" tgz="$TP/ncurses-$NCURSES_VER.tar.gz"
|
|
[[ -f "$tgz" ]] || curl -fL -o "$tgz" \
|
|
"https://invisible-island.net/archives/ncurses/ncurses-$NCURSES_VER.tar.gz"
|
|
[[ -d "$src" ]] || tar -C "$TP" -xzf "$tgz"
|
|
local pf
|
|
for pf in "$ROOT"/scripts/patches/ncurses-"$NCURSES_VER"-*.patch; do
|
|
[[ -e "$pf" ]] || continue
|
|
patch -d "$src" -p1 -R --dry-run -s -f <"$pf" >/dev/null 2>&1 && continue
|
|
if ! patch -d "$src" -p1 --dry-run -s -f <"$pf" >/dev/null 2>&1; then
|
|
echo "ncurses: $src has another version of $(basename "$pf"); re-extracting"
|
|
rm -rf "$src"
|
|
tar -C "$TP" -xzf "$tgz"
|
|
fi
|
|
patch -d "$src" -p1 -s <"$pf"
|
|
done
|
|
rm -rf "$src/build-mingw"
|
|
mkdir -p "$src/build-mingw"
|
|
cd "$src/build-mingw"
|
|
# --host stays canonical (config.sub may not know Debian's "mingw32ucrt");
|
|
# the tools themselves come from $HOST.
|
|
CC="${T}gcc" AR="${T}ar" RANLIB="${T}ranlib" STRIP="${T}strip" WINDRES="${T}windres" \
|
|
../configure --host=x86_64-w64-mingw32 --prefix="$PREFIX" \
|
|
--without-ada --without-cxx --without-cxx-binding --without-manpages \
|
|
--without-progs --without-tests --without-debug --without-shared \
|
|
--enable-widec --enable-sp-funcs --enable-term-driver \
|
|
--enable-interop --disable-home-terminfo --disable-db-install \
|
|
--with-fallbacks=ms-terminal,xterm-256color --without-pkg-config \
|
|
--disable-pc-files --with-build-cc="${BUILD_CC:-cc}" >/dev/null
|
|
make -j"$JOBS" libs >/dev/null
|
|
make install.libs >/dev/null
|
|
echo "ncurses $NCURSES_VER -> $PREFIX"
|
|
}
|
|
|
|
build_busybox_w32() {
|
|
checkout https://github.com/rmyorston/busybox-w32.git "$TP/busybox-w32" "$BUSYBOX_W32_REV"
|
|
cd "$TP/busybox-w32"
|
|
make -s mingw64u_defconfig >/dev/null
|
|
make -s -j"$JOBS" CROSS_COMPILE="$T" </dev/null
|
|
mkdir -p "$TP/busybox"
|
|
cp -f busybox.exe "$TP/busybox/busybox.exe"
|
|
cat >"$TP/busybox/LICENSE.busybox" <<EOF
|
|
BusyBox is GPLv2. This busybox.exe is busybox-w32 ($BUSYBOX_W32_REV, Unicode build):
|
|
https://github.com/rmyorston/busybox-w32
|
|
Upstream BusyBox: https://busybox.net/
|
|
EOF
|
|
ls -la "$TP/busybox/busybox.exe"
|
|
}
|
|
|
|
case "${1:-all}" in
|
|
curl) build_curl ;;
|
|
pdcurses) build_pdcurses ;;
|
|
ncurses) build_ncurses ;;
|
|
busybox-w32) build_busybox_w32 ;;
|
|
all)
|
|
build_curl
|
|
build_ncurses
|
|
build_busybox_w32
|
|
;;
|
|
*)
|
|
echo "usage: $0 [all|curl|pdcurses|ncurses|busybox-w32]"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo "DONE"
|