Files
build_infra/linux_shell/cqwrteur/toolchainbuildscripts-main/common/install-libc.sh
T
2026-06-16 10:23:51 +08:00

449 lines
20 KiB
Bash

#!/bin/bash
install_libc() {
local sharedstorage="$1"
local host_triplet="$2"
local TRIPLET="$3"
local currentpathlibc="$4"
local tripletpath="$5"
local sysrootpathusr="$6"
local usellvm="$7"
local buildheadersonly="$8"
local multilibs="${9:-no}"
local isgcccrossing="${10:-no}"
local install_full_libc="${11:-no}"
local CPU
local VENDOR
local OS
local ABI
parse_triplet $TRIPLET CPU VENDOR OS ABI
if [[ "$OS" == mingw* ]]; then
VENDOR=""
OS="windows"
ABI="gnu"
fi
local ANDROIDAPIVERSION
if [[ "$OS" == "linux" && "$ABI" == android* ]]; then
ANDROIDAPIVERSION=${ABI#android}
if [ -z "$ANDROIDAPIVERSION" ]; then
echo "Error: ANDROIDAPIVERSION is not set."
exit 1
fi
fi
local phase_file
if [ "$buildheadersonly" == "yes" ]; then
phase_file=".libc_headers_phase_done"
else
phase_file=".libc_phase_done"
fi
local installdirpath="${sysrootpathusr}"
mkdir -p "${currentpathlibc}"
mkdir -p "${tripletpath}"
if [ ! -f "${currentpathlibc}/${phase_file}" ]; then
if [[ "$OS" == "darwin"* ]]; then
cd "${currentpathlibc}"
local repo_url
local base_url
if [ "$CLONE_IN_CHINA" = "yes" ]; then
repo_url="https://gitee.com/qabeowjbtkwb/apple-darwin-sysroot.git"
base_url="https://gitee.com/qabeowjbtkwb/apple-darwin-sysroot/releases/download"
else
repo_url="https://github.com/trcrsired/apple-darwin-sysroot.git"
base_url="https://github.com/trcrsired/apple-darwin-sysroot/releases/download"
fi
local darwinversiondate
if [ -z ${DARWINVERSIONDATE+x} ]; then
darwinversiondate=$(git ls-remote --tags $repo_url | tail -n 1 | sed 's/.*\///')
else
darwinversiondate=${DARWINVERSIONDATE}
fi
local triplet_variant=${TRIPLET}
[[ $triplet_variant == arm64e-* ]] && triplet_variant="aarch64-${triplet_variant#arm64e-}"
wget --no-verbose ${base_url}/${darwinversiondate}/${triplet_variant}.tar.xz
if [ $? -ne 0 ]; then
echo "Failed to download the Darwin sysroot"
exit 1
fi
chmod 755 ${triplet_variant}.tar.xz
tar -xf "${triplet_variant}.tar.xz" -C "${tripletpath}"
if [ $? -ne 0 ]; then
echo "Failed to extract the Darwin sysroot"
exit 1
fi
if [[ $TRIPLET != "$triplet_variant" ]]; then
mv "${tripletpath}/$triplet_variant" "${tripletpath}/$TRIPLET"
fi
elif [[ "$OS" == "freebsd"* ]]; then
cd "${currentpathlibc}"
local base_url
if [ "$CLONE_IN_CHINA" = "yes" ]; then
base_url="https://github.com/trcrsired/x86_64-freebsd-libc-bin/releases/download"
else
base_url="https://gitee.com/qabeowjbtkwb/x86_64-freebsd-libc-bin/releases/download"
fi
local version_tag="1"
local archive_name="${CPU}-freebsd-libc.tar.xz"
local remote_url="${base_url}/${version_tag}/${archive_name}"
local local_archive="${currentpathlibc}/downloads/${archive_name}"
local shared_archive="${sharedstorage}/freebsd-libc/${archive_name}"
local decompress_dir="${currentpathlibc}/sysroot_decompress"
mkdir -p "$(dirname "$local_archive")"
mkdir -p "$(dirname "$shared_archive")"
mkdir -p "$decompress_dir"
# Step 1: Try to reuse shared archive if available
if [ -f "$shared_archive" ]; then
echo "Using cached libc archive from sharedstorage"
cp "$shared_archive" "$local_archive"
else
echo "Downloading libc archive from $remote_url"
wget --no-verbose -O "$local_archive" "$remote_url"
if [ $? -ne 0 ]; then
echo "Error: Failed to download $archive_name for $TRIPLET"
exit 1
fi
cp "$local_archive" "$shared_archive"
fi
# Step 2: Extract
tar -xf "$local_archive" -C "$decompress_dir"
if [ $? -ne 0 ]; then
echo "Error: Failed to extract $archive_name"
exit 1
fi
# Step 3: Add write permission for owner
chmod -R u+w "$decompress_dir/${CPU}-freebsd-libc"
# Step 4: Install
mkdir -p "$installdirpath"
cp -a "$decompress_dir/${CPU}-freebsd-libc/"* "$installdirpath/"
if [ $? -ne 0 ]; then
echo "Error: Copy to installdir for freebsd"
exit 1
fi
elif [[ "$OS" == "windows" ]]; then
if [[ "$ABI" == "msvc" ]]; then
clone_or_update_dependency windows-msvc-sysroot
elif [[ "$ABI" == "gnu" ]]; then
clone_or_update_dependency mingw-w64
local MINGWTRIPLET="${CPU}-w64-mingw32"
local MINGWW64COMMON
if [[ ${CPU} == "x86_64" ]]; then
if [[ "$multilibs" == "yes" ]]; then
MINGWW64COMMON="--enable-lib32 --enable-lib64"
else
MINGWW64COMMON="--disable-lib32 --enable-lib64"
fi
elif [[ ${CPU} == "aarch64" ]]; then
MINGWW64COMMON="--disable-lib32 --disable-lib64 --disable-libarm32 --enable-libarm64"
elif [[ ${CPU} == "arm" ]]; then
MINGWW64COMMON="--disable-lib32 --disable-lib64 --enable-libarm32 --disable-libarm64"
elif [[ ${CPU} =~ i[3-6]86 ]]; then
MINGWW64COMMON="--enable-lib32 --disable-lib64 --with-default-msvcrt=msvcrt"
else
MINGWW64COMMON="--disable-lib32 --disable-lib64 --disable-libarm32 --disable-libarm64 --enable-lib$CPU"
fi
MINGWW64COMMON="$MINGWW64COMMON --host=${MINGWTRIPLET} --disable-nls --disable-werror --prefix=${sysrootpathusr}"
local MINGWW64COMMONENV="
CC=\"clang --target=${TRIPLET} -fuse-ld=lld \"--sysroot=${sysrootpathusr}\"\"
CXX=\"clang++ --target=${TRIPLET} -fuse-ld=lld \"--sysroot=${sysrootpathusr}\"\"
LD=lld
NM=llvm-nm
RANLIB=llvm-ranlib
AR=llvm-ar
DLLTOOL=llvm-dlltool
AS=llvm-as
STRIP=llvm-strip
OBJDUMP=llvm-objdump
WINDRES=llvm-windres
"
# Resolve absolute paths to ensure accurate comparison
local tripletpath_real="$(realpath "${tripletpath}")"
local installdirpath_real="$(realpath "${installdirpath}")"
if [ ! -f "${currentpathlibc}/.libc_phase_header" ]; then
mkdir -p "${currentpathlibc}/mingw-w64-headers"
cd "${currentpathlibc}/mingw-w64-headers"
if [ ! -f Makefile ]; then
if [[ "$usellvm" == "yes" ]]; then
eval ${MINGWW64COMMONENV} $TOOLCHAINS_BUILD/mingw-w64/mingw-w64-headers/configure ${MINGWW64COMMON}
else
$TOOLCHAINS_BUILD/mingw-w64/mingw-w64-headers/configure ${MINGWW64COMMON}
fi
if [ $? -ne 0 ]; then
echo "Error: mingw-w64-headers($TRIPLET) configure failed"
exit 1
fi
fi
make -j$(nproc) 2>err.txt
if [ $? -ne 0 ]; then
echo "Error: make mingw-w64-headers($TRIPLET) install-strip failed"
exit 1
fi
make install-strip -j$(nproc) 2>>err.txt
if [ $? -ne 0 ]; then
echo "Error: make mingw-w64-headers($TRIPLET) install-strip failed"
exit 1
fi
# Skip copy if source and destination are the same directory
# if [ "$tripletpath_real" = "$installdirpath_real" ]; then
# echo "Skip copy: source and destination are the same ($tripletpath_real)"
# else
# Copy all files from source to destination, preserving symbolic links
# cp -r --preserve=links "${tripletpath}"/* "${installdirpath}"/
# Check if the copy command failed
# if [ $? -ne 0 ]; then
# echo "Error: copy mingw-w64-headers($TRIPLET) failed"
# exit 1
# fi
# fi
echo "$(date +%s)" > "${currentpathlibc}/.libc_phase_header"
fi
mkdir -p "${currentpathlibc}/mingw-w64-crt"
cd "${currentpathlibc}/mingw-w64-crt"
if [ ! -f Makefile ]; then
if [[ "$usellvm" == "yes" ]]; then
eval ${MINGWW64COMMONENV} $TOOLCHAINS_BUILD/mingw-w64/mingw-w64-crt/configure ${MINGWW64COMMON}
else
$TOOLCHAINS_BUILD/mingw-w64/mingw-w64-crt/configure ${MINGWW64COMMON}
fi
if [ $? -ne 0 ]; then
echo "Error: configure mingw-w64-crt($TRIPLET) failed"
exit 1
fi
fi
make -j$(nproc) 2>err.txt
if [ $? -ne 0 ]; then
echo "Error: make mingw-w64-crt($TRIPLET) failed"
exit 1
fi
make install-strip -j$(nproc) 2>>err.txt
if [ $? -ne 0 ]; then
echo "Error: make install-strip mingw-w64-crt($TRIPLET) failed"
exit 1
fi
if [[ "$isgcccrossing" == "yes" ]]; then
# Create lib/32 symlink if lib32 exists and multilibs is enabled for x86_64
if [[ "$CPU" == "x86_64" && "$multilibs" == "yes" ]]; then
if [ -d "${installdirpath}/lib32" ]; then
mkdir -p "${installdirpath}/lib"
if [ ! -e "${installdirpath}/lib/32" ]; then
ln -sfn ../lib32 "${installdirpath}/lib/32"
echo "Created symlink: ${installdirpath}/lib/32 → ../lib32"
else
echo "Symlink already exists: ${installdirpath}/lib/32"
fi
else
echo "lib32 directory not found under ${installdirpath}, skipping symlink"
fi
fi
fi
# Skip copy if source and destination are the same directory
# if [ "$tripletpath_real" = "$installdirpath_real" ]; then
# echo "Skip copy: source and destination are the same ($tripletpath_real)"
# else
# Copy all files from source to destination, preserving symbolic links
# cp -r --preserve=links "${tripletpath}"/* "${installdirpath}"/
# Check if the copy command failed
# if [ $? -ne 0 ]; then
# echo "Error: copy mingw-w64-crt($TRIPLET) failed"
# exit 1
# fi
# fi
else
echo "Unknown Windows ABI: $ABI"
exit 1
fi
elif [[ "$OS" == "linux" ]]; then
if [[ "$ABI" == "android"* ]]; then
if [ -z "${ANDROIDNDKVERSION}" ]; then
ANDROIDNDKVERSION=$(git ls-remote --tags https://github.com/android/ndk.git 2>/dev/null \
| grep -v '\^{}' \
| awk -F'/' '{print $3}' \
| grep -E '^r[0-9]+$' \
| sort -V \
| tail -n1)
echo "Detected ANDROIDNDKVERSION: ${ANDROIDNDKVERSION}"
if [ -z "${ANDROIDNDKVERSION}" ]; then
ANDROIDNDKVERSION="r29"
fi
fi
local ANDROIDNDKVERSIONSHORTNAME="android-ndk-${ANDROIDNDKVERSION}"
local ANDROIDNDKVERSIONFULLNAME="${ANDROIDNDKVERSIONSHORTNAME}-linux"
# China Mirror no longer works
# if [ "$CLONE_IN_CHINA" = "yes" ]; then
# base_url="https://googledownloads.cn/android/repository"
# else
local base_url="https://dl.google.com/android/repository"
# fi
local NDKURL="${base_url}/${ANDROIDNDKVERSIONFULLNAME}.zip"
# Define filenames and paths
local NDK_ZIP="${ANDROIDNDKVERSIONFULLNAME}.zip"
local NDK_DONE_FILE=".ndk_downloaded_at"
local NDK_SHARED_ZIP="${sharedstorage}/${NDK_ZIP}"
local NDK_SHARED_DONE="${sharedstorage}/${NDK_DONE_FILE}"
# Ensure sharedstorage exists
mkdir -p "${sharedstorage}"
# Download to sharedstorage if not already completed
if [ -f "${NDK_SHARED_DONE}" ] && [ -f "${NDK_SHARED_ZIP}" ]; then
echo "NDK zip already downloaded in shared storage."
else
echo "Downloading NDK zip to shared storage..."
cd "${sharedstorage}"
wget --tries=2 --show-progress "${NDKURL}"
if [ $? -ne 0 ]; then
echo "wget ${NDKURL} failure"
exit 1
fi
echo "$(date +%s)" > "${NDK_DONE_FILE}"
fi
# Prepare target extraction directory
mkdir -p "${currentpathlibc}"
cd "${currentpathlibc}"
# Unzip directly from sharedstorage into currentpathlibc
unzip -q "${NDK_SHARED_ZIP}"
if [ $? -ne 0 ]; then
echo "unzip ${NDK_SHARED_ZIP} failure"
exit 1
fi
# Record download completion timestamp
echo "$(date +%s)" > "${NDK_DONE_FILE}"
mkdir -p "${installdirpath}"
cp -r --preserve=links ${currentpathlibc}/${ANDROIDNDKVERSIONSHORTNAME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/${CPU}-linux-android/${ANDROIDAPIVERSION} ${installdirpath}/lib
cp -r --preserve=links ${currentpathlibc}/${ANDROIDNDKVERSIONSHORTNAME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include ${installdirpath}/
cp -r --preserve=links ${installdirpath}/include/${CPU}-linux-android/asm ${installdirpath}/include/
else
clone_or_update_dependency linux
if [ $? -ne 0 ]; then
echo "Error: Failed to clone or update linux"
exit 1
fi
install_linux_kernel_headers $CPU "${currentpathlibc}" "${installdirpath}"
if [ $? -ne 0 ]; then
echo "Error: Failed to install Linux kernel headers"
exit 1
fi
if [[ "$ABI" == "gnu" ]]; then
clone_or_update_dependency glibc
if [ $? -ne 0 ]; then
echo "Error: Failed to clone or update glibc"
exit 1
fi
build_glibc $CPU "${currentpathlibc}" "${installdirpath}" "${usellvm}" "${buildheadersonly}" "no" "" "${install_full_libc}"
if [ $? -ne 0 ]; then
echo "Error: Failed to build glibc"
exit 1
fi
elif [[ "$ABI" == "musl" ]]; then
clone_or_update_dependency musl
if [ $? -ne 0 ]; then
echo "Error: Failed to clone or update musl"
exit 1
fi
build_musl $TRIPLET "${currentpathlibc}" "${installdirpath}" "${usellvm}" "${buildheadersonly}" "no" "" "${install_full_libc}"
if [ $? -ne 0 ]; then
echo "Error: Failed to build musl"
exit 1
fi
fi
fi
elif [[ "$OS" == "msdosdjgpp" ]]; then
local DJCRX="${DJCRX:-djcrx205}"
local shared_djgpp_zip="${sharedstorage}/djgpp/${DJCRX}.zip"
local local_djgpp_zip="${currentpathlibc}/downloads/${DJCRX}.zip"
local local_djgpp_root="${currentpathlibc}/${DJCRX}"
mkdir -p "${currentpathlibc}/downloads"
mkdir -p "${local_djgpp_root}"
mkdir -p "${sysrootpathusr}"
mkdir -p "$(dirname "$shared_djgpp_zip")"
# Step 1: Try to copy from sharedstorage if available
if [ -f "$shared_djgpp_zip" ]; then
echo "Using cached ${DJCRX}.zip from sharedstorage"
cp "$shared_djgpp_zip" "$local_djgpp_zip"
else
echo "Downloading ${DJCRX}.zip from Delorie"
#Use my fix up of djcrx since it has no struct timespec which breaks libstdc++ build
# wget -O "$local_djgpp_zip" "http://www.delorie.com/pub/djgpp/current/v2/${DJCRX}.zip"
wget -O "$local_djgpp_zip" "https://github.com/trcrsired/djcrx/releases/download/20251102/${DJCRX}.zip"
if [ $? -ne 0 ]; then
echo "Error: Failed to download ${DJCRX}.zip"
exit 1
fi
cp "$local_djgpp_zip" "$shared_djgpp_zip"
fi
chmod 755 "$local_djgpp_zip" || true
unzip "$local_djgpp_zip" -d "${local_djgpp_root}"
if [ $? -ne 0 ]; then
echo "Error: Failed to unzip ${DJCRX}.zip"
exit 1
fi
mkdir -p "${sysrootpathusr}/bin"
# Determine compiler for stubify/stubedit
local stub_compiler=""
if [ -z "$host_triplet" ]; then
if [[ "$usellvm" == "yes" ]]; then
stub_compiler="clang -fuse-ld=lld"
else
stub_compiler="gcc"
fi
else
if [[ "$usellvm" == "yes" ]]; then
stub_compiler="clang --target=${host_triplet} -fuse-ld=lld"
else
stub_compiler="${host_triplet}-gcc"
fi
fi
$stub_compiler -o "${sysrootpathusr}/bin/stubify" "${local_djgpp_root}/src/stub/stubify.c" -s -O3 -flto
if [ $? -ne 0 ]; then
echo "Error: Failed to compile stubify"
exit 1
fi
$stub_compiler -o "${sysrootpathusr}/bin/stubedit" "${local_djgpp_root}/src/stub/stubedit.c" -s -O3 -flto
if [ $? -ne 0 ]; then
echo "Error: Failed to compile stubedit"
exit 1
fi
cp -a "${local_djgpp_root}"/include "${sysrootpathusr}/"
cp -a "${local_djgpp_root}"/lib "${sysrootpathusr}/"
fi
echo "$(date +%s)" > "${currentpathlibc}/${phase_file}"
fi
}