From 0ff2902587298e6c43e0eabbd2f6a200766d84a7 Mon Sep 17 00:00:00 2001 From: Jake Hamilton Date: Wed, 5 Jun 2024 15:16:52 -0700 Subject: [PATCH] feat: add mes, mes-libs, and nyacc --- foundation/flake.nix | 8 + foundation/src/builders/file/text/default.nix | 9 +- foundation/src/exports/default.nix | 39 +- foundation/src/stages/stage1/default.nix | 19 +- foundation/src/stages/stage1/mes/compiler.nix | 109 ++ .../src/stages/stage1/mes/create-sources.sh | 99 ++ foundation/src/stages/stage1/mes/default.nix | 27 +- foundation/src/stages/stage1/mes/libs.nix | 238 ++++ foundation/src/stages/stage1/mes/sources.nix | 1060 +++++++++++++++++ .../src/stages/stage1/nyacc/default.nix | 3 +- foundation/src/system/default.nix | 1 + 11 files changed, 1589 insertions(+), 23 deletions(-) create mode 100644 foundation/src/stages/stage1/mes/compiler.nix create mode 100755 foundation/src/stages/stage1/mes/create-sources.sh create mode 100644 foundation/src/stages/stage1/mes/libs.nix create mode 100644 foundation/src/stages/stage1/mes/sources.nix diff --git a/foundation/flake.nix b/foundation/flake.nix index e8c5694..16e5550 100644 --- a/foundation/flake.nix +++ b/foundation/flake.nix @@ -19,6 +19,14 @@ # "aarch64-darwin" ]; in { + extras = let + result = lib.modules.run { + modules = + builtins.attrValues modules; + }; + in + result.config.exports.resolved.extras; + packages = forEachSystem ( system: let result = lib.modules.run { diff --git a/foundation/src/builders/file/text/default.nix b/foundation/src/builders/file/text/default.nix index 88f6e4c..f8c35d5 100644 --- a/foundation/src/builders/file/text/default.nix +++ b/foundation/src/builders/file/text/default.nix @@ -24,7 +24,6 @@ in { extras ? {}, ... }: let - source = builtins.toFile "source" contents; script = '' target=''${out}''${destination} @@ -33,17 +32,19 @@ in { mkdir -p ''${out}''${destinationDir} '' + '' - cp ${source} ''${target} + cp ''${contentsPath} ''${target} '' + lib.strings.when isExecutable '' chmod 555 ''${target} ''; package = builtins.derivation ( - (builtins.removeAttrs settings ["meta" "extras" "contents" "executable" "isExecutable"]) + (builtins.removeAttrs settings ["meta" "extras" "executable" "isExecutable"]) // { - inherit name system destination; + inherit name system destination contents; destinationDir = builtins.dirOf destination; + passAsFile = ["contents"]; + builder = "${stage0.kaem.package}/bin/kaem"; args = [ diff --git a/foundation/src/exports/default.nix b/foundation/src/exports/default.nix index 902bce8..9093897 100644 --- a/foundation/src/exports/default.nix +++ b/foundation/src/exports/default.nix @@ -8,31 +8,40 @@ type = lib.types.attrs.of lib.types.package; }; + + extras = lib.options.create { + default.value = {}; + type = lib.types.attrs.any; + }; }; in { options = { exports = { - inherit (options) packages; + inherit (options) packages extras; resolved = { - inherit (options) packages; + inherit (options) packages extras; }; }; }; config = { - exports.resolved = - builtins.mapAttrs ( - name: value: - lib.attrs.filter - ( - name: value: - if value ? meta && value.meta ? platforms - then builtins.elem config.aux.system value.meta.platforms - else true - ) - value - ) - (builtins.removeAttrs config.exports ["resolved"]); + exports.resolved = { + packages = + builtins.mapAttrs ( + name: value: + lib.attrs.filter + ( + name: value: + if value ? meta && value.meta ? platforms + then builtins.elem config.aux.system value.meta.platforms + else true + ) + value + ) + config.exports.packages; + + extras = config.exports.extras; + }; }; } diff --git a/foundation/src/stages/stage1/default.nix b/foundation/src/stages/stage1/default.nix index 7157d33..c25a027 100644 --- a/foundation/src/stages/stage1/default.nix +++ b/foundation/src/stages/stage1/default.nix @@ -3,16 +3,31 @@ config, }: let cfg = config.aux.foundation.stages.stage1; + + stage1 = config.aux.foundation.stages.stage1; in { includes = [ ./nyacc - # ./mes + ./mes ]; config = { exports = { packages = { - stage1-nyacc = config.aux.foundation.stages.stage1.nyacc.package; + stage1-nyacc = stage1.nyacc.package; + stage1-mes = stage1.mes.compiler.package; + stage1-mes-libs = stage1.mes.libs.package; + }; + + extras = { + stage1 = { + mes = { + src = stage1.mes.src; + libs = { + prefix = stage1.mes.libs.prefix; + }; + }; + }; }; }; }; diff --git a/foundation/src/stages/stage1/mes/compiler.nix b/foundation/src/stages/stage1/mes/compiler.nix new file mode 100644 index 0000000..6211efe --- /dev/null +++ b/foundation/src/stages/stage1/mes/compiler.nix @@ -0,0 +1,109 @@ +{ + lib, + config, +}: let + cfg = config.aux.foundation.stages.stage1.mes.compiler; + + system = config.aux.system; + builders = config.aux.foundation.builders; + + stage0 = config.aux.foundation.stages.stage0; + stage1 = config.aux.foundation.stages.stage1; +in { + options.aux.foundation.stages.stage1.mes.compiler = { + package = lib.options.create { + type = lib.types.package; + description = "The package to use for the mes compiler."; + }; + + meta = { + description = lib.options.create { + type = lib.types.string; + description = "Description for the package."; + default.value = "Scheme interpreter and C compiler for bootstrapping."; + }; + + homepage = lib.options.create { + type = lib.types.string; + description = "Homepage for the package."; + default.value = "https://www.gnu.org/software/mes"; + }; + + 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"]; + }; + }; + }; + + config = { + aux.foundation.stages.stage1.mes.compiler = { + package = let + compile = path: let + file = builtins.baseNameOf path; + fileWithoutExtension = builtins.replaceStrings [".c"] [""] file; + + cc = builtins.concatStringsSep " " [ + "${stage1.mes.libs.src.bin}/bin/mes-m2" + "-e" + "main" + "${stage1.mes.libs.src.bin}/bin/mescc.scm" + "--" + "-D" + "HAVE_CONFIG_H=1" + "-I" + "${stage1.mes.libs.prefix}/include" + "-I" + "${stage1.mes.libs.prefix}/include/linux/x86" + ]; + in + builders.kaem.build { + name = fileWithoutExtension; + + script = '' + mkdir ''${out} + cd ''${out} + ${cc} -c ${stage1.mes.libs.prefix}/${path} + ''; + }; + + getSourcePath = suffix: source: "${source}/${source.name}${suffix}"; + + sources = import ./sources.nix; + + files = + lib.strings.concatMapSep + " " + (getSourcePath ".o") + (builtins.map compile sources.x86.linux.mescc.mes); + in + builders.kaem.build { + name = "mes-${stage1.mes.version}"; + + meta = cfg.meta; + + script = '' + mkdir -p ''${out}/bin + + ${stage1.mes.libs.src.bin}/bin/mes-m2 -e main ${stage1.mes.libs.src.bin}/bin/mescc.scm -- \ + -L ${stage1.mes.libs.prefix}/lib \ + -L ${stage1.mes.libs.package}/lib \ + -lc \ + -lmescc \ + -nostdlib \ + -o ''${out}/bin/mes \ + ${stage1.mes.libs.package}/lib/x86-mes/crt1.o \ + ${files} + ''; + }; + }; + }; +} diff --git a/foundation/src/stages/stage1/mes/create-sources.sh b/foundation/src/stages/stage1/mes/create-sources.sh new file mode 100755 index 0000000..0a006f4 --- /dev/null +++ b/foundation/src/stages/stage1/mes/create-sources.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p bash coreutils gnutar + +# Generate a sources.nix for a version of GNU mes. Creates lists of source files +# from build-aux/configure-lib.sh. +# +# You may point this tool at a manually downloaded tarball, but more ideal is +# using the source tarball from Nixpkgs. For example: +# +# MES_TARBALL="$(nix eval --raw .#extras.stage1.mes.src)" +# ./create-sources.sh "$MES_TARBALL" > ./sources.nix +# +# Alternatively, here is a one-liner: +# +# ./create-sources.sh "$(nix eval --raw .#extras.stage1.mes.src)" > ./sources.nix + +set -eu + +# Supported platforms +ARCHS="x86" +KERNELS="linux" +COMPILERS="mescc gcc" + + +format() { + echo "[" + echo $* | xargs printf ' "%s"\n' + echo " ]" +} + +gen_sources() { + # Configuration variables used by configure-lib.sh + export mes_libc=mes + export mes_cpu=$1 + export mes_kernel=$2 + export compiler=$3 + + # Populate source file lists + source $CONFIGURE_LIB_SH + + cat <&2 + exit 1 +fi +echo "Generating sources.nix from $MES_TARBALL" >&2 + +TMP=$(mktemp -d) +cd $TMP +echo "Workdir: $TMP" >&2 + +echo "Extracting $MES_TARBALL" >&2 +tar --strip-components 1 -xf $MES_TARBALL + +CONFIGURE_LIB_SH="$TMP/build-aux/configure-lib.sh" +if [ ! -f $CONFIGURE_LIB_SH ]; then + echo "Could not find mes's configure-lib.sh script at $CONFIGURE_LIB_SH" >&2 + exit 1 +fi + +# Create dummy config expected by configure-lib.sh +touch config.sh +chmod +x config.sh + + +echo "Configuring with $CONFIGURE_LIB_SH" >&2 + +cat <