From a0a8188d82a9392d47c9677683cfd5aacfe18674 Mon Sep 17 00:00:00 2001 From: Lucy Date: Mon, 1 Sep 2025 19:57:53 +0200 Subject: [PATCH] gcc --- derivations/cross_toolchain/binutils.nix | 31 +++- derivations/cross_toolchain/gcc.nix | 184 +++++++++++++++++++ derivations/cross_toolchain/glibc.nix | 102 ++++++++++ derivations/cross_toolchain/linuxHeaders.nix | 87 +++++++++ flake.nix | 4 + 5 files changed, 399 insertions(+), 9 deletions(-) create mode 100644 derivations/cross_toolchain/gcc.nix create mode 100644 derivations/cross_toolchain/glibc.nix create mode 100644 derivations/cross_toolchain/linuxHeaders.nix diff --git a/derivations/cross_toolchain/binutils.nix b/derivations/cross_toolchain/binutils.nix index 5730521..8667dfa 100644 --- a/derivations/cross_toolchain/binutils.nix +++ b/derivations/cross_toolchain/binutils.nix @@ -2,6 +2,9 @@ let stdenv = pkgs.stdenv; + name = "binutils"; + version = "2.45"; + nativePackages = with pkgs; [ cmake zlib @@ -9,14 +12,25 @@ let bison ]; - binutilsPkg = stdenv.mkDerivation { - name = "binutils"; - version = "2.45"; + src = pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/${name}/${name}-${version}.tar.xz"; + hash = "sha256-xQwOf5yxiJgOLMl+RTdiaxZyRBgVWH8eq2nSob++9dI="; + }; - src = pkgs.fetchurl { - url = "https://sourceware.org/pub/${name}/releases/${name}-${version}.tar.xz"; - hash = ""; - }; + binutilsPkg = stdenv.mkDerivation { + inherit name version src; + + + /* + Nixpkgs derivations automatically enable a few hardening flags, including some that cause non-literal format strings to become errors. https://nixos.org/manual/nixpkgs/stable/#sec-hardening-in-nixpkgs + + You can disable this particular one with + */ + hardeningDisable = [ "format" ]; + + /* + But really the package author should be notified of the issue, and a patch should be applied. Even if it's clear that it's safe (it's probably not), NixOS is far from the only organization that enables hardening flags like this by default. + */ nativeBuildInputs = [ nativePackages ]; buildInputs = [ ]; @@ -29,8 +43,6 @@ let mkdir -v $LFSTOOLS ''; - - # Using --prefix=$out instead of $LFS/tools. configurePhase = '' echo "Configuring... " echo "Starting config" @@ -65,3 +77,4 @@ let }; in binutilsPkg + diff --git a/derivations/cross_toolchain/gcc.nix b/derivations/cross_toolchain/gcc.nix new file mode 100644 index 0000000..bbf9a9d --- /dev/null +++ b/derivations/cross_toolchain/gcc.nix @@ -0,0 +1,184 @@ +{ pkgs, binutils }: + +let + stdenv = pkgs.stdenv; + + nativePackages = with pkgs; [ + cmake + zlib + bison + ]; + + name = "gcc"; + version = "15.2.0"; + + src = pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/${name}/${name}-${version}/${name}-${version}.tar.xz"; + hash = "sha256-Q4/ZloJrDIJIWinaA6ctcdbjVBqD7HAt9Ccfb+Al0k4="; + }; + + + # Attributes for stdenv.mkDerivation can be found at: + # https://nixos.org/manual/nixpkgs/stable/#sec-tools-of-stdenv + gccPkg = stdenv.mkDerivation { + /* + Nixpkgs derivations automatically enable a few hardening flags, including some that cause non-literal format strings to become errors. https://nixos.org/manual/nixpkgs/stable/#sec-hardening-in-nixpkgs + + You can disable this particular one with + */ + hardeningDisable = [ "format" ]; + + /* + But really the package author should be notified of the issue, and a patch should be applied. Even if it's clear that it's safe (it's probably not), NixOS is far from the only organization that enables hardening flags like this by default. + */ + + + inherit name version src; + + secondarySrcs = [ + (pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/mpfr/mpfr-4.2.2.tar.xz"; + hash = "sha256-tnugOD736KhWNzTi6InvXsPDuJigHQD6CmhprYHGzgE="; + }) + (pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/gmp/gmp-6.3.0.tar.xz"; + hash = "sha256-o8K4AgG4nmhhb0rTC8Zq7kknw85Q4zkpyoGdXENTiJg="; + }) + (pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/mpc/mpc-1.3.1.tar.gz"; + hash = "sha256-q2QkkvXPiCt0qgy3MM1BCoHtzb7IlRg86TDnBsHHWbg="; + }) + ]; + + nativeBuildInputs = nativePackages ++ [ binutils ]; + buildInputs = with pkgs; [ gcc ]; + + prePhases = " + prepEnvironmentPhase "; + + prepEnvironmentPhase = '' + export LFS_TGT=$(uname -m)-lfs-linux-gnu + export BINTOOLS=${binutils} + export LFS=$(pwd) + export LFSTOOLS=$(pwd)/tools + export PATH=$LFSTOOLS/bin:$PATH + export CONFIG_SITE=$LFS/usr/share/config.site + + cp -r $BINTOOLS/* $LFS + chmod -R u+w $LFS + ''; + + # Adding mpc, gmp, and mpfr to gcc source repo. + patchPhase = '' + export SOURCE=/build/$sourceRoot + + for secSrc in $secondarySrcs; do + case $secSrc in + *.xz) + tar -xJf $secSrc -C ../$sourceRoot/ + ;; + *.gz) + tar -xzf $secSrc -C ../$sourceRoot/ + ;; + *) + echo " + Invalid filetype: $secSrc " + exit 1 + ;; + esac + + srcDir=$(echo $secSrc | sed 's/^[^-]*-\(.*\)\.tar.*/\1/') + echo " Src: $srcDir " + newDir=$(echo $secSrc | cut -d'-' -f2) + echo " newDir: $newDir " + mv -v ./$srcDir ./$newDir + done + + sed -e '/m64=/s/lib64/lib/' \ + -e '/m32=/s/m32=.*/m32=..\/lib32$(call if_multiarch,:i386-linux-gnu)/' \ + -i.orig gcc/config/i386/t-linux64 + + sed '/STACK_REALIGN_DEFAULT/s/0/(!TARGET_64BIT \&\& TARGET_SSE)/' \ + -i gcc/config/i386/i386.h + ''; + + # CFLAGS and CXXFLAGS added to dodge string literal warning error. + configurePhase = '' + echo " + Starting + config " + + mkdir -v build + cd build + + mlist=m64,m32 + ../configure \ + --target=$LFS_TGT \ + --prefix=$LFSTOOLS \ + --with-glibc-version=2.42 \ + --with-sysroot=$LFS \ + --with-newlib \ + --without-headers \ + --enable-default-pie \ + --enable-default-ssp \ + --enable-initfini-array \ + --disable-nls \ + --disable-shared \ + --enable-multilib --with-multilib-list=$mlist \ + --disable-decimal-float \ + --disable-threads \ + --disable-libatomic \ + --disable-libgomp \ + --disable-libquadmath \ + --disable-libssp \ + --disable-libvtv \ + --disable-libstdcxx \ + --enable-languages=c,c++ + ''; + + # Path to the GCC source headers is in gcc dir of source folder. + # Concatenate these to create/populate internal limits.h of crossGcc + postInstall = '' + echo " + Install + complete." + + cat $LFS/$sourceRoot/gcc/limitx.h $LFS/$sourceRoot/gcc/glimits.h $LFS/$sourceRoot/gcc/limity.h > \ + $(dirname $($LFSTOOLS/bin/$LFS_TGT-gcc -print-libgcc-file-name))/include/limits.h + + rm -r $LFS/$sourceRoot + cp -rvp $LFS/* $out/ + ''; + + shellHook = '' + echo -e "\033 [ + 31 + mNix + Develop -> $name: Loading...\033 + [ + 0 + m + " + + if [[ "$(basename $(pwd)) + " != "$name + " ]]; then + mkdir -p "$name + " + cd "$name + " + fi + + eval "$prepEnvironmentPhase + " + echo -e "\033 + [ + 36 + mNix + Develop -> $name: Loaded.\033[0m " + echo -e "\033 [ 36 mNix Develop -> Current directory: $(pwd)\033 [ 0 m " + ''; + }; +in +gccPkg + diff --git a/derivations/cross_toolchain/glibc.nix b/derivations/cross_toolchain/glibc.nix new file mode 100644 index 0000000..55881be --- /dev/null +++ b/derivations/cross_toolchain/glibc.nix @@ -0,0 +1,102 @@ +{ pkgs, cc1 }: +let + stdenvNoCC = pkgs.stdenvNoCC; + + nativePackages = with pkgs; [ + bison + texinfo + perl + python3 + ]; + + name = "glibc"; + version = "2.42"; + + + + # Attributes for stdenv.mkDerivation can be found at: + # https://nixos.org/manual/nixpkgs/stable/#sec-tools-of-stdenv + glibcPkg = stdenvNoCC.mkDerivation { + inherit name version; + + src = pkgs.fetchurl { + url = "https://ftp.fau.de/gnu/${name}/${name}-${version}.tar.xz"; + hash = ""; + }; + + patchSrc = pkgs.fetchurl { + url = "https://www.linuxfromscratch.org/patches/lfs/development/${name}-${version}-fhs-1.patch"; + hash = ""; + }; + + + nativeBuildInputs = [ nativePackages ]; + buildInputs = [ cc1 pkgs.gcc ]; + + prePhases = "prepEnvironmentPhase"; + prepEnvironmentPhase = '' + export LFS=$PWD + export LFSTOOLS=$LFS/tools + export LFS_TGT=$(uname -m)-lfs-linux-gnu + export PATH=$LFSTOOLS/bin:$PATH + export PATH=$LFS/usr/bin:$PATH + export CC1=${cc1} + export CONFIG_SITE=$LFS/usr/share/config.site + + cp -r $CC1/* $LFS/ + chmod -R u+w $LFS + + ''; + + configurePhase = '' + echo "rootsbindir=/usr/sbin" > configparms + cp -pv $patchSrc ./glibc.patch + patch -Np1 -i ./glibc.patch + + mkdir -v build + cd build + + ../configure \ + --prefix=/usr \ + --host=$LFS_TGT \ + --build=$(../scripts/config.guess) \ + --enable-kernel=4.19 \ + --with-headers=$LFS/usr/include \ + --disable-nscd \ + libc_cv_slibdir=/usr/lib + ''; + + installFlags = [ "DESTDIR=$(LFS)" ]; + + postInstall = '' + sed '/RTLDLIST=/s@/usr@@g' -i $LFS/usr/bin/ldd + + pushd $LFS/lib + case $(uname -m) in + i?86) ln -sfv ./ld-linux.so.2 ./ld-lsb.so.3 + ;; + x86_64) ln -sfv ./ld-linux-x86-64.so.2 ../lib64 + ln -sfv ./ld-linux-x86-64.so.2 ../lib64/ld-lsb-x86-64.so.3 + ;; + esac + popd + + rm -r $LFS/$sourceRoot + cp -rvp $LFS/* $out/ + ''; + + shellHook = '' + echo -e "\033[31mNix Develop -> $name: Loading...\033[0m" + + if [[ "$(basename $(pwd))" != "$name" ]]; then + mkdir -p "$name" + cd "$name" + fi + + eval "$prepEnvironmentPhase" + echo -e "\033[36mNix Develop -> $name: Loaded.\033[0m" + echo -e "\033[36mNix Develop -> Current directory: $(pwd)\033[0m" + ''; + }; +in +glibcPkg diff --git a/derivations/cross_toolchain/linuxHeaders.nix b/derivations/cross_toolchain/linuxHeaders.nix new file mode 100644 index 0000000..88c272a --- /dev/null +++ b/derivations/cross_toolchain/linuxHeaders.nix @@ -0,0 +1,87 @@ +{ pkgs, cc1 }: +let + nixpkgs = pkgs; + stdenv = nixpkgs.stdenv; + + nativePackages = with pkgs; [ + cmake + zlib + bison + # binutils + ]; + + name = "linux-headers"; + version = "6.17-rc4"; + + headersCCPkgs = stdenv.mkDerivation { + inherit name version; + + src = pkgs.fetchurl { + url = "https://git.kernel.org/torvalds/t/linux-${version}.tar.gz"; + hash = ""; + }; + + nativeBuildInputs = [ nativePackages ]; + buildInputs = [ cc1 ]; + + + prePhases = "prepEnvironmentPhase"; + prepEnvironmentPhase = '' + export LFS=$(pwd) + export LFSTOOLS=$(pwd)/tools + export PATH=$LFSTOOLS/bin:$PATH + export PATH=$LFS/usr/bin:$PATH + export CONFIG_SITE=$LFS/usr/share/config.site + export CC1=${cc1} + + chmod -R u+w ./ + + cp -r $CC1/* $LFS + chmod -R u+w $LFS + + mkdir -vp $LFS/usr/{bin,lib,sbin} $LFS/{etc,var} + + case $(uname -m) in + x86_64) mkdir -pv $LFS/lib64 ;; + esac + ''; + + + configurePhase = '' + echo "Starting config" + make mrproper + + ''; + + buildPhase = '' + make headers + ''; + + installPhase = '' + runHook preInstall + + find ./usr/include -type f ! -name '*.h' -delete + + mkdir $out + cp -rvp ./usr/include $LFS/usr + rm -r $LFS/$sourceRoot + cp -rvp $LFS/* $out/ + + runHook postInstall + ''; + + shellHook = '' + echo -e "\033[31mNix Develop -> $name: Loading...\033[0m" + + if [[ "$(basename $(pwd))" != "$name" ]]; then + mkdir -p "$name" + cd "$name" + fi + + eval "$prepEnvironmentPhase" + echo -e "\033[36mNix Develop -> $name: Loaded.\033[0m" + echo -e "\033[36mNix Develop -> Current directory: $(pwd)\033[0m" + ''; + }; +in +headersCCPkgs diff --git a/flake.nix b/flake.nix index cbc000d..0ba1011 100644 --- a/flake.nix +++ b/flake.nix @@ -17,9 +17,13 @@ # Cross Compilation Toolchain binutilsStage = import ./derivations/cross_toolchain/binutils.nix { pkgs = pkgs; }; + gccStage1 = import ./derivations/cross_toolchain/gcc.nix { pkgs = pkgs; binutils = binutilsStage; }; + linuxHeadersStage = import ./derivations/cross_toolchain/linuxHeaders.nix { pkgs = pkgs; cc1 = linuxHeadersStage; }; in { packages.${system}.crossToolchain = { + linuxHeaders = linuxHeadersStage; + gcc = gccStage1; binutils = binutilsStage; };