From aa49ef89466a6502628ffd2dac6c75188917d6aa Mon Sep 17 00:00:00 2001 From: Jake Hamilton Date: Fri, 7 Jun 2024 01:07:17 -0700 Subject: [PATCH] feat: coreutils, binutils, findutils, diffutils --- .../src/stages/stage1/binutils/default.nix | 146 ++++++++++++++++++ .../binutils/patches/deterministic.patch | 13 ++ .../src/stages/stage1/coreutils/default.nix | 71 +++++++++ foundation/src/stages/stage1/default.nix | 9 ++ .../src/stages/stage1/diffutils/default.nix | 105 +++++++++++++ .../src/stages/stage1/findutils/default.nix | 111 +++++++++++++ foundation/src/stages/stage1/gawk/default.nix | 2 +- foundation/src/stages/stage1/xz/default.nix | 109 +++++++++++++ 8 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 foundation/src/stages/stage1/binutils/default.nix create mode 100644 foundation/src/stages/stage1/binutils/patches/deterministic.patch create mode 100644 foundation/src/stages/stage1/diffutils/default.nix create mode 100644 foundation/src/stages/stage1/findutils/default.nix create mode 100644 foundation/src/stages/stage1/xz/default.nix diff --git a/foundation/src/stages/stage1/binutils/default.nix b/foundation/src/stages/stage1/binutils/default.nix new file mode 100644 index 0000000..fb92b78 --- /dev/null +++ b/foundation/src/stages/stage1/binutils/default.nix @@ -0,0 +1,146 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.binutils; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.binutils = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for binutils."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + + src = lib.options.create { + type = lib.types.package; + description = "Source for the package."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "Tools for manipulating binaries (linker, assembler, etc.)"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/binutils"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.gpl3Plus; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.binutils = { + version = "2.41"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/binutils/binutils-${cfg.version}.tar.xz"; + sha256 = "rppXieI0WeWWBuZxRyPy0//DHAMXQZHvDQFb3wYAdFA="; + }; + + package = let + patches = [ + # Make binutils output deterministic by default. + ./patches/deterministic.patch + ]; + + configureFlags = [ + "--prefix=${builtins.placeholder "out"}" + "--build=${platform.build}" + "--host=${platform.host}" + "--with-sysroot=/" + "--enable-deterministic-archives" + # depends on bison + "--disable-gprofng" + + # Turn on --enable-new-dtags by default to make the linker set + # RUNPATH instead of RPATH on binaries. This is important because + # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime. + "--enable-new-dtags" + + # By default binutils searches $libdir for libraries. This brings in + # libbfd and libopcodes into a default visibility. Drop default lib + # path to force users to declare their use of these libraries. + "--with-lib-path=:" + ]; + in + builders.bash.boot.build { + name = "binutils-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.gnumake.package + stage1.gnupatch.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gnutar.musl.package + stage1.gzip.package + stage1.gawk.package + stage1.diffutils.package + stage1.xz.package + ]; + + script = '' + # Unpack + cp ${cfg.src} binutils.tar.xz + unxz binutils.tar.xz + tar xf binutils.tar + rm binutils.tar + cd binutils-${cfg.version} + + # Patch + ${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches} + sed -i 's|/bin/sh|${stage1.bash.boot.package}/bin/bash|' \ + missing install-sh mkinstalldirs + # see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 + sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh + # alias makeinfo to true + mkdir aliases + ln -s ${stage1.coreutils.package}/bin/true aliases/makeinfo + export PATH="$(pwd)/aliases/:$PATH" + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export AR="tcc -ar" + export lt_cv_sys_max_cmd_len=32768 + export CFLAGS="-D__LITTLE_ENDIAN__=1" + bash ./configure ${builtins.concatStringsSep " " configureFlags} + + # Build + make -j $NIX_BUILD_CORES all-libiberty all-gas all-bfd all-libctf all-zlib all-gprof + make all-ld # race condition on ld/.deps/ldwrite.Po, serialize + make -j $NIX_BUILD_CORES + + # Install + make -j $NIX_BUILD_CORES install + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/binutils/patches/deterministic.patch b/foundation/src/stages/stage1/binutils/patches/deterministic.patch new file mode 100644 index 0000000..5b479ba --- /dev/null +++ b/foundation/src/stages/stage1/binutils/patches/deterministic.patch @@ -0,0 +1,13 @@ +diff -ur orig/binutils-2.23.1/ld/ldlang.c binutils-2.23.1/ld/ldlang.c +--- orig/ld/ldlang.c ++++ new/ld/ldlang.c +@@ -3095,6 +3095,8 @@ + ldfile_output_machine)) + einfo (_("%P%F:%s: can not set architecture: %E\n"), name); + ++ link_info.output_bfd->flags |= BFD_DETERMINISTIC_OUTPUT; ++ + link_info.hash = bfd_link_hash_table_create (link_info.output_bfd); + if (link_info.hash == NULL) + einfo (_("%P%F: can not create hash table: %E\n")); + diff --git a/foundation/src/stages/stage1/coreutils/default.nix b/foundation/src/stages/stage1/coreutils/default.nix index 590bfb9..38a62c1 100644 --- a/foundation/src/stages/stage1/coreutils/default.nix +++ b/foundation/src/stages/stage1/coreutils/default.nix @@ -4,6 +4,7 @@ }: let cfg = config.aux.foundation.stages.stage1.coreutils; + platform = config.aux.platform; builders = config.aux.foundation.builders; stage1 = config.aux.foundation.stages.stage1; @@ -13,6 +14,21 @@ in { ]; options.aux.foundation.stages.stage1.coreutils = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for coreutils-boot."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + + src = lib.options.create { + type = lib.types.package; + description = "Source for the package."; + }; + meta = { description = lib.options.create { type = lib.types.string; @@ -40,4 +56,59 @@ in { }; }; }; + + config = { + aux.foundation.stages.stage1.coreutils = { + version = "9.4"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/coreutils/coreutils-${cfg.version}.tar.gz"; + sha256 = "X2ANkJOXOwr+JTk9m8GMRPIjJlf0yg2V6jHHAutmtzk="; + }; + + package = let + configureFlags = [ + "--prefix=${builtins.placeholder "out"}" + "--build=${platform.build}" + "--host=${platform.host}" + # musl 1.1.x doesn't use 64bit time_t + "--disable-year2038" + # libstdbuf.so fails in static builds + "--enable-no-install-program=stdbuf" + ]; + in + builders.bash.boot.build { + name = "coreutils-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.gnumake.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gawk.package + stage1.gnutar.musl.package + stage1.gzip.package + ]; + + script = '' + # Unpack + tar xzf ${cfg.src} + cd coreutils-${cfg.version} + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export LD=tcc + bash ./configure ${builtins.concatStringsSep " " configureFlags} + + # Build + make -j $NIX_BUILD_CORES AR="tcc -ar" MAKEINFO="true" + + # Install + make -j $NIX_BUILD_CORES install MAKEINFO="true" + ''; + }; + }; + }; } diff --git a/foundation/src/stages/stage1/default.nix b/foundation/src/stages/stage1/default.nix index cb25e2f..f455088 100644 --- a/foundation/src/stages/stage1/default.nix +++ b/foundation/src/stages/stage1/default.nix @@ -22,6 +22,10 @@ in { ./gzip ./musl ./gawk + ./xz + ./diffutils + ./binutils + ./findutils ]; config = { @@ -55,6 +59,11 @@ in { stage1-gnumake = stage1.gnumake.package; stage1-gnutar-musl = stage1.gnutar.musl.package; stage1-gawk = stage1.gawk.package; + stage1-xz = stage1.xz.package; + stage1-diffutils = stage1.diffutils.package; + stage1-coreutils = stage1.coreutils.package; + stage1-binutils = stage1.binutils.package; + stage1-findutils = stage1.findutils.package; }; extras = { diff --git a/foundation/src/stages/stage1/diffutils/default.nix b/foundation/src/stages/stage1/diffutils/default.nix new file mode 100644 index 0000000..01f341d --- /dev/null +++ b/foundation/src/stages/stage1/diffutils/default.nix @@ -0,0 +1,105 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.diffutils; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.diffutils = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for diffutils."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + + src = lib.options.create { + type = lib.types.package; + description = "Source for the package."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "Commands for showing the differences between files (diff, cmp, etc.)"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/diffutils"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.gpl3Only; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.diffutils = { + version = "3.8"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/diffutils/diffutils-${cfg.version}.tar.xz"; + sha256 = "pr3X0bMSZtEcT03mwbdI1GB6sCMa9RiPwlM9CuJDj+w="; + }; + + package = builders.bash.boot.build { + name = "diffutils-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.gnumake.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gnutar.musl.package + stage1.gawk.package + stage1.xz.package + ]; + + script = '' + # Unpack + cp ${cfg.src} diffutils.tar.xz + unxz diffutils.tar.xz + tar xf diffutils.tar + rm diffutils.tar + cd diffutils-${cfg.version} + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export LD=tcc + bash ./configure \ + --prefix=$out \ + --build=${platform.build} \ + --host=${platform.host} + + # Build + make -j $NIX_BUILD_CORES AR="tcc -ar" + + # Install + make -j $NIX_BUILD_CORES install + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/findutils/default.nix b/foundation/src/stages/stage1/findutils/default.nix new file mode 100644 index 0000000..bd0b372 --- /dev/null +++ b/foundation/src/stages/stage1/findutils/default.nix @@ -0,0 +1,111 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.findutils; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.findutils = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for findutils."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + + src = lib.options.create { + type = lib.types.package; + description = "Source for the package."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "GNU Find Utilities, the basic directory searching utilities of the GNU operating system"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/findutils"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.attrs.any; + description = "License for the package."; + default.value = lib.licenses.gpl3Plus; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.findutils = { + version = "4.9.0"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/findutils/findutils-${cfg.version}.tar.xz"; + sha256 = "or+4wJ1DZ3DtxZ9Q+kg+eFsWGjt7nVR1c8sIBl/UYv4="; + }; + + package = builders.bash.boot.build { + name = "findutils-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.gnumake.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gnutar.musl.package + stage1.gawk.package + stage1.xz.package + ]; + + script = '' + # Unpack + cp ${cfg.src} findutils.tar.xz + unxz findutils.tar.xz + tar xf findutils.tar + rm findutils.tar + cd findutils-${cfg.version} + + # Patch + # configure fails to accurately detect PATH_MAX support + sed -i 's/chdir_long/chdir/' gl/lib/save-cwd.c + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export AR="tcc -ar" + export LD=tcc + bash ./configure \ + --prefix=$out \ + --build=${platform.build} \ + --host=${platform.host} + + # Build + make -j $NIX_BUILD_CORES + + # Install + make -j $NIX_BUILD_CORES install + + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/gawk/default.nix b/foundation/src/stages/stage1/gawk/default.nix index 0049c3a..932ad44 100644 --- a/foundation/src/stages/stage1/gawk/default.nix +++ b/foundation/src/stages/stage1/gawk/default.nix @@ -52,7 +52,7 @@ in { platforms = lib.options.create { type = lib.types.list.of lib.types.string; description = "Platforms the package supports."; - default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; + default.value = ["i686-linux"]; }; mainProgram = lib.options.create { diff --git a/foundation/src/stages/stage1/xz/default.nix b/foundation/src/stages/stage1/xz/default.nix new file mode 100644 index 0000000..c25baaa --- /dev/null +++ b/foundation/src/stages/stage1/xz/default.nix @@ -0,0 +1,109 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.xz; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.xz = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for xz."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of the package."; + }; + + src = lib.options.create { + type = lib.types.package; + description = "Source for the package."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "A general-purpose data compression software, successor of LZMA"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://tukaani.org/xz"; + }; + + license = lib.options.create { + # TODO: Add a proper type for licenses. + type = lib.types.list.of lib.types.attrs.any; + description = "License for the package."; + default.value = [ + lib.licenses.gpl2Plus + lib.licenses.lgpl21Plus + ]; + }; + + platforms = lib.options.create { + type = lib.types.list.of lib.types.string; + description = "Platforms the package supports."; + default.value = ["i686-linux"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.xz = { + version = "5.4.3"; + + src = builtins.fetchurl { + url = "https://tukaani.org/xz/xz-${cfg.version}.tar.gz"; + sha256 = "HDguC8Lk4K9YOYqQPdYv/35RAXHS3keh6+BtFSjpt+k="; + }; + + package = builders.bash.boot.build { + name = "xz-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.gnumake.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gnutar.musl.package + stage1.gzip.package + stage1.gawk.boot.package + ]; + + script = '' + # Unpack + tar xzf ${cfg.src} + cd xz-${cfg.version} + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export AR="tcc -ar" + export LD=tcc + bash ./configure \ + --prefix=$out \ + --build=${platform.build} \ + --host=${platform.host} \ + --disable-shared \ + --disable-assembler + + # Build + make -j $NIX_BUILD_CORES + + # Install + make -j $NIX_BUILD_CORES install + + ''; + }; + }; + }; +}