#!/bin/bash set -e # ================================================================== # Версии пакетов # ================================================================== BINUTILS_VER="2.42" GCC_VER="13.4.0" LINUX_VER="4.9.224" UCLIBC_VER="1.0.34" # ================================================================== # Основные параметры тулчейна # ================================================================== TARGET="arm-uclinuxfdpiceabi" SUBARCH="armv7-m" SUBMODE="thumb" TOP="$(pwd)" CONFIGS_DIR="${TOP}/config" BUILD_DIR="${TOP}/build" BUILD_SRC_DIR="${BUILD_DIR}/src" INSTALL_DIR="${TOP}/install" INSTALL_BIN_DIR="${INSTALL_DIR}/bin" KERNEL_SYSROOT_DIR="${INSTALL_DIR}/sysroot" KERNEL_SYSROOT_USR_DIR="${KERNEL_SYSROOT_DIR}/usr" KERNEL_SYSROOT_USR_INCLUDES_DIR="${KERNEL_SYSROOT_USR_DIR}/include" CFLAGS_TOOLSET='-O2' CFLAGS_TARGET='-Os -mthumb' export CFLAGS=$CFLAGS_TOOLSET export CFLAGS_FOR_TARGET=$CFLAGS_TARGET export CXXFLAGS_FOR_TARGET=$CFLAGS_TARGET # ================================================================== # Имена распакованных директорий (обычно совпадают с версией) # ================================================================== SRC_BINUTILS="${BUILD_SRC_DIR}/binutils-${BINUTILS_VER}" SRC_GCC="${BUILD_SRC_DIR}/gcc-${GCC_VER}" SRC_LINUX="${BUILD_SRC_DIR}/linux-${LINUX_VER}" SRC_UCLIBC="${BUILD_SRC_DIR}/uClibc-ng-${UCLIBC_VER}" # ================================================================== echo "== Создание директорий ==" mkdir -p "${KERNEL_SYSROOT_DIR}" "${BUILD_SRC_DIR}" echo "== Распаковка архивов в ${BUILD_SRC_DIR} ==" for f in *.tar.xz; do [ -f "$f" ] || { echo "Нет архивов *.tar.xz в текущей директории!"; exit 1; } echo " * $f" tar -xf "$f" -C "${BUILD_SRC_DIR}" done # ================================================================== # BINUTILS # ================================================================== echo "== Сборка binutils-${BINUTILS_VER} ==" mkdir -p build/binutils && cd build/binutils "${SRC_BINUTILS}/configure" \ --target="${TARGET}" \ --prefix="${INSTALL_DIR}" \ --with-sysroot="${KERNEL_SYSROOT_DIR}" \ --disable-nls \ --without-bugurl \ --disable-werror make -j$(nproc) all make install cd ../../.. # ================================================================== # GCC STAGE 1 (только C, без libc) # ================================================================== echo "== Сборка GCC-${GCC_VER} Stage 1 ==" cd "${SRC_GCC}" ./contrib/download_prerequisites cd ../../.. mkdir -p build/gcc1 && cd build/gcc1 "${SRC_GCC}/configure" \ --target="${TARGET}" \ --prefix="${INSTALL_DIR}" \ --with-arch="${SUBARCH}" \ --with-mode="${SUBMODE}" \ --without-headers \ --with-newlib \ --disable-shared \ --disable-threads \ --disable-libssp \ --disable-libgomp \ --disable-libmudflap \ --enable-languages=c \ --disable-libquadmath \ --disable-multilib \ --without-cloog \ --without-ppl \ --disable-nls \ --disable-libatomic make -j$(nproc) all-gcc make install-gcc make -j$(nproc) all-target-libgcc make install-target-libgcc cd ../../.. # ================================================================== # Linux headers # ================================================================== echo "== Установка заголовков linux-${LINUX_VER} ==" mkdir -p build/kernelheader cd "${SRC_LINUX}" PATH="${INSTALL_BIN_DIR}:${PATH}" \ make ARCH=arm \ INSTALL_HDR_PATH="${KERNEL_SYSROOT_USR_DIR}" \ CROSS_COMPILE="${TARGET}-" \ O="${TOP}/build/kernelheader" \ headers_install cd "${TOP}" # ================================================================== # uClibc-ng # ================================================================== echo "== Сборка uClibc-ng-${UCLIBC_VER} ==" cd "${SRC_UCLIBC}" # Подготовка .config перед сборкой uClibc-ng CONFIG_SRC_FILE="${CONFIGS_DIR}/config-uclib-${UCLIBC_VER}" # Если в TOP существует .config-<версия uclibc>, копируем его if [ -f "${CONFIG_SRC_FILE}" ]; then echo "== Найден ${CONFIG_SRC_FILE}, копирую в .config ==" cp "${CONFIG_SRC_FILE}" .config else echo "== Файл ${CONFIG_SRC_FILE} не найден, используем существующий .config ==" fi # Обновляем путь к заголовкам ядра — сначала удаляем старую строку sed -i '/^KERNEL_HEADERS=/d' .config 2>/dev/null || true # Добавляем новый путь echo "KERNEL_HEADERS=\"${KERNEL_SYSROOT_USR_INCLUDES_DIR}\"" >> .config PATH="${INSTALL_BIN_DIR}:${PATH}" make oldconfig || true PATH="${INSTALL_BIN_DIR}:${PATH}" make -j$(nproc) PATH="${INSTALL_BIN_DIR}:${PATH}" make PREFIX="${KERNEL_SYSROOT_DIR}" install cd "${TOP}" # ================================================================== # GCC FINAL (C + C++) # ================================================================== echo "== Сборка финального GCC-${GCC_VER} (C+C++) ==" mkdir -p build/gcc2 && cd build/gcc2 "${SRC_GCC}/configure" \ --target="${TARGET}" \ --prefix="${INSTALL_DIR}" \ --with-sysroot="${KERNEL_SYSROOT_DIR}" \ --with-arch="${SUBARCH}" \ --with-mode="${SUBMODE}" \ --enable-languages=c,c++ \ --enable-threads=posix \ --enable-fdpic \ --disable-libstdcxx-pch \ --disable-multilib \ --disable-bootstrap \ --disable-libgomp \ --disable-libatomic make -j$(nproc) make install cd "${TOP}" # ================================================================== # Strip и упаковка # ================================================================== echo "== Strip toolchain и упаковка ==" WDIR=$(mktemp -d) trap 'rm -rf "$WDIR"' EXIT cp -a install/* "$WDIR"/ find "$WDIR" -type f -executable -exec strip -p {} \; 2>/dev/null || true tar -C "$WDIR" --owner=0 --group=0 -cJf "toolset-jlv-${SUBARCH}-gcc${GCC_VER}-uclibc${UCLIBC_VER}.tar.xz" . echo "Готово: toolset-jlv-${SUBARCH}-gcc${GCC_VER}-uclibc${UCLIBC_VER}.tar.xz" # ================================================================== # Очистка # ================================================================== echo echo "=== Управление архивами и очистка ===" read -p "Удалить исходники (*.tar.xz)? (y/N): " -n 1 -r REPLY; echo [[ $REPLY =~ ^[Yy]$ ]] && rm -f *.tar.xz && echo "Исходные архивы удалены." read -p "Удалить директории сборки (build/, install/)? (y/N): " -n 1 -r REPLY; echo [[ $REPLY =~ ^[Yy]$ ]] && rm -rf build install && echo "Директории сборки удалены." echo echo "== Сборка полностью завершена! =="