Files
2026-08-13 13:04:55 +08:00

470 lines
16 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# shellcheck disable=SC2155
if ! type "include" > /dev/null 2>&1; then
include() {
. "$(cd "$(dirname "$1")" && pwd)/${2}";
};
fi
include "${BASH_SOURCE[0]}" ../pragma_once.bash
if ! pragma_once ${BASH_SOURCE[0]}; then return 0; fi
include "${BASH_SOURCE[0]}" ../base/export.bash
false && source ../base/export.bash
# 必选项
export bge_install_prefix
# 平台选项
export bge_build bge_host bge_target
export bge_source_sysroot # 交叉编译和 拿大编译必填项 使用模式两种 软链接使用和 复制使用
export bge_sysroot_use_mode # 使用模式两种 软链接(link), 复制(copy) 使用
# 1阶段gcc
export bge_stage1 # 1代表这是不依赖glibc的gcc,用于构建glibc的gcc0代表是普通的gcc
# url选项集合
export bge_gcc_ver bge_gcc_suffix_opts
export bge_gmp_url bge_gmp_suffix_opts
export bge_mpfr_url bge_mpfr_suffix_opts
export bge_mpc_url bge_mpc_suffix_opts
export bge_binutils_gdb_ver bge_binutils_gdb_suffix_opts
export bge_isl_url bge_isl_suffix_opts
# 内部自动计算的变量(每次都会刷新)
export bge_build_mode # native pseudo_native cross canadian_stage3
export b_cpu b_vendor b_os b_abi
export h_cpu h_vendor h_os h_abi
export t_cpu t_vendor t_os t_abi
export bge_toolchain_name
bge_dump_config() {
log_info "========== 【构建gcc 全局选项 BGE CONFIG】 =========="
log_info "%-24s = %s" "bge_install_prefix" "${bge_install_prefix}"
log_info "%-24s = %s" "bge_build" "${bge_build}"
log_info "%-24s = %s" "bge_host" "${bge_host}"
log_info "%-24s = %s" "bge_target" "${bge_target}"
log_info "%-24s = %s" "bge_build_mode" "${bge_build_mode}"
log_info "%-24s = %s" "bge_source_sysroot" "${bge_source_sysroot}"
log_info "%-24s = %s" "bge_sysroot_use_mode" "${bge_sysroot_use_mode}"
log_info "内部自动计算的变量"
parse_triplet "$bge_build" b_cpu b_vendor b_os b_abi
parse_triplet "$bge_host" h_cpu h_vendor h_os h_abi
parse_triplet "$bge_target" t_cpu t_vendor t_os t_abi
log_info "bge_build_mode:%s" "${bge_build_mode}"
log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "build tuple" "$b_cpu" "$b_vendor" "$b_os" "$b_abi"
log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "host tuple" "$h_cpu" "$h_vendor" "$h_os" "$h_abi"
log_info "%-24s = cpu=%-12s vendor=%-12s os=%-12s abi=%s" "target tuple" "$t_cpu" "$t_vendor" "$t_os" "$t_abi"
log_info "每次build_gcc后需要,手动重置的变量"
log_info "%-24s = %s" "bge_gcc_ver" "${bge_gcc_ver}"
log_info "%-24s = %s" "bge_gcc_suffix_opts" "${bge_gcc_suffix_opts}"
log_info "%-24s = %s" "bge_gmp_url" "${bge_gmp_url}"
log_info "%-24s = %s" "bge_gmp_suffix_opts" "${bge_gmp_suffix_opts}"
log_info "%-24s = %s" "bge_mpfr_url" "${bge_mpfr_url}"
log_info "%-24s = %s" "bge_mpfr_suffix_opts" "${bge_mpfr_suffix_opts}"
log_info "%-24s = %s" "bge_mpc_url" "${bge_mpc_url}"
log_info "%-24s = %s" "bge_mpc_suffix_opts" "${bge_mpc_suffix_opts}"
log_info "%-24s = %s" "bge_isl_url" "${bge_isl_url}"
log_info "%-24s = %s" "bge_isl_suffix_opts" "${bge_isl_suffix_opts}"
log_info "%-24s = %s" "bge_binutils_gdb_ver" "${bge_binutils_gdb_ver}"
log_info "%-24s = %s" "bge_binutils_gdb_suffix_opts" "${bge_binutils_gdb_suffix_opts}"
log_info "%-24s = %s" "bge_toolchain_name" "${bge_toolchain_name}"
log_info "========== 【构建gcc 全局选项 BGE CONFIG】 =========="
}
bge_refresh_ver(){
bge_gcc_ver="releases/gcc-15.1.0"
bge_gcc_suffix_opts=""
bge_gmp_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/gmp/gmp-6.2.0.tar.xz"
bge_gmp_suffix_opts=""
bge_mpfr_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/mpfr/mpfr-4.2.2.tar.xz"
bge_mpfr_suffix_opts=""
bge_mpc_url="https://mirrors.tuna.tsinghua.edu.cn/gnu/mpc/mpc-1.3.1.tar.gz"
bge_mpc_suffix_opts=""
bge_isl_url="https://libisl.sourceforge.io/isl-0.26.tar.xz"
bge_isl_suffix_opts=""
bge_binutils_gdb_ver="binutils-2_46"
bge_binutils_gdb_suffix_opts=""
}
bge_init_params() {
# 必选项
bge_install_prefix="${_ae_root_}/env/local_gcc_15_1_0"
# 平台选项
local local_triplet
detect_platform_triplet local_triplet local_triplet_no_vendor
bge_build="${local_triplet}"
bge_host="${local_triplet}"
bge_target="${local_triplet}"
bge_source_sysroot=""
bge_sysroot_use_mode="link"
# 1阶段gcc
bge_stage1=0
# url选项集合
bge_refresh_ver
}
# 初始化参数值
bge_init_params
bge_check_params() {
bge_dump_config
[[ -z "$bge_build" || -z "$bge_host" || -z "$bge_target" ]] && log_error "ERROR:build/host/target not fully set" && exit 1
log_info "原始 build:$bge_build host:$bge_host target:$bge_target"
check_value_in_range bge_sysroot_use_mode "link" "copy"
check_value_in_range bge_stage1 "1" "0"
local b_full="${b_cpu}-${b_vendor}-${b_os}-${b_abi}"
local h_full="${h_cpu}-${h_vendor}-${h_os}-${h_abi}"
local t_full="${t_cpu}-${t_vendor}-${t_os}-${t_abi}"
local b_core="${b_cpu}_${b_os}_${b_abi}"
local h_core="${h_cpu}_${h_os}_${h_abi}"
local t_core="${t_cpu}_${t_os}_${t_abi}"
log_info "核心 build:$b_core host:$h_core target:$t_core"
if [[ "$b_full" == "$h_full" && "$h_full" == "$t_full" ]]; then
bge_build_mode="native"
elif [[ "$b_core" == "$h_core" && "$h_core" == "$t_core" ]]; then
bge_build_mode="pseudo_native"
elif [[ "$b_full" == "$h_full" ]]; then
bge_build_mode="cross"
else
bge_build_mode="canadian_stage3"
fi
# check_and_create_dir "$bge_source_sysroot"
if [[ "$bge_build_mode" == "cross" ||
"$bge_build_mode" == "canadian_stage3" ]]; then
[[ "$bge_sysroot_use_mode" != "link" && "$bge_sysroot_use_mode" != "copy" ]] && log_error "ERROR:invalid bge_sysroot_use_mode:$bge_sysroot_use_mode" && exit 5
fi
log_info "$bge_build_mode check ok!"
}
bge_setup_canadian_compilers() {
[[ "$bge_build_mode" == "canadian_stage3" ]] || return 0
local build_cc
local build_cxx
build_cc="$(command -v gcc)"
build_cxx="$(command -v g++)"
export CC="${bge_host}-gcc"
export CXX="${bge_host}-g++"
export CC_FOR_BUILD="$build_cc"
export CXX_FOR_BUILD="$build_cxx"
export CPP_FOR_BUILD="$build_cc -E"
export CC_FOR_TARGET="${bge_target}-gcc"
export CXX_FOR_TARGET="${bge_target}-g++"
log_info "canadian compilers: build=%s host=%s target=%s" "$CC_FOR_BUILD" "$CC" "$CC_FOR_TARGET"
}
# sudo apt install flex bison git依赖
build_gcc_ex() {
bge_check_params
bge_setup_canadian_compilers
local sysroot=""
if [[ "$bge_build_mode" == "cross" ||
"$bge_build_mode" == "canadian_stage3" ]]; then
local base="${bge_install_prefix}/${bge_target}"
sysroot="${base}/sysroot"
exec_record_fast_fail "rm -rf \"${sysroot}\""
exec_record_fast_fail "mkdir -p \"$(dirname "${sysroot}")\""
if [[ "$bge_sysroot_use_mode" == "link" ]]; then
local relative_path
relative_path=$(realpath --relative-to="$(dirname "${sysroot}")" "${bge_source_sysroot}")
log_info "sysroot: ${sysroot} bge_source_sysroot:${bge_source_sysroot} relative_path:${relative_path}"
exec_record_fast_fail "ln -s \"${relative_path}\" \"${sysroot}\""
elif [[ "$bge_sysroot_use_mode" == "copy" ]]; then
exec_record_fast_fail "mkdir -p \"${sysroot}\""
exec_record_fast_fail "cp -a \"${bge_source_sysroot}/.\" \"${sysroot}/\""
fi
fi
if [[ "$bge_build_mode" == "pseudo_native" ]]; then
sysroot="/"
fi
(
#GMP(大整数库)在 MinGW/Windows host 场景下的一个明确限制:
# 在同一次构建里同时启用 --enable-shared 和 --enable-static
# 会导致生成的 gmp.h 内容不一致(静态库和 DLL 的 gmp.h 有不同的导出宏/声明),
# 所以 configure 直接拒绝
local build_host="--build=$bge_build --host=$bge_host"
local prefix_opt="--prefix=$bge_install_prefix"
#local lib_opts="--disable-static --enable-shared"
local lib_opts="--enable-static --disable-shared"
configure_gnu_zip "$bge_gmp_url" "$prefix_opt $build_host $lib_opts $bge_gmp_suffix_opts"
exec_record_fast_fail "make -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
configure_gnu_zip "$bge_mpfr_url" "$prefix_opt $build_host --with-gmp=$bge_install_prefix $lib_opts $bge_mpfr_suffix_opts"
exec_record_fast_fail "make -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
configure_gnu_zip "$bge_mpc_url" "$prefix_opt $build_host --with-gmp=$bge_install_prefix --with-mpfr=$bge_install_prefix $lib_opts $bge_mpc_suffix_opts"
exec_record_fast_fail "make -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
configure_gnu_zip "$bge_isl_url" "$prefix_opt $build_host --with-gmp-prefix=$bge_install_prefix $lib_opts $bge_isl_suffix_opts"
exec_record_fast_fail "make -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
# --disable-doc 或者 apt install texinfo
local binutils_opts
binutils_opts="$prefix_opt --build=$bge_build --host=$bge_host --target=$bge_target \
--with-gmp=$bge_install_prefix --with-mpfr=$bge_install_prefix --with-mpc=$bge_install_prefix --with-isl=$bge_install_prefix \
--disable-doc --disable-werror --disable-nls"
if [[
"$bge_build_mode" == "cross" ||
"$bge_build_mode" == "canadian_stage3" ]] \
; then
local ld_search_path="=/lib:=/lib64:=/usr/lib:=/usr/lib64:=/lib/${bge_target}:=/usr/lib/${bge_target}"
# 这里=会在后续的链接器选项中变成sysroot
binutils_opts="${binutils_opts} --with-sysroot=$sysroot --with-lib-path=${ld_search_path}"
fi
if [[ "$bge_build_mode" == "pseudo_native" ]]; then
binutils_opts="${binutils_opts} --with-sysroot=$sysroot"
fi
binutils_opts="${binutils_opts} $bge_binutils_gdb_suffix_opts"
# configure_gnu_zip "$bge_binutils_url" "$binutils_opts"
local src_dir
ensure_repo_version src_dir "binutils-gdb" "$bge_binutils_gdb_ver"
configure_gnu "${src_dir}" "$binutils_opts"
exec_record_fast_fail "make -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
)
# --disable-multiarch \ 怎么确定sysroot是不是 multiarch 布局
check_ret_exit "构建gcc_rely_${bge_build_mode}失败!"
(
# 这里不能加" 加了的话 eval 执行不对了 寻找匹配的“"”时遇到了未预期的文件结束符
local gcc_opts=" \
--prefix=$bge_install_prefix \
--build=$bge_build --host=$bge_host --target=$bge_target \
--with-gmp=$bge_install_prefix \
--with-mpfr=$bge_install_prefix \
--with-mpc=$bge_install_prefix \
--with-isl=$bge_install_prefix \
"
# if [[ "${h_os}" == "w64" ]]; then
# local exe_dir="${bge_install_prefix}/bin"
# gcc_opts="\
# --libexecdir=\"${exe_dir}/\" \
# ${gcc_opts}"
# log_info "w64 添加库到exe所在目录, 这样不用配置环境变量"
# fi
if [[ "$bge_stage1" == "0" ]]; then
log_info "构建普通gcc,依赖glibc"
gcc_opts="\
--disable-multilib \
--enable-languages=c,c++ \
--enable-shared \
--enable-static \
--disable-werror \
--disable-bootstrap \
--disable-libsanitizer \
--disable-libssp \
${gcc_opts}"
fi
if [[ "$bge_stage1" == "1" ]]; then
log_info "stage1 gcc(不依赖 glibc,用于构建 glibc"
# --enable-shared 这个选项开启 会导致 stage1 链接glibc 所以要关掉
gcc_opts="\
--with-newlib \
--without-headers \
--without-isl \
--enable-initfini-array \
--disable-nls \
--disable-shared \
--enable-static \
--disable-multilib \
--disable-decimal-float \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--disable-bootstrap \
--enable-languages=c,c++ \
${gcc_opts}"
fi
if [[ "$bge_build_mode" == "cross" ||
"$bge_build_mode" == "canadian_stage3" ]]; then
gcc_opts="--with-sysroot=$sysroot ${gcc_opts}"
fi
if [[ "$bge_build_mode" == "pseudo_native" ]]; then
# --with-native-system-header-dir=/usr/include
gcc_opts="--with-sysroot=${sysroot} ${gcc_opts}"
fi
gcc_opts="${gcc_opts} ${bge_gcc_suffix_opts}"
local src_dir
ensure_repo_version src_dir "gcc" "$bge_gcc_ver"
exec_record_fast_fail "rm -rf \"${src_dir}/build\""
cd "${src_dir}" || exit
# 如果启用了这个选项 共有依赖项就会全部失效
#exec_record "./contrib/download_prerequisites"
#export LD_LIBRARY_PATH="${bge_install_prefix}/lib:$LD_LIBRARY_PATH"
configure_gnu "${src_dir}" "$gcc_opts"
if [[ "$bge_stage1" == "0" ]]; then
exec_record_fast_fail "make -j $(nproc)"
#exec_record_fast_fail "make install -j $(nproc)"
exec_record_fast_fail "make install-strip -j $(nproc)"
fi
if [[ "$bge_stage1" == "1" ]]; then
exec_record_fast_fail "make all-gcc -j $(nproc)"
exec_record_fast_fail "make install-gcc -j $(nproc)"
exec_record_fast_fail "make all-target-libgcc -j $(nproc)"
exec_record_fast_fail "make install-target-libgcc -j $(nproc)"
fi
)
check_ret_exit "构建gcc_${bge_build_mode}失败!"
# 创建 cc c++ 软链接, gcc 安装一般不会附带 但是发行版会自己附带来兼容
local gcc_bin="${bge_install_prefix}/bin"
cd "${gcc_bin}"
ln -sf "${bge_target}-gcc" cc
ln -sf "${bge_target}-g++" c++
# 生成cmake 工具链文件
local SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local template="${SCRIPT_DIR}/cmake_template/toolchain_template.cmake"
local cmake_os=""
local cmake_cpu=""
gnu_os_to_cmake_system_name "$t_os" cmake_os
gnu_cpu_to_cmake_system_processor "$t_cpu" cmake_cpu
log_debug "cmake OS -> $cmake_os"
log_debug "cmake CPU -> $cmake_cpu"
local exe shared static prefix
gnu_triple_to_suffixes ${bge_host} exe shared static prefix
template_render_to_file_strict "${template}" "${bge_install_prefix}/${bge_toolchain_name}.cmake" \
CMAKE_SYSTEM_NAME "${cmake_os}" \
CMAKE_SYSTEM_PROCESSOR "${cmake_cpu}" \
exe_suffix "${exe}" \
build "${bge_build}" \
host "${bge_host}" \
target "${bge_target}"
local preset_template="${SCRIPT_DIR}/cmake_template/toolchain_template.json"
template_render_to_file_strict "${preset_template}" "${bge_install_prefix}/preset.json" \
toolchain_name "${bge_toolchain_name}"
}
#https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-15.1.0/gcc-15.1.0.tar.xz
#"15.1.0"
upgrade_local_gcc() {
local ver="$1"
local vendor="$2" # 空字符串就是local_triplet
[[ -z "$ver" ]] && log_error "ERROR:ver required" && exit 1
[[ -z "$_root_" ]] && log_error "ERROR:_root_ not set" && exit 2
local local_triplet local_triplet_no_vendor
detect_platform_triplet local_triplet local_triplet_no_vendor
local new_triplet
if [[ -z "$vendor" ]]; then
new_triplet="$local_triplet"
else
local local_cpu local_vendor local_os local_abi
parse_triplet "$local_triplet" local_cpu local_vendor local_os local_abi
compose_triplet new_triplet "$local_cpu" "$vendor" "$local_os" "$local_abi"
fi
local install_prefix="${_ae_root_}/toolchain/${new_triplet}"
bge_install_prefix="${install_prefix}/$ver"
log_info "bge_install_prefix $bge_install_prefix"
bge_gcc_ver="${ver}"
bge_build="$local_triplet"
bge_host="$local_triplet"
bge_target="$new_triplet"
bge_source_sysroot=""
bge_sysroot_use_mode="link"
build_gcc_ex
}
build_local_local_cross_gcc() {
local target="$1"
local ver="$2"
local source_sysroot="$3"
[[ -z "$target" ]] && log_error "ERROR: target required" && exit 1
[[ -z "$ver" ]] && log_error "ERROR: ver required" && exit 1
[[ -z "$source_sysroot" ]] && log_error "ERROR: source_sysroot required" && exit 1
[[ ! -d "$source_sysroot" ]] && log_error "ERROR: sysroot not found: $source_sysroot" && exit 1
[[ -z "$_root_" ]] && log_error "ERROR:_root_ not set" && exit 2
(
local local_triplet local_triplet_no_vendor
detect_platform_triplet local_triplet local_triplet_no_vendor
local install_prefix="$_root_/gcc/${target}"
bge_install_prefix="${install_prefix}_$ver"
bge_build="$local_triplet"
bge_host="$local_triplet"
bge_target="$target"
bge_source_sysroot="$source_sysroot"
bge_sysroot_use_mode="copy"
bge_gcc_ver="${ver}"
#bge_gcc_ver="https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-$ver/gcc-$ver.tar.xz"
build_gcc_ex
)
check_ret_exit "build_local_local_cross_gcc 编译错误!"
}
return 0