diff --git a/foundation/src/builders/bash/default.nix b/foundation/src/builders/bash/default.nix index 1909ea0..58646fb 100644 --- a/foundation/src/builders/bash/default.nix +++ b/foundation/src/builders/bash/default.nix @@ -5,18 +5,75 @@ system = config.aux.system; builders = config.aux.foundation.builders; - stage0 = config.aux.foundation.stages.stage0; + stage1 = config.aux.foundation.stages.stage1; in { includes = [ ./boot.nix ]; options.aux.foundation.builders.bash = { - # TODO: Bash builder that isn't boot. + build = lib.options.create { + type = lib.types.function lib.types.package; + description = "Builds a package using the kaem builder."; + }; }; config = { aux.foundation.builders.bash = { + build = lib.modules.overrides.default (settings @ { + name, + script, + meta ? {}, + extras ? {}, + env ? {}, + deps ? {}, + ... + }: let + package = builtins.derivation ( + (builtins.removeAttrs settings ["meta" "extras" "executable" "env" "deps" "script"]) + // env + // { + inherit name system script; + + passAsFile = ["script"]; + + builder = "${stage1.bash.package}/bin/bash"; + + args = [ + "-e" + (builtins.toFile "bash-builder.sh" '' + export CONFIG_SHELL=$SHELL + + # Normalize the NIX_BUILD_CORES variable. The value might be 0, which + # means that we're supposed to try and auto-detect the number of + # available CPU cores at run-time. + NIX_BUILD_CORES="''${NIX_BUILD_CORES:-1}" + if ((NIX_BUILD_CORES <= 0)); then + guess=$(nproc 2>/dev/null || true) + ((NIX_BUILD_CORES = guess <= 0 ? 1 : guess)) + fi + export NIX_BUILD_CORES + + bash -eux $scriptPath + '') + ]; + + SHELL = "${stage1.bash.package}/bin/bash"; + + PATH = lib.paths.bin ( + (deps.build.host or []) + ++ [ + stage1.bash.package + stage1.coreutils.package + ] + ); + } + ); + in + package + // { + inherit meta extras; + }); }; }; } diff --git a/foundation/src/stages/stage1/bash/default.nix b/foundation/src/stages/stage1/bash/default.nix index 4759d02..4f9f3d3 100644 --- a/foundation/src/stages/stage1/bash/default.nix +++ b/foundation/src/stages/stage1/bash/default.nix @@ -4,6 +4,7 @@ }: let cfg = config.aux.foundation.stages.stage1.bash; + 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.bash = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for gnumake."; + }; + + 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; @@ -38,6 +54,74 @@ in { description = "Platforms the package supports."; default.value = ["x86_64-linux" "aarch64-linux" "i686-linux"]; }; + + mainProgram = lib.options.create { + type = lib.types.string; + description = "The main program of the package."; + default.value = "bash"; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.bash = { + version = "5.2.15"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/bash/bash-${cfg.version}.tar.gz"; + sha256 = "132qng0jy600mv1fs95ylnlisx2wavkkgpb19c6kmz7lnmjhjwhk"; + }; + + package = let + patches = [ + # flush output for generated code + ./patches/mksignames-flush.patch + ]; + in + builders.bash.boot.build { + name = "bash-${cfg.version}"; + + meta = cfg.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.coreutils.package + stage1.gnumake.package + stage1.gnupatch.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gnutar.package + stage1.gawk.boot.package + stage1.gzip.package + stage1.diffutils.package + ]; + + script = '' + # Unpack + tar xzf ${cfg.src} + cd bash-${cfg.version} + + # Patch + ${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches} + + # 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} \ + --without-bash-malloc + + # Build + make -j $NIX_BUILD_CORES SHELL=bash + + # Install + make -j $NIX_BUILD_CORES install + ln -s bash $out/bin/sh + ''; + }; }; }; } diff --git a/foundation/src/stages/stage1/bash/patches/mksignames-flush.patch b/foundation/src/stages/stage1/bash/patches/mksignames-flush.patch new file mode 100644 index 0000000..0b0dfe7 --- /dev/null +++ b/foundation/src/stages/stage1/bash/patches/mksignames-flush.patch @@ -0,0 +1,11 @@ +--- a/support/mksignames.c ++++ b/support/mksignames.c +@@ -68,6 +68,7 @@ write_signames (stream) + fprintf (stream, "};\n\n"); + fprintf (stream, "#define initialize_signames()\n\n"); + #endif ++ fflush(stream); + } + + int + diff --git a/foundation/src/stages/stage1/default.nix b/foundation/src/stages/stage1/default.nix index f455088..792f6d7 100644 --- a/foundation/src/stages/stage1/default.nix +++ b/foundation/src/stages/stage1/default.nix @@ -26,6 +26,7 @@ in { ./diffutils ./binutils ./findutils + ./gcc ]; config = { @@ -64,6 +65,10 @@ in { stage1-coreutils = stage1.coreutils.package; stage1-binutils = stage1.binutils.package; stage1-findutils = stage1.findutils.package; + stage1-bash = stage1.bash.package; + + # These packages are built using Bash v5 + stage1-gcc-46 = stage1.gcc.v46.package; }; extras = { diff --git a/foundation/src/stages/stage1/gcc/default.nix b/foundation/src/stages/stage1/gcc/default.nix new file mode 100644 index 0000000..6b6e4be --- /dev/null +++ b/foundation/src/stages/stage1/gcc/default.nix @@ -0,0 +1,44 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.gcc; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + includes = [ + ./v4.6.nix + ]; + + options.aux.foundation.stages.stage1.gcc = { + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "GNU Compiler Collection."; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://gcc.gnu.org"; + }; + + 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 = ["i686-linux"]; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/gcc/patches/no-system-headers.patch b/foundation/src/stages/stage1/gcc/patches/no-system-headers.patch new file mode 100644 index 0000000..09801d3 --- /dev/null +++ b/foundation/src/stages/stage1/gcc/patches/no-system-headers.patch @@ -0,0 +1,12 @@ +--- a/gcc/Makefile.in ++++ b/gcc/Makefile.in +@@ -440,7 +440,7 @@ LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h + LTO_SYMTAB_H = $(srcdir)/../include/lto-symtab.h + + # Default native SYSTEM_HEADER_DIR, to be overridden by targets. +-NATIVE_SYSTEM_HEADER_DIR = /usr/include ++# NATIVE_SYSTEM_HEADER_DIR = /usr/include + # Default cross SYSTEM_HEADER_DIR, to be overridden by targets. + CROSS_SYSTEM_HEADER_DIR = @CROSS_SYSTEM_HEADER_DIR@ + + diff --git a/foundation/src/stages/stage1/gcc/v4.6.nix b/foundation/src/stages/stage1/gcc/v4.6.nix new file mode 100644 index 0000000..b81d893 --- /dev/null +++ b/foundation/src/stages/stage1/gcc/v4.6.nix @@ -0,0 +1,212 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.gcc.v46; + + platform = config.aux.platform; + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.gcc.v46 = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for gcc."; + }; + + 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."; + }; + + cc = { + src = lib.options.create { + type = lib.types.package; + description = "The cc source for the package."; + }; + }; + + gmp = { + src = lib.options.create { + type = lib.types.package; + description = "The gmp source for the package."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of gmp."; + }; + }; + + mpfr = { + src = lib.options.create { + type = lib.types.package; + description = "The mpfr source for the package."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of mpfr."; + }; + }; + + mpc = { + src = lib.options.create { + type = lib.types.package; + description = "The mpc source for the package."; + }; + + version = lib.options.create { + type = lib.types.string; + description = "Version of mpc."; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.gcc.v46 = { + version = "4.6.4"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/gcc/gcc-${cfg.version}/gcc-core-${cfg.version}.tar.gz"; + sha256 = "173kdb188qg79pcz073cj9967rs2vzanyjdjyxy9v0xb0p5sad75"; + }; + + cc = { + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/gcc/gcc-${cfg.version}/gcc-g++-${cfg.version}.tar.gz"; + sha256 = "1fqqk5zkmdg4vmqzdmip9i42q6b82i3f6yc0n86n9021cr7ms2k9"; + }; + }; + + gmp = { + version = "4.3.2"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/gmp/gmp-${cfg.gmp.version}.tar.gz"; + sha256 = "15rwq54fi3s11izas6g985y9jklm3xprfsmym3v1g6xr84bavqvv"; + }; + }; + + mpfr = { + version = "2.4.2"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/mpfr/mpfr-${cfg.mpfr.version}.tar.gz"; + sha256 = "0dxn4904dra50xa22hi047lj8kkpr41d6vb9sd4grca880c7wv94"; + }; + }; + + mpc = { + version = "1.0.3"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/mpc/mpc-${cfg.mpc.version}.tar.gz"; + sha256 = "1hzci2zrrd7v3g1jk35qindq05hbl0bhjcyyisq9z209xb3fqzb1"; + }; + }; + + package = let + patches = [ + # Remove hardcoded NATIVE_SYSTEM_HEADER_DIR + ./patches/no-system-headers.patch + ]; + in + builders.bash.build { + name = "gcc-${cfg.version}"; + + meta = stage1.gcc.meta; + + deps.build.host = [ + stage1.tinycc.musl.compiler.package + stage1.binutils.package + stage1.gnumake.boot.package + stage1.gnupatch.package + stage1.gnused.package + stage1.gnugrep.package + stage1.gawk.boot.package + stage1.diffutils.package + stage1.findutils.package + stage1.gnutar.musl.package + stage1.gzip.package + ]; + + script = '' + # Unpack + tar xzf ${cfg.src} + tar xzf ${cfg.cc.src} + tar xzf ${cfg.gmp.src} + tar xzf ${cfg.mpfr.src} + tar xzf ${cfg.mpc.src} + cd gcc-${cfg.version} + + ln -s ../gmp-${cfg.gmp.version} gmp + ln -s ../mpfr-${cfg.mpfr.version} mpfr + ln -s ../mpc-${cfg.mpc.version} mpc + + # Patch + ${lib.strings.concatMapSep "\n" (file: "patch -Np1 -i ${file}") patches} + + # Configure + export CC="tcc -B ${stage1.tinycc.musl.libs.package}/lib" + export C_INCLUDE_PATH="${stage1.tinycc.musl.libs.package}/include:$(pwd)/mpfr/src" + export CPLUS_INCLUDE_PATH="$C_INCLUDE_PATH" + + # Avoid "Link tests are not allowed after GCC_NO_EXECUTABLES" + export lt_cv_shlibpath_overrides_runpath=yes + export ac_cv_func_memcpy=yes + export ac_cv_func_strerror=yes + + bash ./configure \ + --prefix=$out \ + --build=${platform.build} \ + --host=${platform.host} \ + --with-native-system-header-dir=${stage1.tinycc.musl.libs.package}/include \ + --with-build-sysroot=${stage1.tinycc.musl.libs.package}/include \ + --disable-bootstrap \ + --disable-decimal-float \ + --disable-libatomic \ + --disable-libcilkrts \ + --disable-libgomp \ + --disable-libitm \ + --disable-libmudflap \ + --disable-libquadmath \ + --disable-libsanitizer \ + --disable-libssp \ + --disable-libvtv \ + --disable-lto \ + --disable-lto-plugin \ + --disable-multilib \ + --disable-plugin \ + --disable-threads \ + --enable-languages=c \ + --enable-static \ + --disable-shared \ + --enable-threads=single \ + --disable-libstdcxx-pch \ + --disable-build-with-cxx + + # Build + # FIXME: This throws an error when called with more than a single job core. + # The error is "line 6: 5629 Alarm clock" which seems to be timeout related. + # + # make -j $NIX_BUILD_CORES + make + + # Install + # FIXME: This throws an error when called with more than a single job core. + # The error is "line 6: 5629 Alarm clock" which seems to be timeout related. + # + # make -j $NIX_BUILD_CORES install + make install + ''; + }; + }; + }; +}