#!/usr/bin/env bash # Build pinned static deps for a Linux release into third_party/prefix-linux-ARCH: # mbedTLS, libcurl (HTTP(S) only, mbedTLS) and wide ncurses. # scripts/build_third_party_linux.sh x86_64|x86|aarch64 [all|mbedtls|curl|ncurses] # Uses LINUX_HOST-gcc from PATH, else fetches it via ci_linux_toolchain.sh. # Host tools: cmake ninja make perl, and tic/infocmp with the fallback # terminal entries (Debian: ncurses-bin ncurses-term). set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" ARCH="${1:?usage: $0 x86_64|x86|aarch64 [all|mbedtls|curl|ncurses]}" TP="$ROOT/third_party" PREFIX="$TP/prefix-linux-$ARCH" SRC="$TP/src" WORK="$TP/build-linux-$ARCH" JOBS="${JOBS:-$(nproc 2>/dev/null || echo 4)}" MBEDTLS_VER=3.6.7 MBEDTLS_SHA=a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6 CURL_VER=8.22.0 CURL_SHA=f7ef3ae8a22e521f289803fe93543eb64c329b58aa73a9e224dfd915a2a5f4f7 NCURSES_VER=6.6 NCURSES_SHA=355b4cbbed880b0381a04c46617b7656e362585d52e9cf84a67e2009b749ff11 # Compiled in, so the TUI starts even where no terminfo database is found. NCURSES_FALLBACKS=xterm-256color,xterm,screen-256color,tmux-256color,linux,vt100 if [[ -z "${LINUX_HOST:-}" ]] || ! command -v "$LINUX_HOST-gcc" >/dev/null; then read -r LINUX_HOST bindir < <(bash "$ROOT/scripts/ci_linux_toolchain.sh" "$ARCH") export PATH="$bindir:$PATH" fi T="$LINUX_HOST-" need() { command -v "$1" >/dev/null || { echo "missing: $1" >&2; exit 1; }; } need "${T}gcc" need cmake need ninja need make need tic need infocmp mkdir -p "$PREFIX" "$SRC" "$WORK" fetch() { # file sha url... local file="$1" sha="$2" u shift 2 if [[ -f "$SRC/$file" ]] && echo "$sha $SRC/$file" | sha256sum -c --quiet - 2>/dev/null; then return 0 fi for u in "$@"; do echo " try $u" if curl -fsSL --retry 2 --connect-timeout 15 --max-time 600 -o "$SRC/$file.part" "$u" && echo "$sha $SRC/$file.part" | sha256sum -c --quiet -; then mv "$SRC/$file.part" "$SRC/$file" return 0 fi done rm -f "$SRC/$file.part" echo "download failed: $file" >&2 exit 1 } unpack() { # file dir rm -rf "${WORK:?}/$2" tar -C "$WORK" -xf "$SRC/$1" } gh() { # path -> GitHub URL candidates (CN proxies first) printf '%s\n' "https://ghfast.top/https://github.com/$1" \ "https://ghproxy.net/https://github.com/$1" "https://github.com/$1" } cmake_cross() { # src build args... local s="$1" b="$2" shift 2 cmake -S "$s" -B "$b" -G Ninja \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_C_COMPILER="${T}gcc" -DCMAKE_AR="$(command -v "${T}ar")" \ -DCMAKE_RANLIB="$(command -v "${T}ranlib")" \ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$PREFIX" \ -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_PREFIX_PATH="$PREFIX" \ -DCMAKE_FIND_ROOT_PATH="$PREFIX" \ -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \ -DCMAKE_POSITION_INDEPENDENT_CODE=OFF \ "$@" cmake --build "$b" -j"$JOBS" cmake --install "$b" } build_mbedtls() { local f="mbedtls-$MBEDTLS_VER.tar.bz2" mapfile -t urls < <(gh "Mbed-TLS/mbedtls/releases/download/mbedtls-$MBEDTLS_VER/$f") fetch "$f" "$MBEDTLS_SHA" "${urls[@]}" unpack "$f" "mbedtls-$MBEDTLS_VER" cmake_cross "$WORK/mbedtls-$MBEDTLS_VER" "$WORK/mbedtls-$MBEDTLS_VER/build" \ -DENABLE_TESTING=OFF -DENABLE_PROGRAMS=OFF -DGEN_FILES=OFF \ -DUSE_STATIC_MBEDTLS_LIBRARY=ON -DUSE_SHARED_MBEDTLS_LIBRARY=OFF \ -DMBEDTLS_FATAL_WARNINGS=OFF echo "mbedTLS $MBEDTLS_VER -> $PREFIX" } build_curl() { local f="curl-$CURL_VER.tar.xz" mapfile -t urls < <(gh "curl/curl/releases/download/curl-${CURL_VER//./_}/$f") fetch "$f" "$CURL_SHA" "https://curl.se/download/$f" "${urls[@]}" unpack "$f" "curl-$CURL_VER" # Cross builds skip CA detection; this is only libcurl's default, the # program probes the usual distro paths when it is missing. cmake_cross "$WORK/curl-$CURL_VER" "$WORK/curl-$CURL_VER/build" \ -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON \ -DCURL_USE_MBEDTLS=ON -DCURL_USE_OPENSSL=OFF \ -DMBEDTLS_INCLUDE_DIR="$PREFIX/include" \ -DMBEDTLS_LIBRARY="$PREFIX/lib/libmbedtls.a" \ -DMBEDX509_LIBRARY="$PREFIX/lib/libmbedx509.a" \ -DMBEDCRYPTO_LIBRARY="$PREFIX/lib/libmbedcrypto.a" \ -DCURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt -DCURL_CA_PATH=none \ -DHTTP_ONLY=ON -DCURL_DISABLE_LDAP=ON -DCURL_USE_LIBPSL=OFF \ -DCURL_USE_LIBSSH2=OFF -DCURL_USE_LIBSSH=OFF -DUSE_LIBIDN2=OFF \ -DUSE_NGHTTP2=OFF -DCURL_ZLIB=OFF -DCURL_BROTLI=OFF -DCURL_ZSTD=OFF \ -DCURL_USE_GSSAPI=OFF -DENABLE_THREADED_RESOLVER=ON \ -DBUILD_CURL_EXE=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF \ -DBUILD_LIBCURL_DOCS=OFF -DBUILD_MISC_DOCS=OFF -DENABLE_CURL_MANUAL=OFF echo "curl $CURL_VER -> $PREFIX" } build_ncurses() { local f="ncurses-$NCURSES_VER.tar.gz" fetch "$f" "$NCURSES_SHA" \ "https://invisible-island.net/archives/ncurses/$f" \ "https://mirrors.tuna.tsinghua.edu.cn/gnu/ncurses/$f" \ "https://ftp.gnu.org/gnu/ncurses/$f" unpack "$f" "ncurses-$NCURSES_VER" local b="$WORK/ncurses-$NCURSES_VER/build" mkdir -p "$b" cd "$b" CC="${T}gcc" AR="${T}ar" RANLIB="${T}ranlib" STRIP="${T}strip" \ ../configure --host="$LINUX_HOST" --prefix="$PREFIX" \ --without-ada --without-cxx --without-cxx-binding --without-manpages \ --without-progs --without-tests --without-debug --without-shared \ --with-normal --enable-widec --disable-db-install \ --with-default-terminfo-dir=/usr/share/terminfo \ --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo:/usr/lib/terminfo \ --with-fallbacks="$NCURSES_FALLBACKS" \ --with-tic-path="$(command -v tic)" --with-infocmp-path="$(command -v infocmp)" \ --enable-pc-files --with-pkg-config-libdir="$PREFIX/lib/pkgconfig" \ --with-build-cc="${BUILD_CC:-cc}" >/dev/null make -j"$JOBS" libs >/dev/null make install.libs >/dev/null echo "ncurses $NCURSES_VER -> $PREFIX" } case "${2:-all}" in mbedtls) build_mbedtls ;; curl) build_curl ;; ncurses) build_ncurses ;; all) build_mbedtls build_curl build_ncurses ;; *) echo "usage: $0 ARCH [all|mbedtls|curl|ncurses]" >&2 exit 1 ;; esac echo "DONE $ARCH"