#!/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的gcc,0代表是普通的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