Skip to content

Commit

Permalink
Add Nix flake
Browse files Browse the repository at this point in the history
This commit adds a [Nix flake] for building Humility for Nix users,
providing a dev environment with build dependencies for use with `nix
develop` or `direnv`, and (on NixOS) configuring udev rules to allow all
debug probes supported by `probe-rs`. Parts of this flake --- in
particular, the code for cross-compiling for multiple targets --- are
based on code written by @faithanalog.

## What The Flake Provides

The flake provides the following:

- Packages for `humility` (for the host platform), as well as
  `humility-aarch64` and `humility-armv7l` for cross-compiling for ARM
  linux environments. These were in @faithanalog's config as I believe
  she's got dev boards hooked up to a Raspberry Pi or something that she
  SSHes into, but would like to build Humility on her dev machine for
  the Pi target.
- The Linux Packages contains the canonical `udev`` rules published by
  `probe-rs`, allowing NixOS users to add
  ```nix
  services.udev.packages = [ pkgs.humility ];
  ```
  to their `configuration.nix`` to allow all the debug probes that
  `probe-rs` supports to be run by non-root users. This config is
  fetched from the `probe-rs/website` Git repository, so if upstream
  adds new supported probes, we can pick up their changes.
- A flake `app` for use with `nix run`, which runs a Humility command.
- A dev shell including Humility's build time dependencies, which can be
  used with `nix develop` or `direnv`
- A NixOS module `programs.humility` which can be used by NixOS users to
  add Humility to the system's packages, add the udev rules, and add
  user account(s) to the `plugdev` group to allow access to debug
  probes.

## On Checking In Nix Configurations

I understand that checking in configurations that are specific to a
package manager/distro that not everyone uses may be controversial. And,
if folks don't want Nix configs in the main Humility repo, that's
understandable, and there are alternative options for Nix users to build
Humility --- we can also have a Nix flake in a separate repo that
fetches the Humility sources from Git. However, checking in this flake
to the Humility repo has some meaningful advantages for Nix users:

1. It allows the Nix build environment for packaging Humility to be used
   as a dev environment for `direnv` or `nix-develop`. If the Nix
   configuration is not in the source tree, it can't easily be used with
   `direnv`. Of course, Nix users can have their own dev environment
   that isn't checked in. However, this would no longer be the *same*
   build environment definition that would be used for building a
   Humility nix package, meaning that there is the potential for drift
   between individual contributors' dev environments and the canonical
   build environment.
2. I'd like to eventually set up publishing to [FlakeHub] on CI when new
   release tags are pushed to the repo, requiring an in-repo Nix flake.
3. I know at least a few folks at Oxide are Nix users (at the very
   least, myself and @faithanalog), and it seems nice to have a
   canonical configuration in the repository rather than requiring folks
   to write their own (potentially differing in minor ways) whenever a
   NixOS user wants to build or contribute to Humility.

If this rationale isn't convincing, that's okay, and I'm happy to close
this PR. :)

[Nix flake]: https://zero-to-nix.com/concepts/flakes
[FlakeHub]: https://flakehub.com/
  • Loading branch information
hawkw committed Mar 22, 2024
1 parent bc6810e commit 0939f91
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
/target
# created by `nix-direnv`
.direnv
# created by `nix build`
/result
82 changes: 82 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

166 changes: 166 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
{
description = "debugger for Hubris";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs = { self, nixpkgs, rust-overlay }:
let
systems = [ "x86_64-linux" "aarch64-linux" "armv7l-linux" "x86_64-darwin" "aarch64-darwin" ];
overlays = [ (import rust-overlay) ];
forAllSystems = function:
nixpkgs.lib.genAttrs systems
(system:
let
pkgs = import nixpkgs {
inherit system overlays;
};
in
function pkgs);
pname = "humility";
build-humility =
(pkgs: with pkgs; let

udevFilename = "69-probe-rs.rules";
# fetch the probe-rs website to use their list of udev rules for all
# debug probes supported by probe-rs
probeRsWebsite = fetchFromGitHub
{
owner = "probe-rs";
repo = "webpage";
rev = "2617971b3584bae9c227cd026aaaabdc45a308a3";
hash = "sha256-ur5oGb6aypce6h0YPvCKc/8/X7FBfzOQS9zlkLP2UGY=";
};

# use the Rust toolchain specified in the project's rust-toolchain.toml
rustToolchain =
let
file = pkgsBuildHost.rust-bin.fromRustupToolchainFile
./rust-toolchain.toml;
in
file.override {
extensions = [
"rust-src" # for rust-analyzer
];
};

configuredRustPlatform = makeRustPlatform {
cargo = rustToolchain;
rustc = rustToolchain;
};

src = nix-gitignore.gitignoreSource [ ] ./.;
cargoTOML = lib.importTOML "${src}/Cargo.toml";
in
configuredRustPlatform.buildRustPackage {
inherit src pname;
inherit (cargoTOML.package) version;

buildInputs =
if stdenv.isLinux then [
libudev-zero
] else [ ];
nativeBuildInputs = if stdenv.isLinux then [ pkg-config ] else [ ];

cargoLock.lockFile = ./Cargo.lock;
cargoLock.outputHashes = {
"capstone-0.10.0" = "sha256-x0p005W6u3QsTKRupj9HEg+dZB3xCXlKb9VCKv+LJ0U=";
"gimlet-inspector-protocol-0.1.0" = "sha256-NLKiYL1CMkQaaTP0ePwEK49Y9lckkOrzw7371SHHEWQ=";
"hidapi-1.4.1" = "sha256-2SBQu94ArGGwPU3wJYV0vwwVOXMCCq+jbeBHfKuE+pA=";
"hif-0.3.1" = "sha256-o3r1akaSARfqIzuP86SJc6/s0b2PIkaZENjYO3DPAUo=";
"humpty-0.1.3" = "sha256-efeb+RaAjQs9XU3KkfVo8mVK2dGyv+2xFKSVKS0vyTc=";
"idol-0.3.0" = "sha256-s6ZM/EyBE1eOySPah5GtT0/l7RIQKkeUPybMmqUpmt8=";
"idt8a3xxxx-0.1.0" = "sha256-S36fS9hYTIn57Tt9msRiM7OFfujJEf8ED+9R9p0zgK4=";
"libusb1-sys-0.5.0" = "sha256-7Bb1lpZvCb+OrKGYiD6NV+lMJuxFbukkRXsufaro5OQ=";
"pmbus-0.1.2" = "sha256-NFSrh4yD7PCqYhGuioRYWFmFIcpFvDO1qh6Lp9tsJ9E=";
"probe-rs-0.12.0" = "sha256-/L+85K6uxzUmz/TlLLFbMlyekoXC/ClO33EQ/yYjQKU=";
"spd-0.1.0" = "sha256-X6XUx+huQp77XF5EZDYYqRqaHsdDSbDMK8qcuSGob3E=";
"tlvc-0.2.0" = "sha256-HiqDRqmKOTxz6UQSXNMOZdWdc5W+cFGuKBkNrqFvIIE=";
"vsc7448-info-0.1.0" = "sha256-otNLdfGIzuyu03wEb7tzhZVVMdS0of2sU/AKSNSsoho=";
};

# Copy the probe-rs udev rules into `etc/udev/rules.d` so that this
# package can be added to `services.udev.packages` on NixOS.
postInstall = ''
mkdir -p $out/etc/udev/rules.d
cp ${probeRsWebsite}/src/static/files/${udevFilename} $out/etc/udev/rules.d/${udevFilename}
'';

meta = {
inherit (cargoTOML.package) homepage license;
description = "debugger for Hubris";
mainProgram = pname;
};
});
in
{
########################################################################
#### Packages
########################################################################
packages = forAllSystems (pkgs: with pkgs; {
humility = build-humility pkgs;
default = self.packages.${system}.humility;
humility-cross-armv7l-linux =
build-humility pkgsCross.armv7l-hf-multiplatform;
humility-cross-aarch64-linux =
build-humility pkgsCross.aarch64-multiplatform;
});

########################################################################
#### Flake app (for `nix run`)
########################################################################
apps = forAllSystems
(pkgs: with pkgs; {
humility = {
type = "app";
program = "${self.packages.${system}.humility}/bin/${pname}";
};
default = self.apps.${system}.humility;
});

########################################################################
#### Dev shell (for `nix develop`)
########################################################################
devShells = forAllSystems
(pkgs: with pkgs; let humilityPackage = self.packages.${system}.humility; in {
default = mkShell {
buildInputs = [ humilityPackage humilityPackage.buildInputs ];
nativeBuildInputs = [ humilityPackage.nativeBuildInputs ];
};
});

########################################################################
#### NixOS module (`programs.humility`)
########################################################################
nixosModules.default = { config, lib, pkgs, ... }: with lib; let
cfg = config.programs.humility;
in
{
options.programs.humility = {
enable = mkEnableOption "Humility, the debugger for Hubris";
users = mkOption {
type = types.listOf types.str;
default = [ ];
description = mdDoc ''
List of users added to the "plugdev" group,
allowing access to debug probes used by Humility.
'';
};
};

config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.humility ];
services.udev.packages = [ pkgs.humility ];
users.groups.plugdev = {
members = cfg.users;
};
};
};

};
}

0 comments on commit 0939f91

Please sign in to comment.