Skip to content

Nix flakes/packages for developing and building systems based on the Genode OS Framework

License

Notifications You must be signed in to change notification settings

zgzollers/nixpkgs-genode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Genode Nixpkgs

This repository provides useful Nix flakes/packages for developing and building systems based on the Genode OS Framework. Some familiarity with Nix (flakes) is recommended.

Usage

The following sections assume a working Nix installation with flakes enabled. See the official documentation for instructions for enabling Nix flakes.

Flake Template

This flake provides a containing a simple directory structure for a single Genode package.

Cloning the Template

To clone the provided flake template and create a new Genode package, run the following command.

nix flake new -t github:zgzollers/nixpkgs-genode#genode ./genode-project

Nix flakes can only access files that are added to a git repository. To initialize a new repository in the flake directory, run

git init && git add .

Make any desired changes to the initial template, then create the initial flake lock file by running

nix flake update && git add flake.lock

Finally, commit the changes. For some yet-unclear reason, the Genode build system will fail to build/run system scenarios and components if the initial flake template (in particular the .gitignore) is not committed to the repository.

git commit -m "Initial commit"

Note that in order for Nix flakes to access a source file, it must be tracked by (not necessarily committed to) the repository containing the flake. See the official documentation for more information.

Building Genode Packages

The template contains a sample Genode repository with a single "hello" application and runscript from the Genode Foundations book. This demo provides a nice opportunity to demonstrate the various ways this flake can be used, and ensure Nix is set up correctly.

To produce the system image for the demo scenario, we may build the package provided by the flake using the following command.

nix build

This will produce an ISO image located at result (which is a symbolic link to the produced image stored in the Nix store). You can run this image on Genode supported hardware, or in QEMU.

qemu-system-x86_64 -cdrom result -m 64 -nographic

Interactive Development Environment

It is often preferable to tinker with source code in a more interactive environment. Nix provides a tool for creating reproducible shell environments. To prepare all dependencies and required sources, simply enter the Nix shell using the following command.

nix develop

If you prefer not to use nix flakes, nix-shell may be used in place of the above command. Both of these commands will set a few useful environment variables.

Variable Default Value Description
SOURCE_DIR "$(pwd)/.build" Working directory for the build steps
GENODE_DIR "${SOURCE_DIR}/genode" Location of the root of the working copy of the Genode source tree
CONTRIB_DIR "${GENODE_DIR}/contrib" Location of prepared ports
BUILD_DIR "${SOURCE_DIR}/build" Location of the Genode build directory

These paths will not be created until you run the unpackPhase using the following command.

runPhase unpackPhase

This will create a .build subdirectory in the current working directory, populate it with the source codes and binary files required to build the derivation, and change to the $BUILD_DIR directory. Note that this directory persists after exiting the Nix shell. Subsequent executions of the unpackPhase will overwrite the contents of the .build directory. To preserve intermediate compilations when developing, avoid rerunning the unpackPhase upon returning to the Nix shell environment.

You can execute Genode tools/helper scripts located at $GENODE_DIR/tool. For example, additional ports can be prepared by running the following command.

${GENODE_DIR}/tool/ports/prepare_port . . .

The demo scenario can be built by running the buildPhase.

runPhase buildPhase

Creating a Genode Package

To facilitate packaging of Genode build artifacts with Nix, this flake provides a genodeEnv package. Similar to the Nix stdenv package, it contains a set of common packages necessary to build most Genode scenarios. Additionally, it provides a patched Genode source tree, and functions for building derivations and preparing additional dependencies (e.g., ports). Interaction with this environment is done primarily through the mkDerivation function provided by genodeEnv (not to be confused with mkDerivation provided by stdenv).

In the following sections, we will describe basic usage of this function to support common use cases. For more in-depth documentation of genodeEnv, please refer to the reference provided in this repository.

Adding Dependencies and Sources

In all but the simplest of cases, additional dependencies will be required to build a Genode package. The genodeEnv only provides a few packages (in addition to those provided by stdenv) required to run Makefiles and scripts in the $GENODE_DIR/tool directory. To specify additional dependencies (including ports, libraries, and tools), add the corresponding Nix package to the buildInputs argument of gendeEnv.mkDerivation. For example, when placed in the flake.nix file (as is the case in the template), the genodeEnv.mkDerivation call may look like the following.

. . .

genodeEnv.mkDerivation {
    name = "my-package";

    buildInputs = with genode-utils.packages.${system}; [
        grub2
        nova
    ];
}

. . .

This will add the nova and grub2 ports to the contrib directory at build time.

By default, all repositories included in the Genode source tree are made available at build time (i.e., added to the REPOSITORIES variable in build.conf). To provide additional repositories, add them to the repos argument. For example, in the flake template, a Genode repository is provided in the same directory as the flake.nix file. This repository may be included at build time by adding the following to the genode.mkDerivation call.

. . .

genodeEnv.mkDerivation {
    name = "my-package";

    buildInputs = with genode-utils.packages.${system}; [
        grub2
        nova
    ];

    repos = [
        ./.
    ];
}

. . .

This both makes the source accessible at build time and adds it to the REPOSITORIES variable in the generated build.conf.

Supplying Build Steps

With all dependencies supplied and sources prepared, we may now supply the commands to build and install the desired artifacts. The genodeEnv.mkDerivation function generates a build directory (and corresponding build.conf) based on the sources provided. All commands supplied in the buildPhase and installPhase are executed from within this directory. Additionally, all environment variables available in the Nix shell are available here. Keep in mind that, unlike the shell environment, internet access is not available when building Nix derivations. All downloads (e.g., ports) must be prepared in advance by Nix to protect reproducibility.

The buildPhase should include all commands required to produce the desired artifacts. For example, the template runs a single Genode runscript to produce a system image.

The installPhase immediately follows the buildPhase and should copy the desired artifact(s) to the output directory stored in the $out environment variable.

. . .

genodeEnv.mkDerivation {
    name = "my-package";

    buildInputs = with genode-utils.packages.${system}; [
        grub2
        nova
    ];

    repos = [
        ./.
    ];

    buildPhase = ''
        make run/hello
    '';

    installPhase = ''
        cp var/run/hello.iso $out
    '';
}

. . .

Updating Flake Inputs

Nix flakes make updating the external dependencies of your project very simple. Each of the inputs to your flake is "locked" at a specific commit hash by flake.lock. To advance all inputs to the latest commit in the branch they are following, run the following command.

nix flake update --commit-lock-file

Note that the --commit-lock-file is optional, but provides a nice commit message precisely describing the changes that were made. Keeping flake.lock updates in separate commits also makes it easy to revert if an update causes breakage.

To update a single input (e.g., nixpkgs), run the following command.

nix flake lock --update-input nixpkgs --commit-lock-file

Again, the --commit-lock-file is optional.

About

Nix flakes/packages for developing and building systems based on the Genode OS Framework

Topics

Resources

License

Stars

Watchers

Forks

Languages