From b99c63a123e2253253b66d3aecf305cc1b6d8db5 Mon Sep 17 00:00:00 2001 From: Jake Hamilton Date: Thu, 6 Jun 2024 18:03:49 -0700 Subject: [PATCH] feat: add coreutils and stage1 bash --- foundation/src/stages/stage1/bash/boot.nix | 162 ++++++++++++++++++ foundation/src/stages/stage1/bash/default.nix | 43 +++++ .../src/stages/stage1/coreutils/boot.nix | 138 +++++++++++++++ .../src/stages/stage1/coreutils/default.nix | 43 +++++ foundation/src/stages/stage1/default.nix | 4 + 5 files changed, 390 insertions(+) create mode 100644 foundation/src/stages/stage1/bash/boot.nix create mode 100644 foundation/src/stages/stage1/bash/default.nix create mode 100644 foundation/src/stages/stage1/coreutils/boot.nix create mode 100644 foundation/src/stages/stage1/coreutils/default.nix diff --git a/foundation/src/stages/stage1/bash/boot.nix b/foundation/src/stages/stage1/bash/boot.nix new file mode 100644 index 0000000..589ed49 --- /dev/null +++ b/foundation/src/stages/stage1/bash/boot.nix @@ -0,0 +1,162 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.bash.boot; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.bash.boot = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for bash-boot."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "GNU Bourne-Again Shell, the de facto standard shell on Linux"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/bash"; + }; + + 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"]; + }; + }; + + 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."; + }; + }; + + config = { + aux.foundation.stages.stage1.bash.boot = { + version = "2.05b"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/bash/bash-${cfg.version}.tar.gz"; + sha256 = "1r1z2qdw3rz668nxrzwa14vk2zcn00hw7mpjn384picck49d80xs"; + }; + + package = let + # Thanks to the live-bootstrap project! + # See https://github.com/fosslinux/live-bootstrap/blob/1bc4296091c51f53a5598050c8956d16e945b0f5/sysa/bash-2.05b/bash-2.05b.kaem + liveBootstrap = "https://github.com/fosslinux/live-bootstrap/raw/1bc4296091c51f53a5598050c8956d16e945b0f5/sysa/bash-2.05b"; + + main_mk = builtins.fetchurl { + url = "${liveBootstrap}/mk/main.mk"; + sha256 = "0hj29q3pq3370p18sxkpvv9flb7yvx2fs96xxlxqlwa8lkimd0j4"; + }; + + common_mk = builtins.fetchurl { + url = "${liveBootstrap}/mk/common.mk"; + sha256 = "09rigxxf85p2ybnq248sai1gdx95yykc8jmwi4yjx389zh09mcr8"; + }; + + builtins_mk = builtins.fetchurl { + url = "${liveBootstrap}/mk/builtins.mk"; + sha256 = "0939dy5by1xhfmsjj6w63nlgk509fjrhpb2crics3dpcv7prl8lj"; + }; + + patches = [ + # mes libc does not have locale support + (builtins.fetchurl { + url = "${liveBootstrap}/patches/mes-libc.patch"; + sha256 = "0zksdjf6zbb3p4hqg6plq631y76hhhgab7kdvf7cnpk8bcykn12z"; + }) + # int name, namelen; is wrong for mes libc, it is char* name, so we modify tinycc + # to reflect this. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/tinycc.patch"; + sha256 = "042d2kr4a8klazk1hlvphxr6frn4mr53k957aq3apf6lbvrjgcj2"; + }) + # add ifdef's for features we don't want + (builtins.fetchurl { + url = "${liveBootstrap}/patches/missing-defines.patch"; + sha256 = "1q0k1kj5mrvjkqqly7ki5575a5b3hy1ywnmvhrln318yh67qnkj4"; + }) + # mes libc + setting locale = not worky + (builtins.fetchurl { + url = "${liveBootstrap}/patches/locale.patch"; + sha256 = "1p1q1slhafsgj8x4k0dpn9h6ryq5fwfx7dicbbxhldbw7zvnnbx9"; + }) + # We do not have /dev at this stage of the bootstrap, including /dev/tty + (builtins.fetchurl { + url = "${liveBootstrap}/patches/dev-tty.patch"; + sha256 = "1315slv5f7ziajqyxg4jlyanf1xwd06xw14y6pq7xpm3jzjk55j9"; + }) + ]; + in + builders.kaem.build { + name = "bash-${cfg.version}"; + + meta = cfg.meta; + src = cfg.src; + + deps.build.host = [ + stage1.tinycc.mes.compiler.package + stage1.gnumake.package + stage1.gnupatch.package + stage1.coreutils.boot.package + ]; + + script = '' + # Unpack + ungz --file ${cfg.src} --output bash.tar + untar --file bash.tar + rm bash.tar + cd bash-${cfg.version} + + # Patch + ${lib.strings.concatMapSep "\n" (file: "patch -Np0 -i ${file}") patches} + + # Configure + cp ${main_mk} Makefile + cp ${builtins_mk} builtins/Makefile + cp ${common_mk} common.mk + touch config.h + touch include/version.h + touch include/pipesize.h + + # Build + make \ + CC="tcc -B ${stage1.tinycc.mes.libs.package}/lib" \ + mkbuiltins + cd builtins + make \ + CC="tcc -B ${stage1.tinycc.mes.libs.package}/lib" \ + libbuiltins.a + cd .. + make CC="tcc -B ${stage1.tinycc.mes.libs.package}/lib" + + # Install + install -D bash ''${out}/bin/bash + ln -s bash ''${out}/bin/sh + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/bash/default.nix b/foundation/src/stages/stage1/bash/default.nix new file mode 100644 index 0000000..4759d02 --- /dev/null +++ b/foundation/src/stages/stage1/bash/default.nix @@ -0,0 +1,43 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.bash; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + includes = [ + ./boot.nix + ]; + + options.aux.foundation.stages.stage1.bash = { + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "GNU Bourne-Again Shell, the de facto standard shell on Linux"; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/bash"; + }; + + 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"]; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/coreutils/boot.nix b/foundation/src/stages/stage1/coreutils/boot.nix new file mode 100644 index 0000000..7792c9a --- /dev/null +++ b/foundation/src/stages/stage1/coreutils/boot.nix @@ -0,0 +1,138 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.coreutils.boot; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.coreutils.boot = { + 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."; + }; + }; + + config = { + aux.foundation.stages.stage1.coreutils.boot = { + version = "5.0"; + + src = builtins.fetchurl { + url = "https://ftpmirror.gnu.org/coreutils/coreutils-${cfg.version}.tar.gz"; + sha256 = "10wq6k66i8adr4k08p0xmg87ff4ypiazvwzlmi7myib27xgffz62"; + }; + + package = let + # Thanks to the live-bootstrap project! + # See https://github.com/fosslinux/live-bootstrap/blob/a8752029f60217a5c41c548b16f5cdd2a1a0e0db/sysa/coreutils-5.0/coreutils-5.0.kaem + liveBootstrap = "https://github.com/fosslinux/live-bootstrap/raw/a8752029f60217a5c41c548b16f5cdd2a1a0e0db/sysa/coreutils-5.0"; + + makefile = builtins.fetchurl { + url = "${liveBootstrap}/mk/main.mk"; + sha256 = "0njg4xccxfqrslrmlb8ls7h6hlnfmdx42nvxwmca8flvczwrplfd"; + }; + + patches = [ + # modechange.h uses functions defined in sys/stat.h, so we need to move it to + # after sys/stat.h include. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/modechange.patch"; + sha256 = "04xa4a5w2syjs3xs6qhh8kdzqavxnrxpxwyhc3qqykpk699p3ms5"; + }) + # mbstate_t is a struct that is required. However, it is not defined by mes libc. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/mbstate.patch"; + sha256 = "0rz3c0sflgxjv445xs87b83i7gmjpl2l78jzp6nm3khdbpcc53vy"; + }) + # strcoll() does not exist in mes libc, change it to strcmp. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/ls-strcmp.patch"; + sha256 = "0lx8rz4sxq3bvncbbr6jf0kyn5bqwlfv9gxyafp0541dld6l55p6"; + }) + # getdate.c is pre-compiled from getdate.y + # At this point we don't have bison yet and in any case getdate.y does not + # compile when generated with modern bison. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/touch-getdate.patch"; + sha256 = "1xd3z57lvkj7r8vs5n0hb9cxzlyp58pji7d335snajbxzwy144ma"; + }) + # touch: add -h to change symlink timestamps, where supported + (builtins.fetchurl { + url = "${liveBootstrap}/patches/touch-dereference.patch"; + sha256 = "0wky5r3k028xwyf6g6ycwqxzc7cscgmbymncjg948vv4qxsxlfda"; + }) + # strcoll() does not exist in mes libc, change it to strcmp. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/expr-strcmp.patch"; + sha256 = "19f31lfsm1iwqzvp2fyv97lmqg4730prfygz9zip58651jf739a9"; + }) + # strcoll() does not exist in mes libc, change it to strcmp. + # hard_LC_COLLATE is used but not declared when HAVE_SETLOCALE is unset. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/sort-locale.patch"; + sha256 = "0bdch18mpyyxyl6gyqfs0wb4pap9flr11izqdyxccx1hhz0a2i6c"; + }) + # don't assume fopen cannot return stdin or stdout. + (builtins.fetchurl { + url = "${liveBootstrap}/patches/uniq-fopen.patch"; + sha256 = "0qs6shyxl9j4h34v5j5sgpxrr4gjfljd2hxzw416ghwc3xzv63fp"; + }) + ]; + in + builders.kaem.build { + name = "coreutils-boot-${cfg.version}"; + + meta = stage1.coreutils.meta; + + deps.build.host = [ + stage1.tinycc.mes.compiler.package + stage1.gnumake.package + stage1.gnupatch.package + ]; + + script = '' + # Unpack + ungz --file ${cfg.src} --output coreutils.tar + untar --file coreutils.tar + rm coreutils.tar + cd coreutils-${cfg.version} + + # Patch + ${lib.strings.concatMapSep "\n" (file: "patch -Np0 -i ${file}") patches} + + # Configure + catm config.h + cp lib/fnmatch_.h lib/fnmatch.h + cp lib/ftw_.h lib/ftw.h + cp lib/search_.h lib/search.h + rm src/dircolors.h + + # Build + make -f ${makefile} \ + CC="tcc -B ${stage1.tinycc.mes.libs.package}/lib" \ + PREFIX=''${out} + + # Check + ./src/echo "Hello coreutils!" + + # Install + ./src/mkdir -p ''${out}/bin + make -f ${makefile} install PREFIX=''${out} + + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/coreutils/default.nix b/foundation/src/stages/stage1/coreutils/default.nix new file mode 100644 index 0000000..590bfb9 --- /dev/null +++ b/foundation/src/stages/stage1/coreutils/default.nix @@ -0,0 +1,43 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.coreutils; + + builders = config.aux.foundation.builders; + + stage1 = config.aux.foundation.stages.stage1; +in { + includes = [ + ./boot.nix + ]; + + options.aux.foundation.stages.stage1.coreutils = { + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "The GNU Core Utilities."; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/coreutils"; + }; + + 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"]; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/default.nix b/foundation/src/stages/stage1/default.nix index b136e05..b97be73 100644 --- a/foundation/src/stages/stage1/default.nix +++ b/foundation/src/stages/stage1/default.nix @@ -13,6 +13,8 @@ in { ./tinycc ./gnupatch ./gnumake + ./coreutils + ./bash ]; config = { @@ -29,6 +31,8 @@ in { stage1-tinycc-mes-libs = stage1.tinycc.mes.libs.package; stage1-gnupatch = stage1.gnupatch.package; stage1-gnumake = stage1.gnumake.package; + stage1-coreutils-boot = stage1.coreutils.boot.package; + stage1-bash-boot = stage1.bash.boot.package; }; extras = {