From 097c3dd5b7d0fc09fd6a1fe703b0fddc24e4b3d7 Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Sun, 4 May 2025 14:06:34 +0000 Subject: [PATCH 1/1] initial commit --- LICENSE.txt | 21 ++++ README.md | 33 +++++ "document\360\237\226\211/Readme.org" | 16 +++ env_toolsmith | 11 ++ "script\360\237\226\211/README.org" | 29 +++++ "script\360\237\226\211/build_all.sh" | 47 +++++++ "script\360\237\226\211/build_binutils.sh" | 46 +++++++ .../build_binutils_requisites.sh" | 24 ++++ "script\360\237\226\211/build_gcc_final.sh" | 31 +++++ .../build_gcc_final_requisites.sh" | 46 +++++++ "script\360\237\226\211/build_gcc_stage1.sh" | 69 ++++++++++ .../build_gcc_stage1_requisites.sh" | 28 +++++ "script\360\237\226\211/build_glibc.sh" | 26 ++++ .../build_glibc_headers.sh" | 78 ++++++++++++ .../build_glibc_requisites.sh" | 51 ++++++++ .../build_linux_headers.sh" | 35 ++++++ "script\360\237\226\211/clean_build.sh" | 16 +++ "script\360\237\226\211/clean_dist.sh" | 52 ++++++++ "script\360\237\226\211/clean_source.sh" | 9 ++ .../download_expand_sources.sh" | 92 ++++++++++++++ "script\360\237\226\211/environment.sh" | 119 ++++++++++++++++++ .../prepare_gcc_sources.sh" | 24 ++++ .../prepare_glibc_sources.sh" | 27 ++++ "script\360\237\226\211/setup_project.sh" | 45 +++++++ 24 files changed, 975 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 "document\360\237\226\211/Readme.org" create mode 100644 env_toolsmith create mode 100755 "script\360\237\226\211/README.org" create mode 100755 "script\360\237\226\211/build_all.sh" create mode 100755 "script\360\237\226\211/build_binutils.sh" create mode 100755 "script\360\237\226\211/build_binutils_requisites.sh" create mode 100755 "script\360\237\226\211/build_gcc_final.sh" create mode 100755 "script\360\237\226\211/build_gcc_final_requisites.sh" create mode 100755 "script\360\237\226\211/build_gcc_stage1.sh" create mode 100755 "script\360\237\226\211/build_gcc_stage1_requisites.sh" create mode 100755 "script\360\237\226\211/build_glibc.sh" create mode 100755 "script\360\237\226\211/build_glibc_headers.sh" create mode 100755 "script\360\237\226\211/build_glibc_requisites.sh" create mode 100755 "script\360\237\226\211/build_linux_headers.sh" create mode 100755 "script\360\237\226\211/clean_build.sh" create mode 100755 "script\360\237\226\211/clean_dist.sh" create mode 100755 "script\360\237\226\211/clean_source.sh" create mode 100644 "script\360\237\226\211/download_expand_sources.sh" create mode 100755 "script\360\237\226\211/environment.sh" create mode 100755 "script\360\237\226\211/prepare_gcc_sources.sh" create mode 100755 "script\360\237\226\211/prepare_glibc_sources.sh" create mode 100755 "script\360\237\226\211/setup_project.sh" diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..47a74bc --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Reasoning Technology Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6655a4e --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Standalone GCC Installation with option for RT mods. + +As of 2025-05-04: +* Based on GCC 15.1.0 +* I'm still tweeking the standalone scripts. +* Have not yet integrated any of the RT mods. + +## Standalone build + +For those who desire to watch the chips stand where they may: + +``` +> source env_toolsmith +> ./build_all.sh +``` + +Otherwise read `build_all.sh` and follow the steps. + +Note the file 'script🖉/environnment.sh' for the variables that guide the installation. + +## The `#assign` directive. + +Requires running: + +``` +> source env_toolsmith +> ./apply_RT_assign_directive_mod +> ./build_all.sh +``` + +### License + +The code in this project is released under the **MIT License**, see the LICENSE.text file for details. diff --git "a/document\360\237\226\211/Readme.org" "b/document\360\237\226\211/Readme.org" new file mode 100644 index 0000000..de4df5b --- /dev/null +++ "b/document\360\237\226\211/Readme.org" @@ -0,0 +1,16 @@ + +So this programmer he wanted to add a new directive to gcc. + +So he downloaded gcc sources with the intent to make a modified standalone copy. + +But to do that there had to be headers supplied to by glibc. So he dowloaded that too. + +But to compile gcc required glibc. So he downloaded a compatible version of that too. + +To compile glibc requires a small compile of gcc stage 1. Then one can compile glibc, then compile the final version. And yes, before this binutils must be compiled, apparently using the system's C compiler. + +Ah but to compile gcc stage1 requires glibc headers, so that is built before stage1 gcc, which is built before glibc, which is built before gcc. + +Alas but to compile the glibc heder bootstrap requires having the Linux kernel headers ... + +There was an old lady who swallowed a fly. I don't know why she ... diff --git a/env_toolsmith b/env_toolsmith new file mode 100644 index 0000000..7c40a62 --- /dev/null +++ b/env_toolsmith @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +script_afp=$(realpath "${BASH_SOURCE[0]}") +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + echo "$script_afp:: This script must be sourced, not executed." + exit 1 +fi + +export ROOT=$(dirname "$script_afp") +export SCRIPT_DIR="$ROOT"/script🖉 + +cd "$SCRIPT_DIR" diff --git "a/script\360\237\226\211/README.org" "b/script\360\237\226\211/README.org" new file mode 100755 index 0000000..233a35d --- /dev/null +++ "b/script\360\237\226\211/README.org" @@ -0,0 +1,29 @@ + +# Scripts for building standalone gcc + +The scripts here will build a standalone gcc along with version compatible tools. + +There is a lot more to a gcc than one might imagine. It was developed as though an integral part of Unix. Hence, the standalone build has top level directories with many things in them, in parallel to the top level directories a person would find on a Unix system. + +## .gitignore + +* If there is no top level `.gitignore`, `setup_project.sh` will create one. +* The synthesized `.gitignore` references itself, so it will not get checked in. +* No script, including`clean_dist.sh`, will delete an existing `.gitignore`. + +## Clean + +* clean_build.sh - for saving space after the build is done. The build scripts are idempotent, so in an ideal world this need not be run to do a rebuild. + +* clean_dist.sh - with on exception, this will delete everything that was synthesized. The one exception is that .gitignore is moved to the tmp directory so as to preserve any changes a user might have been made, and the contents of the tmp directory are not removed. + +* clean_tmp.sh - wipes clean all contents of the temporary directory. + +## Setup + +* setup_project.sh - makes the directory structure for the build, creates a `tmp/` directory under the project. If it does not already exist, creates a .gitignore file with all the created directories listed. + +## Download + +* download_upstream_sources.sh - goes to the Internet, fetches all the sources that have not already been fetched. Then expands the sources into the proper sub-directory under `source/1. + diff --git "a/script\360\237\226\211/build_all.sh" "b/script\360\237\226\211/build_all.sh" new file mode 100755 index 0000000..dbe0b24 --- /dev/null +++ "b/script\360\237\226\211/build_all.sh" @@ -0,0 +1,47 @@ +#!/bin/bash +set -euo pipefail + +echo "loading environment" +source "$SCRIPT_DIR/environment.sh" + + + +echo "cleaning ..." + # will force download of sources: + # bash "$SCRIPT_DIR/clean_dist.sh" + + bash "$SCRIPT_DIR/clean_build.sh" + +echo "setting up the project ..." + bash "$SCRIPT_DIR/make_project_structure.sh" + +echo "downloading and expanding upstream sources" + bash "SCRIPT_DIR/download_expand_sources.sh" + +echo "building binutils" +bash "$SCRIPT_DIR/build_binutils_requisites.sh" +bash "$SCRIPT_DIR/build_binutils.sh" + +echo "Step 3: glibc headers installed" +# These provide just enough to bootstrap GCC Stage 1 +bash "$SCRIPT_DIR/build_linux_headers.sh" +bash "$SCRIPT_DIR/prepare_glibc_sources.sh" +bash "$SCRIPT_DIR/build_glibc_headers.sh" + + +echo "Step 4: GCC Stage 1" +bash "$SCRIPT_DIR/build_gcc_stage1_requisites.sh" +bash "$SCRIPT_DIR/build_gcc_stage1.sh" + +echo "Step 5: Build glibc (full libc build)" +bash "$SCRIPT_DIR/build_glibc_requisites.sh" +bash "$SCRIPT_DIR/build_glibc.sh" + + +echo "Step 6: Final GCC" +bash "$SCRIPT_DIR/build_gcc_final_requisites.sh" +bash "$SCRIPT_DIR/build_gcc_final.sh" + + +echo "🎉 Toolchain build complete!" +"$TOOLCHAIN/bin/gcc" --version diff --git "a/script\360\237\226\211/build_binutils.sh" "b/script\360\237\226\211/build_binutils.sh" new file mode 100755 index 0000000..114bc94 --- /dev/null +++ "b/script\360\237\226\211/build_binutils.sh" @@ -0,0 +1,46 @@ +#!/bin/bash +set -euo pipefail + +# Load shared environment +source "$(dirname "$0")/environment.sh" + +mkdir -p "$BINUTILS_SRC" +pushd "$BINUTILS_SRC" + +if [ ! -f "$BINUTILS_TARBALL" ]; then + echo "⤵️ Downloading $BINUTILS_TARBALL..." + curl -LO "$BINUTILS_URL" +else + echo "✅ $BINUTILS_TARBALL already exists. Skipping download." +fi + +if [ ! -f configure ]; then + echo "📦 Extracting binutils..." + tar -xzf "$BINUTILS_TARBALL" --strip-components=1 +else + echo "✅ Binutils source already extracted." +fi + +popd + +mkdir -p "$BINUTILS_BUILD" +pushd "$BINUTILS_BUILD" + +"$BINUTILS_SRC/configure" \ + --prefix="$TOOLCHAIN" \ + --with-sysroot="$SYSROOT" \ + --disable-nls \ + --disable-werror \ + --disable-multilib \ + --enable-deterministic-archives \ + --enable-plugins \ + --with-lib-path="$SYSROOT/lib:$SYSROOT/usr/lib" + +$MAKE +$MAKE install + +[[ -x "$TOOLCHAIN/bin/ld" ]] && echo "✅ Binutils installed in $TOOLCHAIN/bin" || { + echo "❌ Binutils install incomplete"; exit 1; +} + +popd diff --git "a/script\360\237\226\211/build_binutils_requisites.sh" "b/script\360\237\226\211/build_binutils_requisites.sh" new file mode 100755 index 0000000..7a3e116 --- /dev/null +++ "b/script\360\237\226\211/build_binutils_requisites.sh" @@ -0,0 +1,24 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "📦 Checking prerequisites for binutils (bootstrap)..." + +required_tools=(gcc g++ make curl tar xz) +missing=() + +for tool in "${required_tools[@]}"; do + if ! type -P "$tool" &>/dev/null; then + missing+=("$tool") + fi +done + +if (( ${#missing[@]} )); then + echo "❌ Missing required tools: ${missing[*]}" + exit 1 +fi + +echo -e "✅ All required tools found: ${required_tools[*]}" + + diff --git "a/script\360\237\226\211/build_gcc_final.sh" "b/script\360\237\226\211/build_gcc_final.sh" new file mode 100755 index 0000000..1e6ca88 --- /dev/null +++ "b/script\360\237\226\211/build_gcc_final.sh" @@ -0,0 +1,31 @@ +#!/bin/bash +set -euo pipefail + +# Load environment +source "$(dirname "$0")/environment.sh" + +echo "🔧 Starting final GCC build..." + +mkdir -p "$GCC_BUILD_FINAL" +pushd "$GCC_BUILD_FINAL" + +"$GCC_SRC/configure" \ + --prefix="$TOOLCHAIN" \ + --with-sysroot="$SYSROOT" \ + --with-native-system-header-dir=/usr/include \ + --target="$TARGET" \ + --enable-languages=c,c++ \ + --enable-threads=posix \ + --enable-shared \ + --disable-nls \ + --disable-multilib \ + --disable-bootstrap \ + --disable-libsanitizer \ + $CONFIGURE_FLAGS + +$MAKE +$MAKE install + +popd + +echo "✅ Final GCC installed to $TOOLCHAIN/bin" diff --git "a/script\360\237\226\211/build_gcc_final_requisites.sh" "b/script\360\237\226\211/build_gcc_final_requisites.sh" new file mode 100755 index 0000000..5d36697 --- /dev/null +++ "b/script\360\237\226\211/build_gcc_final_requisites.sh" @@ -0,0 +1,46 @@ +#!/bin/bash +set -euo pipefail + +# Load shared environment +source "$(dirname "$0")/environment.sh" + +echo "📦 Checking prerequisites for final GCC..." + +# Required host tools +required_tools=(gcc g++ make curl tar gawk bison flex) +missing_tools=() + +for tool in "${required_tools[@]}"; do + if ! type -P "$tool" > /dev/null; then + missing_tools+=("$tool") + fi +done + +if (( ${#missing_tools[@]} )); then + echo "❌ Missing required tools: ${missing_tools[*]}" + exit 1 +fi + +# Check for libc headers and startup objects in sysroot +required_headers=("$SYSROOT/include/stdio.h") +required_crt_objects=( + "$SYSROOT/lib/crt1.o" + "$SYSROOT/lib/crti.o" + "$SYSROOT/lib/crtn.o" +) + +for hdr in "${required_headers[@]}"; do + if [ ! -f "$hdr" ]; then + echo "❌ C library header missing: $hdr" + exit 1 + fi +done + +for obj in "${required_crt_objects[@]}"; do + if [ ! -f "$obj" ]; then + echo "❌ Startup object missing: $obj" + exit 1 + fi +done + +echo "✅ Prerequisites for final GCC met." diff --git "a/script\360\237\226\211/build_gcc_stage1.sh" "b/script\360\237\226\211/build_gcc_stage1.sh" new file mode 100755 index 0000000..2aae2c7 --- /dev/null +++ "b/script\360\237\226\211/build_gcc_stage1.sh" @@ -0,0 +1,69 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "🔧 Starting stage 1 GCC build (native layout)..." + +# 🧼 Clean optionally if forced +if [[ "${CLEAN_STAGE1:-0}" == "1" ]]; then + echo "🧹 Forcing rebuild: cleaning $GCC_BUILD_STAGE1" + rm -rf "$GCC_BUILD_STAGE1" +fi + +mkdir -p "$GCC_BUILD_STAGE1" +pushd "$GCC_BUILD_STAGE1" + +# 🛠️ Configure only if not yet configured +if [[ ! -f Makefile ]]; then + echo "⚙️ Configuring GCC stage 1..." + "$GCC_SRC/configure" \ + --prefix="$TOOLCHAIN" \ + --with-sysroot="$SYSROOT" \ + --with-build-sysroot="$SYSROOT" \ + --with-native-system-header-dir=/include \ + --enable-languages=c \ + --disable-nls \ + --disable-shared \ + --disable-threads \ + --disable-libatomic \ + --disable-libgomp \ + --disable-libquadmath \ + --disable-libssp \ + --disable-multilib \ + --disable-bootstrap \ + --disable-libstdcxx \ + --disable-fixincludes \ + --without-headers \ + --with-newlib +else + echo "✅ GCC already configured, skipping." +fi + +# 🧾 Ensure proper sysroot handling for internal libgcc +export CFLAGS_FOR_TARGET="--sysroot=$SYSROOT" +export CXXFLAGS_FOR_TARGET="--sysroot=$SYSROOT" +export CPPFLAGS_FOR_TARGET="--sysroot=$SYSROOT" +export CFLAGS="--sysroot=$SYSROOT" +export CXXFLAGS="--sysroot=$SYSROOT" + +# 🏗️ Build only if not built +if [[ ! -x "$TOOLCHAIN/bin/gcc" ]]; then + echo "⚙️ Building GCC stage 1..." + make -j"$(nproc)" all-gcc all-target-libgcc + + echo "📦 Installing GCC stage 1 to $TOOLCHAIN" + make install-gcc install-target-libgcc +else + echo "✅ GCC stage 1 already installed at $TOOLCHAIN/bin/gcc, skipping build." +fi + +popd + +# ✅ Final check +if [[ ! -x "$TOOLCHAIN/bin/gcc" ]]; then + echo "❌ Stage 1 GCC not found at $TOOLCHAIN/bin/gcc — build may have failed." + exit 1 +fi + +echo "✅ Stage 1 GCC successfully installed in $TOOLCHAIN/bin" diff --git "a/script\360\237\226\211/build_gcc_stage1_requisites.sh" "b/script\360\237\226\211/build_gcc_stage1_requisites.sh" new file mode 100755 index 0000000..3098e0f --- /dev/null +++ "b/script\360\237\226\211/build_gcc_stage1_requisites.sh" @@ -0,0 +1,28 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "📦 Checking prerequisites for stage 1 GCC (bootstrap)..." + +required_tools=(gcc g++ make tar gawk bison flex) +missing=() + +for tool in "${required_tools[@]}"; do + if ! type -P "$tool" &>/dev/null; then + missing+=("$tool") + fi +done + +if (( ${#missing[@]} )); then + echo "❌ Missing required tools: ${missing[*]}" + exit 1 +fi + +if [ ! -d "$GCC_SRC" ]; then + echo "❌ GCC source not found at $GCC_SRC" + echo "💡 You may need to run: prepare_gcc_sources.sh" + exit 1 +fi + +echo "✅ Prerequisites for stage 1 GCC met." diff --git "a/script\360\237\226\211/build_glibc.sh" "b/script\360\237\226\211/build_glibc.sh" new file mode 100755 index 0000000..652ebc3 --- /dev/null +++ "b/script\360\237\226\211/build_glibc.sh" @@ -0,0 +1,26 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "🔧 Building full glibc..." + +mkdir -p "$GLIBC_BUILD" +pushd "$GLIBC_BUILD" + +"$GLIBC_SRC/configure" \ + --prefix=/usr \ + --host="$TARGET" \ + --build="$(gcc -dumpmachine)" \ + --with-headers="$SYSROOT/usr/include" \ + --disable-multilib \ + --enable-static \ + --enable-shared \ + libc_cv_slibdir="/usr/lib" + +$MAKE +DESTDIR="$SYSROOT" $MAKE install + +popd + +echo "✅ Full glibc installed in $SYSROOT" diff --git "a/script\360\237\226\211/build_glibc_headers.sh" "b/script\360\237\226\211/build_glibc_headers.sh" new file mode 100755 index 0000000..67e6b59 --- /dev/null +++ "b/script\360\237\226\211/build_glibc_headers.sh" @@ -0,0 +1,78 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "📚 Building glibc headers..." + +# 🧹 Clean previous build artifacts to ensure idempotence +echo "🧼 Cleaning glibc build directory: $GLIBC_BUILD" +rm -rf "$GLIBC_BUILD" +mkdir -p "$GLIBC_BUILD" + +pushd "$GLIBC_BUILD" + +# 🏗️ Configure glibc for headers-only installation +echo "⚙️ Configuring glibc headers install..." +"$GLIBC_SRC/configure" \ + --prefix=/usr \ + --with-headers="$SYSROOT/usr/include" \ + --disable-multilib \ + --enable-static \ + --disable-shared \ + libc_cv_slibdir="/usr/lib" + +# 📥 Install headers only +echo "🛠️ Installing glibc headers to sysroot..." +make install-headers -j"$(nproc)" DESTDIR="$SYSROOT" + +# 📎 Verify critical header files and directories were installed +echo "📦 Verifying installed files..." + +required_headers=( + "$SYSROOT/usr/include/gnu/libc-version.h" + "$SYSROOT/usr/include/stdio.h" + "$SYSROOT/usr/include/unistd.h" +) + +missing_files=() +for header in "${required_headers[@]}"; do + if [[ ! -f "$header" ]]; then + missing_files+=("$header") + fi +done + +if (( ${#missing_files[@]} > 0 )); then + echo "❌ Missing required glibc headers:" + printf ' %s\n' "${missing_files[@]}" + exit 1 +fi + +# 📦 Verify the expected directory structure +if [[ ! -d "$SYSROOT/usr/include" ]]; then + echo "❌ Expected include directory not found: $SYSROOT/usr/include" + exit 1 +fi + +if [[ ! -d "$SYSROOT/usr/lib" ]]; then + echo "❌ Expected lib directory not found: $SYSROOT/usr/lib" + exit 1 +fi + +# 📚 Additional verification: check for key startup files +startup_files=( + "$SYSROOT/usr/lib/crt1.o" + "$SYSROOT/usr/lib/crti.o" + "$SYSROOT/usr/lib/crtn.o" +) + +for file in "${startup_files[@]}"; do + if [[ ! -f "$file" ]]; then + echo "❌ Missing startup file: $file" + exit 1 + fi +done + +popd + +echo "✅ glibc headers successfully installed to $SYSROOT/usr/include" diff --git "a/script\360\237\226\211/build_glibc_requisites.sh" "b/script\360\237\226\211/build_glibc_requisites.sh" new file mode 100755 index 0000000..0d25cf0 --- /dev/null +++ "b/script\360\237\226\211/build_glibc_requisites.sh" @@ -0,0 +1,51 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "📦 Checking prerequisites for glibc..." + +required_tools=(gcc make curl tar perl python3 gawk bison) +missing_tools=() + +for tool in "${required_tools[@]}"; do + if ! command -v "$tool" > /dev/null; then + missing_tools+=("$tool") + fi +done + +if (( ${#missing_tools[@]} )); then + echo "❌ Missing required tools:" + printf ' %s\n' "${missing_tools[@]}" + exit 1 +fi + +# Check that expected headers exist +glibc_headers=( + "$SYSROOT/usr/include/stdio.h" + "$SYSROOT/usr/include/unistd.h" +) + +# Check that expected startup objects exist +startup_objects=( + "$SYSROOT/usr/lib/crt1.o" + "$SYSROOT/usr/lib/crti.o" + "$SYSROOT/usr/lib/crtn.o" +) + +missing_files=() +for f in "${glibc_headers[@]}" "${startup_objects[@]}"; do + if [ ! -f "$f" ]; then + missing_files+=("$f") + fi +done + +if (( ${#missing_files[@]} )); then + echo "❌ Missing required files in sysroot:" + printf ' %s\n' "${missing_files[@]}" + echo + echo "Hint: these files should have been generated by build_glibc_headers.sh" + exit 1 +fi + +echo "✅ All prerequisites for glibc are met and sysroot is correctly populated." diff --git "a/script\360\237\226\211/build_linux_headers.sh" "b/script\360\237\226\211/build_linux_headers.sh" new file mode 100755 index 0000000..0e739e4 --- /dev/null +++ "b/script\360\237\226\211/build_linux_headers.sh" @@ -0,0 +1,35 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +echo "📦 Preparing Linux kernel headers for glibc and GCC..." + +mkdir -p "$LINUX_SRC" +pushd "$LINUX_SRC" + +if [ ! -f "$LINUX_TARBALL" ]; then + echo "⤵️ Downloading Linux $LINUX_VER headers..." + curl -LO "$LINUX_URL" +else + echo "✅ Kernel tarball already exists." +fi + +if [ ! -f Makefile ]; then + echo "📂 Extracting kernel sources..." + tar -xf "$LINUX_TARBALL" --strip-components=1 +else + echo "✅ Kernel source already extracted." +fi + +$MAKE mrproper +$MAKE headers_install ARCH=x86_64 INSTALL_HDR_PATH="$SYSROOT/usr" + +# Optional: check for successful header installation +if [[ ! -f "$SYSROOT/usr/include/linux/version.h" ]]; then + echo "❌ Kernel headers not found at expected location." + exit 1 +fi + +popd +echo "✅ Linux headers installed to $SYSROOT/usr/include" diff --git "a/script\360\237\226\211/clean_build.sh" "b/script\360\237\226\211/clean_build.sh" new file mode 100755 index 0000000..d239cef --- /dev/null +++ "b/script\360\237\226\211/clean_build.sh" @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +# Clean the build directories listed in BUILD_DIR_LISTECTORY_LIST +echo "🧹 Cleaning build directories..." + +for dir in "${BUILD_DIR_LIST[@]}"; do + if [[ -d "$dir" ]]; then + echo "rm -rf $dir" + rm -rf "$dir" + fi +done + +echo "✅ Build directories cleaned." diff --git "a/script\360\237\226\211/clean_dist.sh" "b/script\360\237\226\211/clean_dist.sh" new file mode 100755 index 0000000..33ef605 --- /dev/null +++ "b/script\360\237\226\211/clean_dist.sh" @@ -0,0 +1,52 @@ +#!/bin/bash +set -euo pipefail + +echo "removing: build, source, upstream, and project directories" + +source "$(dirname "$0")/environment.sh" + +# Remove build +# + "./clean_build.sh" + ! ! rmdir "$BUILD_DIR" >& /dev/null && echo "rmdir $BUILD_DIR" + +# Remove source +# + for dir in "${SOURCE_DIR_LIST[@]}"; do + if [[ -d "$dir" ]]; then + echo "rm -r $dir" + rm -r "$dir" + fi + done + ! ! rmdir "$SRC" >& /dev/null && echo "rmdir $SRC" + +# Remove upstream +# + # walk the UPSTREAM_TARBALL_LIST triples + i=0 + while [ $i -lt ${#UPSTREAM_TARBALL_LIST[@]} ]; do + tarball="${UPSTREAM_TARBALL_LIST[$i]}" + # skip URL at index i+1 + dir="${UPSTREAM_TARBALL_LIST[$((i+2))]}" + + tarball_path="$dir/$tarball" + if [[ -f "$tarball_path" ]]; then + echo "rm $tarball_path" + rm "$tarball_path" + fi + + i=$((i + 3)) + done + ! ! rmdir "$UPSTREAM" >& /dev/null && echo "rmdir $UPSTREAM" + + +# Remove project directories +# + for dir in "${PROJECT_SUBDIR_LIST[@]}" "${PROJECT_DIR_LIST[@]}"; do + if [[ -d "$dir" ]]; then + echo "rm -rf $dir" + rm -rf "$dir" + fi + done + +echo "✅ clean_dist.sh" diff --git "a/script\360\237\226\211/clean_source.sh" "b/script\360\237\226\211/clean_source.sh" new file mode 100755 index 0000000..dab2dee --- /dev/null +++ "b/script\360\237\226\211/clean_source.sh" @@ -0,0 +1,9 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +# Clean source expansions (but keep tarballs) +rm -rf "$LINUX_SRC" "$BINUTILS_SRC" "$GCC_SRC" "$GLIBC_SRC" + +echo "✅ Cleared source expansions: $LINUX_SRC, $BINUTILS_SRC, $GCC_SRC, $GLIBC_SRC" diff --git "a/script\360\237\226\211/download_expand_sources.sh" "b/script\360\237\226\211/download_expand_sources.sh" new file mode 100644 index 0000000..173cbaa --- /dev/null +++ "b/script\360\237\226\211/download_expand_sources.sh" @@ -0,0 +1,92 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +# 🛠️ Function to check if the internet is accessible +check_internet_connection() { + echo "🌐 Checking internet connection..." + if curl -s --head http://google.com | head -n 1 | grep "HTTP/1.1 200 OK" > /dev/null; then + echo "✅ Internet is reachable." + else + echo "❌ No internet connection detected. Proceeding with caution..." + fi +} + +# 🏰 Function to check if the server for the URL is reachable +check_server_reachability() { + local url=$1 + echo "🌍 Checking if the server $url is reachable..." + if curl -s --head "$url" | head -n 1 | grep "HTTP/1.1 200 OK" > /dev/null; then + echo "✅ Server $url is reachable." + else + echo "❌ Cannot reach server $url. Proceeding with download attempt anyway..." + fi +} + +# 🏰 Function to check if file already exists in UPSTREAM +check_file_exists() { + local file=$1 + if [[ -f "$UPSTREAM/$file" ]]; then + echo "⚡ $file already exists in $UPSTREAM, skipping download." + return 0 # File exists, so skip download + else + return 1 # File doesn't exist, needs to be downloaded + fi +} + +# 🛡️ Function to download a file from a URL +download_file() { + local file=$1 + local url=$2 + + echo "📥 Downloading $file..." + curl -LO "$url" + + if [[ -f "$file" ]]; then + echo "✅ Successfully downloaded $file." + else + echo "❌ Error downloading $file. Continuing with next source." + fi +} + +# 🌍 Main Function to download all sources +fetch_sources() { + echo "🧙‍♂️ Fetching legendary sources for the build..." + + # Check for internet connection first + check_internet_connection + + # Define source list (version-controlled) + sources=( + "$LINUX_TARBALL:$LINUX_URL" + "$BINUTILS_TARBALL:$BINUTILS_URL" + "$GCC_TARBALL:$GCC_REPO" # Special case for Git repo + "$GLIBC_TARBALL:$GLIBC_URL" + ) + + for source in "${sources[@]}"; do + IFS=":" read -r tarball url <<< "$source" + + if check_file_exists "$tarball"; then + continue # Skip if file already exists + fi + + # Check if we can reach the server before attempting download + check_server_reachability "$url" + + # Special case for Git-based source (GCC) + if [[ "$tarball" == *"gcc"* ]]; then + echo "⚡ Fetching GCC source from Git repo: $GCC_REPO" + git clone --branch "$GCC_BRANCH" "$GCC_REPO" "$UPSTREAM/gcc-$GCC_VER" + echo "✅ GCC source fetched from Git." + else + download_file "$tarball" "$url" + fi + done + + echo "🛠️ All sources fetched and ready for build!" +} + +# Start the fetching process +fetch_sources diff --git "a/script\360\237\226\211/environment.sh" "b/script\360\237\226\211/environment.sh" new file mode 100755 index 0000000..0379c3f --- /dev/null +++ "b/script\360\237\226\211/environment.sh" @@ -0,0 +1,119 @@ +# === environment.sh === +# Source this file in each build script to ensure consistent paths and settings + +echo "ROOT: $ROOT" +cd $SCRIPT_DIR + +#-------------------------------------------------------------------------------- +# tool versions + + export LINUX_VER=6.8 + export BINUTILS_VER=2.42 + export GCC_VER=15.1.0 + export GLIBC_VER=2.39 + +#-------------------------------------------------------------------------------- +# project structure + + # temporary directory + export TMPDIR="$ROOT/tmp" + + # Project directories + export SYSROOT="$ROOT/sysroot" + export TOOLCHAIN="$ROOT/toolchain" + export BUILD_DIR="$ROOT/build" + export LOGDIR="$ROOT/log" + export UPSTREAM="$ROOT/upstream" + + # Synthesized directory lists + PROJECT_DIR_LIST=( + "$LOGDIR" + "$SYSROOT" "$TOOLCHAIN" "$BUILD_DIR" + "$UPSTREAM" + ) + # list these in the order they can be deleted + PROJECT_SUBDIR_LIST=( + "$SYSROOT/usr/lib" + "$SYSROOT/lib" + "$SYSROOT/usr/include" + ) + + # Source directories + export SRC=$ROOT/source + export LINUX_SRC="$SRC/linux-$LINUX_VER" + export BINUTILS_SRC="$SRC/binutils-$BINUTILS_VER" + export GCC_SRC="$SRC/gcc-$GCC_VER" + export GLIBC_SRC="$SRC/glibc-$GLIBC_VER" + SOURCE_DIR_LIST=( + "$LINUX_SRC" + "$BINUTILS_SRC" + "$GCC_SRC" + "$GLIBC_SRC" + ) + + # Build directories + export BINUTILS_BUILD="$BUILD_DIR/binutils" + export GCC_BUILD_STAGE1="$BUILD_DIR/gcc-stage1" + export GCC_BUILD_FINAL="$BUILD_DIR/gcc-final" + export GLIBC_BUILD="$BUILD_DIR/glibc" + BUILD_DIR_LIST=( + "$BINUTILS_BUILD" + "$GCC_BUILD_STAGE1" + "$GCC_BUILD_FINAL" + "$GLIBC_BUILD" + ) + +#-------------------------------------------------------------------------------- +# upstream -> local stuff + + # see top of this file for the _VER variables + + # Tarballs + export LINUX_TARBALL="linux-${LINUX_VER}.tar.xz" + export BINUTILS_TARBALL="binutils-${BINUTILS_VER}.tar.gz" + export GLIBC_TARBALL="glibc-${GLIBC_VER}.tar.gz" + + # Tarball Download Info (Name, URL, Destination Directory) + export UPSTREAM_TARBALL_LIST=( + "$LINUX_TARBALL" + "https://cdn.kernel.org/pub/linux/kernel/v6.x/$LINUX_TARBALL" + "$ROOT/linux-$LINUX_VER" + + "$BINUTILS_TARBALL" + "https://ftp.gnu.org/gnu/binutils/$BINUTILS_TARBALL" + "$ROOT/binutils-$BINUTILS_VER" + + "$GLIBC_TARBALL" + "https://ftp.gnu.org/gnu/libc/$GLIBC_TARBALL" + "$ROOT/glibc-$GLIBC_VER" + ) + + # Git Repositories (URL, Branch, Destination Directory) + export GCC_REPO="git://gcc.gnu.org/git/gcc.git" + export GCC_BRANCH="releases/gcc-15" + + # Git Repo Info: Repository URL, Branch, Destination Directory + export UPSTREAM_GIT_REPO_LIST=( + + "$GCC_REPO" + "$GCC_BRANCH" + "$ROOT/gcc-$GCC_VER" + + #currently there is no second repo + ) + + + +#-------------------------------------------------------------------------------- +# tools + + # machine target + export HOST=$(gcc -dumpmachine) + + export MAKE_JOBS=$(nproc) + export MAKE="make -j$MAKE_JOBS" + + # Compiler path prefixes + export CC_FOR_BUILD=$(command -v gcc) + export CXX_FOR_BUILD=$(command -v g++) + diff --git "a/script\360\237\226\211/prepare_gcc_sources.sh" "b/script\360\237\226\211/prepare_gcc_sources.sh" new file mode 100755 index 0000000..d769c93 --- /dev/null +++ "b/script\360\237\226\211/prepare_gcc_sources.sh" @@ -0,0 +1,24 @@ +#!/bin/bash +set -euo pipefail +source "$(dirname "$0")/environment.sh" + +mkdir -p "$GCC_SRC" +pushd "$GCC_SRC" + +if [ ! -d .git ]; then + echo "⤵️ Cloning GCC source..." + git clone "$GCC_REPO" "$GCC_SRC" + git checkout -b RT_mods origin/"$GCC_BRANCH" +else + echo "✅ GCC repository already exists." + git fetch origin + if git show-ref --quiet refs/heads/RT_mods; then + git checkout RT_mods + else + git checkout -b RT_mods origin/"$GCC_BRANCH" + fi +fi + +./contrib/download_prerequisites + +popd diff --git "a/script\360\237\226\211/prepare_glibc_sources.sh" "b/script\360\237\226\211/prepare_glibc_sources.sh" new file mode 100755 index 0000000..6f287c5 --- /dev/null +++ "b/script\360\237\226\211/prepare_glibc_sources.sh" @@ -0,0 +1,27 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +mkdir -p "$GLIBC_SRC" +pushd "$GLIBC_SRC" + +if [ ! -f "$GLIBC_TARBALL" ]; then + echo "⤵️ Downloading glibc $GLIBC_VER..." + curl -LO "$GLIBC_URL" +else + echo "✅ $GLIBC_TARBALL already exists." +fi + +if [ ! -f configure ]; then + echo "📦 Extracting glibc $GLIBC_VER..." + tar -xzf "$GLIBC_TARBALL" --strip-components=1 + if [[ ! -f configure || ! -d elf ]]; then + echo "❌ glibc extraction failed." + exit 1 + fi +else + echo "✅ glibc source already extracted." +fi + +popd diff --git "a/script\360\237\226\211/setup_project.sh" "b/script\360\237\226\211/setup_project.sh" new file mode 100755 index 0000000..31516dc --- /dev/null +++ "b/script\360\237\226\211/setup_project.sh" @@ -0,0 +1,45 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/environment.sh" + +# Create top-level project directories +for dir in "${PROJECT_DIR_LIST[@]}"; do + echo "mkdir -p $dir" + mkdir -p "$dir" +done + +# Create subdirectories within SYSROOT +for subdir in "${PROJECT_SUBDIR_LIST[@]}"; do + echo "mkdir -p $subdir" + mkdir -p "$subdir" +done + +# Ensure TMPDIR exists and add .gitignore +if [[ ! -d "$TMPDIR" ]]; then + echo "mkdir -p $TMPDIR" + mkdir -p "$TMPDIR" + + echo "echo $TMPDIR/ > $TMPDIR/.gitignore" + echo "$TMPDIR/" > "$TMPDIR/.gitignore" +else + echo "⚠️ TMPDIR already exists" +fi + +# Create root-level .gitignore if missing +if [[ -f "$ROOT/.gitignore" ]]; then + echo "⚠️ $ROOT/.gitignore already exists" +else + echo "create $ROOT/.gitignore" + { + echo "# Ignore synthesized top-level directories" + for dir in "${PROJECT_DIR_LIST[@]}"; do + rel_path="${dir#$ROOT/}" + echo "/$rel_path" + done + echo "# Ignore synthesized files" + echo "/.gitignore" + } > "$ROOT/.gitignore" +fi + +echo "✅ setup_project.sh" -- 2.20.1