diff --git a/Makefile b/Makefile index b698a21c9..c1b6e6acd 100644 --- a/Makefile +++ b/Makefile @@ -5,26 +5,34 @@ # ifeq ($(K),1) - keep_going := -k + keep_going_args := -k endif ifneq ($(J),) - jobs_arg := -j$(J) -else - jobs_arg := -j$$(nproc) + jobs_args := -j$(J) endif ifneq ($(CORES),) - cores_arg := --cores $(CORES) -else - cores_arg := + cores_args := --cores $(CORES) endif -out := out +nix_args := $(keep_going_args) $(jobs_args) $(cores_args) -nix_build := nix-build $(keep_going) $(jobs_arg) $(cores_arg) +append_to_nix_config := NIX_CONFIG="$$(printf "%s\n" "$$NIX_CONFIG" && cat hacking/binary-cache/fragment.nix.conf)" -nix_shell := nix-shell -A shell --pure +nix_build := $(append_to_nix_config) nix-build $(nix_args) +nix_shell := $(append_to_nix_config) nix-shell $(nix_args) + +ifeq ($(IN_NIX_SHELL_FOR_MAKEFILE),) + # TODO + # Should this use --pure? One consideration is that 'make shell' below + # doesn't, and consistency might be more important here. + run_in_nix_shell := $(nix_shell) -A shellForMakefile --pure --run +else + run_in_nix_shell := $(SHELL) -c +endif + +out := out .PHONY: none none: @@ -36,12 +44,9 @@ clean: $(out): mkdir -p $@ -rustc_target_spec_dir := support/targets - -.PHONY: generate-target-specs -generate-target-specs: - rm -f $(rustc_target_spec_dir)/*.json && \ - cargo run -p sel4-generate-target-specs -- write --target-dir $(rustc_target_spec_dir) --all +.PHONY: shell +shell: + $(nix_shell) -A shellForHacking .PHONY: update-generated-sources update-generated-sources: @@ -71,19 +76,26 @@ check-fmt: .PHONY: check-generic-formatting check-generic-formatting: - $(nix_shell) --run "sh hacking/scripts/check-generic-formatting.sh" + $(run_in_nix_shell) "sh hacking/scripts/check-generic-formatting.sh" .PHONY: check-source check-source: check-generated-sources check-fmt check-generic-formatting .PHONY: check-licenses check-licenses: - $(nix_shell) --run "reuse lint" + $(run_in_nix_shell) "reuse lint" .PHONY: check-dependencies check-dependencies: lockfile=$$($(nix_build) -A pkgs.build.this.publicCratesCargoLock --no-out-link) && \ - $(nix_shell) --run "cargo-audit audit -f $$lockfile" + $(run_in_nix_shell) "cargo-audit audit -f $$lockfile" + +rustc_target_spec_dir := support/targets + +.PHONY: generate-target-specs +generate-target-specs: + rm -f $(rustc_target_spec_dir)/*.json && \ + cargo run -p sel4-generate-target-specs -- write --target-dir $(rustc_target_spec_dir) --all try_restore_terminal := tput smam 2> /dev/null || true diff --git a/README.md b/README.md index e6cb371fe..067a1030f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,10 @@ the crates which use them: ### Quick start for running the tests in this repository -The only requirements for running the tests in this repository are Git, Make, and Docker. +The only requirements for building and running the tests in this repository are Linux, Make, +[rustup](https://rustup.rs/), and [Nix](https://nix.dev/). This repository contains scripts for +setting up a Docker container with a suitable development environment in case you aren't on Linux or +don't want to install Nix. First, clone this repository: @@ -130,22 +133,21 @@ git clone https://github.com/seL4/rust-sel4 cd rust-sel4 ``` -Next, build, run, and enter a Docker container for development: +If you are using Docker, build, run, and enter a Docker container for development. This container +mounts this repository's top-level at `/work`. ``` cd hacking/docker && make run && make exec ``` -Inside the container at the repository's top-level directory, build and simulate a simple seL4-based -system with a [root task](./crates/examples/root-task/example-root-task) written in Rust (this will -take a few minutes): +At this repository's top-level directory, build and simulate a simple seL4-based system with a [root +task](./crates/examples/root-task/example-root-task) written in Rust (this will take a few minutes): ``` make example ``` -Also inside the container at the repository's top-level directory, build and run all of this -repository's automated tests: +Build and run all of this repository's automated tests: ``` make run-tests diff --git a/hacking/cache-maintenance/Makefile b/hacking/binary-cache/Makefile similarity index 67% rename from hacking/cache-maintenance/Makefile rename to hacking/binary-cache/Makefile index ab4a5ef36..6c5ae6cc2 100644 --- a/hacking/cache-maintenance/Makefile +++ b/hacking/binary-cache/Makefile @@ -4,11 +4,13 @@ # SPDX-License-Identifier: BSD-2-Clause # -expr_path = ../.. +P ?= ../.. +A ?= everythingWithExcess -attr_args := -A everythingWithExcess +path := $(P) +attr := $(A) -nix_build_cmd := nix-build $(expr_path) $(attr_args) -j1 --no-out-link +nix_build_cmd := nix-build $(path) -A $(attr) --no-out-link cache_name := coliasgroup diff --git a/hacking/binary-cache/fragment.nix.conf b/hacking/binary-cache/fragment.nix.conf new file mode 100644 index 000000000..91b532b7c --- /dev/null +++ b/hacking/binary-cache/fragment.nix.conf @@ -0,0 +1,8 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +extra-substituters = https://coliasgroup.cachix.org +extra-trusted-public-keys = coliasgroup.cachix.org-1:vYRVaHS5FCjsGmVVXlzF5LaIWjeEK17W+MHxK886zIE= diff --git a/hacking/docker/Dockerfile b/hacking/docker/Dockerfile index 80e5d0d67..2f90a24f9 100644 --- a/hacking/docker/Dockerfile +++ b/hacking/docker/Dockerfile @@ -7,42 +7,92 @@ FROM debian:bookworm RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ xz-utils \ - curl git make \ - sudo man vim rsync procps \ + make \ + git \ + # general utilities + sudo \ + man \ + procps \ + rsync \ + file \ + less \ + vim \ bash-completion \ && rm -rf /var/lib/apt/lists/* -ARG UID -ARG GID - -RUN groupadd -f -g $GID x && useradd -u $UID -g $GID -G sudo -m -p x x RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers # for convenience -RUN mkdir -m 0755 /nix && chown x:x /nix - -USER x - -WORKDIR /home/x - -# Convenient shell completion and aliases -RUN mkdir -p .bash_completion.d && \ - curl -sSL -o .bash_completion.d/nix \ - https://raw.githubusercontent.com/hedning/nix-bash-completions/e6db3081fe1f221470a26e345a96855e5f09ddec/_nix - -COPY bashrc_extra .bashrc_extra -RUN echo ". ~/.bashrc_extra" >> .bashrc +ARG UID +ARG GID -WORKDIR /tmp +RUN set -eux; \ + if ! [ $UID = 0 -a $GID = 0 ]; then \ + ! getent passwd $UID; \ + # NOTE + # This is a bit of a hack. For example, GID for "staff" on MacOS is "dialout" on Debian. In + # an ideal world, we'd ensure that an already-occupied GID corresponds to either "users" or + # "staff" on Debian. + if ! getent group $GID; then \ + groupadd -g $GID x; \ + fi; \ + useradd -u $UID -g $GID -G sudo -m -p x x; \ + fi + +# So that they don't depend on $HOME +ENV RUSTUP_HOME=/opt/rustup +ENV CARGO_HOME=/opt/cargo + +RUN set -eux; \ + dirs="/nix $RUSTUP_HOME $CARGO_HOME"; \ + mkdir -p -m 0755 $dirs; \ + chown $UID:$GID $dirs + +USER $UID + +RUN curl -sSf -L https://sh.rustup.rs | \ + bash -s -- -y --no-modify-path --default-toolchain none + +ENV PATH=$CARGO_HOME/bin:$PATH + +RUN curl -sSf -L https://nixos.org/nix/install | \ + bash -s -- --yes --no-modify-profile --no-channel-add + +# Install bash completion for Nix +RUN set -eux; \ + export USER=$(whoami); \ + . ~/.nix-profile/etc/profile.d/nix.sh; \ + nix-channel --add https://nixos.org/channels/nixos-23.11 nixpkgs; \ + nix-channel --update; \ + nix-env -i nix-bash-completions; \ + nix-channel --remove nixpkgs; \ + nix-collect-garbage -d + +# Add gcroot for store paths required by this image so that fresh images can use persistent /nix +# volumes. +RUN set -eux; \ + export USER=$(whoami); \ + . ~/.nix-profile/etc/profile.d/nix.sh; \ + nix-store -r \ + --add-root /nix/var/nix/gcroots-for-image/profile \ + $(readlink --canonicalize-existing ~/.nix-profile) -ARG STATEFUL +COPY nix.conf /etc/nix/ -COPY setup.sh . +ENV NIX_BUILD_SHELL=bash -RUN if [ "$STATEFUL" = "1" ]; then bash setup.sh; fi +RUN ( \ + echo 'export USER=$(whoami)'; \ + echo '. ~/.nix-profile/etc/profile.d/nix.sh'; \ + ) >> ~/.bashrc -COPY nix.conf /etc/nix/ +RUN ( \ + echo 'set show-mode-in-prompt on'; \ + echo 'set editing-mode vi'; \ + ) >> ~/.inputrc -ENV NIX_BUILD_SHELL=bash +VOLUME /nix WORKDIR /work diff --git a/hacking/docker/Makefile b/hacking/docker/Makefile index 4354d1f07..3bdd07159 100644 --- a/hacking/docker/Makefile +++ b/hacking/docker/Makefile @@ -4,47 +4,43 @@ # SPDX-License-Identifier: BSD-2-Clause # -STATEFUL ?= $(if $(findstring Linux,$(shell uname -s)),0,1) +PERSIST ?= 1 work_root := ../.. id := rust-sel4 -label := $(id) image_tag := $(id) container_name := $(id) -volume_name := $(id)-nix-root +volume_name := $(id) uid := $(shell id -u) gid := $(shell id -g) -ifneq ($(STATEFUL),1) - statefulness_run_prerequisites := initialize-volume - statefulness_docker_run_args := --mount type=volume,src=$(volume_name),dst=/nix +ifeq ($(PERSIST),1) + persist_docker_run_args := --mount type=volume,src=$(volume_name),dst=/nix endif .PHONY: none none: +.PHONY: clean +clean: rm-container rm-volume + .PHONY: build build: docker build \ - --build-arg UID=$(uid) --build-arg GID=$(gid) --build-arg STATEFUL=$(STATEFUL) \ - --label $(label) -t $(image_tag) . - -.PHONY: initialize-volume -initialize-volume: build - if [ -z "$$(docker volume ls -q -f "name=^$(volume_name)$$")" ]; then \ - docker volume create --label $(label) $(volume_name) && \ - docker run --privileged --rm --label $(label) -w /tmp \ - $(statefulness_docker_run_args) \ - $(image_tag) flock /nix/.installed.lock bash setup.sh; \ - fi + --build-arg UID=$(uid) \ + --build-arg GID=$(gid) \ + -t $(image_tag) . .PHONY: run -run: build $(statefulness_run_prerequisites) - docker run --privileged -d --name $(container_name) --label $(label) \ - $(statefulness_docker_run_args) \ +run: build + docker run --privileged -d \ + --name $(container_name) \ + $(persist_docker_run_args) \ --mount type=bind,src=$(abspath $(work_root)),dst=/work \ + --publish 8080:8080/tcp \ + --publish 8443:8443/tcp \ $(image_tag) sleep inf .PHONY: exec @@ -53,16 +49,16 @@ exec: .PHONY: show-nix-root show-nix-root: - docker inspect $(volume_name) --format='{{.Mountpoint}}' + docker volume inspect $(volume_name) --format='{{.Mountpoint}}' .PHONY: rm-container rm-container: for id in $$(docker ps -aq -f "name=^$(container_name)$$"); do \ - docker rm -f $$id; \ + docker rm -f --volumes $$id; \ done .PHONY: rm-volume -rm-volume: - for volume in $$(docker volume ls -q -f "name=^$(volume_name)$$"); do \ - docker volume rm $$volume; \ +rm-volume: rm-container + for id in $$(docker volume ls -q -f "name=^$(volume_name)$$"); do \ + docker volume rm $$id; \ done diff --git a/hacking/docker/bashrc_extra b/hacking/docker/bashrc_extra deleted file mode 100644 index f76bd3a6f..000000000 --- a/hacking/docker/bashrc_extra +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -export USER=$(whoami) - -nix_profile_src=$HOME/.nix-profile -nix_profile_dst=/nix/var/nix/the-profile - -if [ ! -L "$nix_profile_src" ]; then - ln -s $nix_profile_dst $nix_profile_src -fi - -. "$nix_profile_src/etc/profile.d/nix.sh" - -for f in ~/.bash_completion.d/*; do - . $f -done diff --git a/hacking/docker/nix.conf b/hacking/docker/nix.conf index b8edeea02..9afe73f35 100644 --- a/hacking/docker/nix.conf +++ b/hacking/docker/nix.conf @@ -4,14 +4,12 @@ # SPDX-License-Identifier: BSD-2-Clause # -max-jobs = auto -cores = 0 - sandbox-fallback = false keep-outputs = true +keep-derivations = true -experimental-features = flakes +experimental-features = nix-command flakes -substituters = https://cache.nixos.org https://coliasgroup.cachix.org -trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= coliasgroup.cachix.org-1:vYRVaHS5FCjsGmVVXlzF5LaIWjeEK17W+MHxK886zIE= +extra-substituters = https://coliasgroup.cachix.org +extra-trusted-public-keys = coliasgroup.cachix.org-1:vYRVaHS5FCjsGmVVXlzF5LaIWjeEK17W+MHxK886zIE= diff --git a/hacking/docker/setup.sh b/hacking/docker/setup.sh deleted file mode 100644 index 06ae8b949..000000000 --- a/hacking/docker/setup.sh +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -set -e - -if [ ! -f /nix/.installed ]; then - curl -L https://nixos.org/nix/install | \ - sh -s -- --yes --no-channel-add --no-modify-profile - ln -s $(readlink --canonicalize $HOME/.nix-profile) /nix/var/nix/the-profile - rm -r $HOME/.nix-profile $HOME/.nix-defexpr $HOME/.local/state/nix - touch /nix/.installed -fi diff --git a/hacking/kani/docker/Dockerfile b/hacking/kani/docker/Dockerfile index 0bf721d40..95fd38ea5 100644 --- a/hacking/kani/docker/Dockerfile +++ b/hacking/kani/docker/Dockerfile @@ -6,34 +6,48 @@ FROM debian:bookworm -RUN apt-get update -q && apt-get install -y --no-install-recommends \ - bash-completion \ +RUN apt-get update && apt-get install -y \ build-essential \ - ca-certificates \ curl \ - make \ - man \ - procps \ python3-pip \ sudo \ + man \ + procps \ vim \ + bash-completion \ && rm -rf /var/lib/apt/lists/* +RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + ARG UID ARG GID -RUN groupadd -f -g $GID x && useradd -u $UID -g $GID -G sudo -m -p x x -RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers # for convenience +RUN set -eux; \ + if ! [ $UID = 0 -a $GID = 0 ]; then \ + ! getent passwd $UID; \ + if ! getent group $GID; then \ + groupadd -g $GID x; \ + fi; \ + useradd -u $UID -g $GID -G sudo -m -p x x; \ + fi + +ENV RUSTUP_HOME=/opt/rustup +ENV CARGO_HOME=/opt/cargo + +RUN set -eux; \ + dirs="$RUSTUP_HOME $CARGO_HOME"; \ + mkdir -p -m 0755 $dirs; \ + chown $UID:$GID $dirs -USER x +USER $UID # Optimize by matching rust-toolchain.toml ENV DEFAULT_TOOLCHAIN=nightly-2023-08-02 -RUN curl -sSf https://sh.rustup.rs | \ +RUN curl -sSf -L https://sh.rustup.rs | \ bash -s -- -y --no-modify-path --default-toolchain $DEFAULT_TOOLCHAIN -ENV PATH=/home/x/.cargo/bin:$PATH +ENV PATH=$CARGO_HOME/bin:$PATH RUN cargo install --locked kani-verifier && cargo kani setup diff --git a/hacking/kani/docker/Makefile b/hacking/kani/docker/Makefile index 57fc414df..80f8e4f70 100644 --- a/hacking/kani/docker/Makefile +++ b/hacking/kani/docker/Makefile @@ -25,18 +25,19 @@ build: --build-arg UID=$(uid) --build-arg GID=$(gid) \ -t $(image_tag) . +.PHONY: runi +runi: build + docker run --rm -it \ + --mount $(mount_params) \ + $(image_tag) bash + .PHONY: run run: build - docker run -d --name $(container_name) \ + docker run -d \ --mount $(mount_params) \ + --name $(container_name) \ $(image_tag) sleep inf -.PHONY: runi -runi: build - docker run --rm \ - --mount $(mount_params) \ - -it $(image_tag) bash - .PHONY: exec exec: docker exec -it $(container_name) bash @@ -49,7 +50,10 @@ rm-container: .PHONY: check check: build - docker run --rm \ + if [ -t 0 ]; then \ + tty_args="-it"; \ + fi && \ + docker run --rm $$tty_args \ --mount $(mount_params),readonly \ - -i $(image_tag) \ + $(image_tag) \ make -C $(here_relative) check BUILD=/tmp/build diff --git a/hacking/nix/default.nix b/hacking/nix/default.nix index 209772327..2ef840110 100644 --- a/hacking/nix/default.nix +++ b/hacking/nix/default.nix @@ -6,21 +6,21 @@ let - defaultNixpkgsSource = + defaultNixpkgsPath = let - rev = "185442f0f70497d8a02f26f8bc36688933a7b5eb"; + rev = "1811c4fec88995679397d6fa20f4f3395a0bebe5"; in builtins.fetchTarball { url = "https://github.com/coliasgroup/nixpkgs/archive/refs/tags/keep/${builtins.substring 0 32 rev}.tar.gz"; - sha256 = "sha256:0swvdlw1qb2xxp50in78lqkx3gkjvzmj4zrhlhnzzjf3aqdqn722"; + sha256 = "sha256:0ad2c7vlr9fidzjjg8szigfhmp1gvlf62ckd6cir8ymrxc93pby7"; }; - defaultNixpkgsFn = import defaultNixpkgsSource; - defaultNixpkgsLib = import (defaultNixpkgsSource + "/lib"); - in -{ lib ? defaultNixpkgsLib, nixpkgsFn ? defaultNixpkgsFn }: +{ nixpkgsPath ? defaultNixpkgsPath +, nixpkgsFn ? import nixpkgsPath +, lib ? import (nixpkgsPath + "/lib") +}: let diff --git a/hacking/nix/scope/default.nix b/hacking/nix/scope/default.nix index e6866268b..b9160e489 100644 --- a/hacking/nix/scope/default.nix +++ b/hacking/nix/scope/default.nix @@ -166,7 +166,8 @@ superCallPackage ../rust-utils {} self // embedDebugInfo = callPackage ./embed-debug-info.nix {}; - shell = callPackage ./shell.nix {}; + shellForMakefile = callPackage ./shell-for-makefile.nix {}; + shellForHacking = callPackage ./shell-for-hacking.nix {}; ### kernel diff --git a/hacking/nix/scope/sel4/default.nix b/hacking/nix/scope/sel4/default.nix index 7d8de97e1..82145c342 100644 --- a/hacking/nix/scope/sel4/default.nix +++ b/hacking/nix/scope/sel4/default.nix @@ -53,7 +53,6 @@ stdenv.mkDerivation { cmake \ -DCROSS_COMPILER_PREFIX=${stdenv.cc.targetPrefix} \ - -DCMAKE_TOOLCHAIN_FILE=gcc.cmake \ -DCMAKE_INSTALL_PREFIX=$out \ -C ${settings} \ -G Ninja \ diff --git a/hacking/nix/scope/shell.nix b/hacking/nix/scope/shell-for-hacking.nix similarity index 55% rename from hacking/nix/scope/shell.nix rename to hacking/nix/scope/shell-for-hacking.nix index 99a60bda1..bc7c91e5a 100644 --- a/hacking/nix/scope/shell.nix +++ b/hacking/nix/scope/shell-for-hacking.nix @@ -6,37 +6,44 @@ { lib, stdenv, hostPlatform, buildPackages , mkShell -, cacert, git -, defaultRustToolchain -, pkgconfig, openssl -, cmake, perl, python3Packages -, rustPlatform -, reuse -, cargo-audit + +, pkgconfig +, git +, cacert +, rustup, rustPlatform +, perl +, python3Packages +, cmake + +, strace +, cntr +, cachix + +, openssl + +, shellForMakefile }: -mkShell { - hardeningDisable = [ "all" ]; +mkShell (shellForMakefile.apply { depsBuildBuild = [ buildPackages.stdenv.cc - cacert - git - cmake - perl - python3Packages.jsonschema - python3Packages.jinja2 - reuse - cargo-audit ]; nativeBuildInputs = [ pkgconfig + git + cacert + rustup + perl + cmake rustPlatform.bindgenHook - defaultRustToolchain + strace + cntr + cachix ]; buildInputs = [ openssl ]; -} +}) diff --git a/hacking/nix/scope/shell-for-makefile.nix b/hacking/nix/scope/shell-for-makefile.nix new file mode 100644 index 000000000..fa66129d8 --- /dev/null +++ b/hacking/nix/scope/shell-for-makefile.nix @@ -0,0 +1,32 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mkShell +, python3 +, reuse +, cargo-audit +}: + +let + # HACK for composability + apply = attrs: attrs // { + IN_NIX_SHELL_FOR_MAKEFILE = 1; + + hardeningDisable = [ "all" ]; + + nativeBuildInputs = (attrs.nativeBuildInputs or []) ++ [ + python3 + reuse + cargo-audit + ]; + }; + +in +mkShell (apply { + passthru = { + inherit apply; + }; +}) diff --git a/hacking/nix/scope/sources.nix b/hacking/nix/scope/sources.nix index 200be5c72..ea4c1ae0a 100644 --- a/hacking/nix/scope/sources.nix +++ b/hacking/nix/scope/sources.nix @@ -35,7 +35,7 @@ let srcRoot = ../../..; # TODO - localRoot = srcRoot + "/../x"; + localRoot = srcRoot + "/tmp/src"; mkKeepRef = rev: "refs/tags/keep/${builtins.substring 0 32 rev}"; diff --git a/hacking/nix/scope/world/instances/microkit/http-server/default.nix b/hacking/nix/scope/world/instances/microkit/http-server/default.nix index 6c943cf3c..4bbbf4f30 100644 --- a/hacking/nix/scope/world/instances/microkit/http-server/default.nix +++ b/hacking/nix/scope/world/instances/microkit/http-server/default.nix @@ -39,11 +39,16 @@ let diskImage = mkDiskImage {}; smallDiskImage = mkDiskImage { excludePatterns = [ "*.mp4" "*.pdf" ]; }; + vmTools = buildPackages.vmTools.override { + # HACK + requireKVM = false; + }; + mkDiskImage = { maxIndividualFileSize ? null , excludePatterns ? null }: - buildPackages.vmTools.runInLinuxVM (runCommand "disk-image" { + vmTools.runInLinuxVM (runCommand "disk-image" { nativeBuildInputs = [ python3 kmod parted fatresize dosfstools ]; preVM = '' mkdir scratch diff --git a/hacking/nix/top-level/default.nix b/hacking/nix/top-level/default.nix index fcdfeec11..57d79c013 100644 --- a/hacking/nix/top-level/default.nix +++ b/hacking/nix/top-level/default.nix @@ -12,7 +12,7 @@ let in { - shell = pkgs.build.this.shell; + inherit (pkgs.build.this) shellForMakefile shellForHacking; worldsForEverythingInstances = [ pkgs.host.aarch64.none.this.worlds.default