#!/bin/bash set -e # ================================================================== # Названия пакетов # ================================================================== PKG_BINUTILS="binutils" PKG_GCC="gcc" PKG_LINUX="linux" PKG_UCLIBC="uClibc-ng" # ================================================================== # Версии пакетов # ================================================================== BINUTILS_VER="2.42" GCC_VER="13.4.0" LINUX_VER="4.9.224" UCLIBC_VER="1.0.55" # ================================================================== # Основные параметры тулчейна # ================================================================== TARGET="arm-uclinuxfdpiceabi" SUBARCH="armv7-m" SUBMODE="thumb" TOP="$(pwd)" CONFIGS_DIR="${TOP}/config" SRC_DIR="${TOP}/src/toolchain" BUILD_DIR="${TOP}/build" BUILD_SRC_DIR="${BUILD_DIR}/src/toolchain" INSTALL_DIR="${BUILD_DIR}/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}/${PKG_BINUTILS}-${BINUTILS_VER}" SRC_GCC="${BUILD_SRC_DIR}/${PKG_GCC}-${GCC_VER}" SRC_LINUX="${BUILD_SRC_DIR}/${PKG_LINUX}-${LINUX_VER}" SRC_UCLIBC="${BUILD_SRC_DIR}/${PKG_UCLIBC}-${UCLIBC_VER}" # ================================================================== echo "== Очистка и создание директорий ==" rm -rf "${BUILD_DIR}" mkdir -p "${KERNEL_SYSROOT_DIR}" "${BUILD_SRC_DIR}" echo "== Распаковка архивов из ${SRC_DIR} в ${BUILD_SRC_DIR} ==" ARCHIVES=( "${SRC_DIR}/${PKG_BINUTILS}-${BINUTILS_VER}.tar.xz" "${SRC_DIR}/${PKG_GCC}-${GCC_VER}.tar.xz" "${SRC_DIR}/${PKG_LINUX}-${LINUX_VER}.tar.xz" "${SRC_DIR}/${PKG_UCLIBC}-${UCLIBC_VER}.tar.xz" ) for f in "${ARCHIVES[@]}"; do if [ ! -f "$f" ]; then echo "Ошибка: архив не найден: $f" exit 1 fi dirname="$(basename "${f%.tar.*}")" if [ -d "${BUILD_SRC_DIR}/${dirname}" ]; then echo " * Пропуск (уже распакован): ${dirname}" continue fi echo " * Распаковка: $(basename "$f")" tar -xf "$f" -C "${BUILD_SRC_DIR}" done # ================================================================== # BINUTILS # ================================================================== echo "== Сборка binutils-${BINUTILS_VER} ==" mkdir -p "${BUILD_DIR}/binutils" && cd "${BUILD_DIR}/binutils" "${SRC_BINUTILS}/configure" \ --target="${TARGET}" \ --prefix="${INSTALL_DIR}" \ --with-sysroot="${KERNEL_SYSROOT_DIR}" \ --disable-nls \ --without-bugurl \ --disable-werror \ MAKEINFO=true make -j$(nproc) MAKEINFO=true all make MAKEINFO=true install cd "${TOP}" # ================================================================== # GCC STAGE 1 (только C, без libc) # ================================================================== echo "== Сборка GCC-${GCC_VER} Stage 1 ==" cd "${SRC_GCC}" ./contrib/download_prerequisites cd "${TOP}" mkdir -p "${BUILD_DIR}/gcc1" && cd "${BUILD_DIR}/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 \ --disable-libitm \ --without-cloog \ --without-ppl \ --disable-nls \ --disable-libatomic \ --disable-tls make -j$(nproc) all-gcc make install-gcc make -j$(nproc) all-target-libgcc make install-target-libgcc cd "${TOP}" # ================================================================== # Linux headers # ================================================================== echo "== Установка заголовков linux-${LINUX_VER} ==" mkdir -p "${BUILD_DIR}/kernelheader" cd "${SRC_LINUX}" PATH="${INSTALL_BIN_DIR}:${PATH}" \ make ARCH=arm \ INSTALL_HDR_PATH="${KERNEL_SYSROOT_USR_DIR}" \ CROSS_COMPILE="${TARGET}-" \ O="${BUILD_DIR}/kernelheader" \ headers_install cd "${TOP}" # ================================================================== # uClibc-ng # ================================================================== echo "== Сборка uClibc-ng-${UCLIBC_VER} ==" cd "${SRC_UCLIBC}" # Подготовка .config перед сборкой uClibc-ng CONFIG_SRC_FILE="${CONFIGS_DIR}/config-${PKG_UCLIBC}-${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_DIR}/gcc2" && cd "${BUILD_DIR}/gcc2" "${SRC_GCC}/configure" \ --target="${TARGET}" \ --prefix="${INSTALL_DIR}" \ --with-sysroot="${KERNEL_SYSROOT_DIR}" \ --with-arch="${SUBARCH}" \ --with-mode="${SUBMODE}" \ --enable-languages=c,c++ \ --disable-threads \ --enable-fdpic \ --disable-libstdcxx-pch \ --disable-libitm \ --disable-multilib \ --disable-bootstrap \ --disable-libgomp \ --disable-libatomic \ --disable-tls make -j$(nproc) make install cd "${TOP}" # ================================================================== # Установка библиотек # ================================================================== ./build-libraries.sh # ================================================================== # Strip и упаковка # ================================================================== echo "== Strip toolchain и упаковка ==" cd "${TOP}" WDIR=$(mktemp -d) trap 'rm -rf "$WDIR"' EXIT cp -a "${INSTALL_DIR}"/* "$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 "Удалить исходники (src/)? (y/N): " -n 1 -r REPLY; echo [[ $REPLY =~ ^[Yy]$ ]] && rm -rf "${SRC_DIR}" && echo "Директория исходников удалена." read -p "Удалить директорию сборки (build/)? (y/N): " -n 1 -r REPLY; echo [[ $REPLY =~ ^[Yy]$ ]] && rm -rf "${BUILD_DIR}" && echo "Директория сборки удалена." echo echo "== Сборка полностью завершена! =="