Circular Packaging framework with nix Flakes, including ROS support
Warning
still early beta: API will change, things will break, and/or are already broken
When one package is defined in a flake, we can by default:
nix build: build the package (and run its tests)nix shell: open a shell with the package ready to be usednix develop: open a shell without the built package, but with everything required to build itnix run: execute the main program from the package
Flakoboros allows to provide the same experience with multiple packages in a flake:
nix build: build all packages (and run their tests)nix shell: open a shell with all packages ready to be usednix develop: open a shell without any of the packages, but with everything required to build them allnix run: execute the main program from all the packages (eg. a python interpreter with all the python modules available)
To do so, the main API is designed around the idea that your packages are distributed in another more-or-less central repository (eg. nixpkgs or nix-ros-overlay),
and you just need my-package.overrideAttrs { src = lib.cleanSource ./. } in the flake of the source.
That notion of re-using an existing distribution of a package inside its source.
More details in rationale.md
example for eigenpy:
{
description = "Bindings between Numpy and Eigen using Boost.Python";
inputs.flakoboros.url = "github:gepetto/flakoboros";
outputs =
inputs:
inputs.flakoboros.lib.mkFlakoboros (
{ lib, ... }:
{
pyOverrideAttrs.eigenpy = {
src = lib.cleanSource ./.;
};
}
);
}Behind the scene, this is a shallow wrapper around `flake-parts.lib.mkFlake`, which can be used directly
{
description = "Bindings between Numpy and Eigen using Boost.Python";
inputs = {
flakoboros.url = "github:gepetto/flakoboros";
flake-parts.follows = "flakoboros/flake-parts";
systems.follows = "flakoboros/systems";
};
outputs =
inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } (
{ lib, ... }:
{
systems = import inputs.systems;
imports = [
inputs.flakoboros.flakeModule
{
flakoboros.pyOverrideAttrs.eigenpy = {
src = lib.cleanSource ./.;
};
}
];
}
);
}(the full list is defined in options.nix)
This will:
- define
overlays.flakoboroswith this override - (if you don't opt-out) instanciate
pkgswith that overlay - inherit this in
packages.${system}.py-eigenpy - define
packages.${system}.defaultas abuildEnvincluding all otherspackages.${system}.*(fornix build&nix shell) - define
devShells.${system}.defaultas amkShellwithinputsFromthe samepackages.${system}.*(fornix develop/nix-direnv)
If you have ROS packages, the default package and devShell will use a default ROS distribution (eg. rolling), but the same features are available for other distros, with eg.
nix build .#ros-humblenix shell .#ros-jazzynix develop .#ros-kiltednix run .#ros-rolling
Also, standard ROS tools like colcon and ros2cli will be included.
flakoboros = {
extends.eigen5 = final: { eigen = final.eigen_5; };
pyOverrideAttrs.eigenpy = {
src = lib.cleanSource ./.;
};
};This will:
- define
pkgs,packages.${system}.py-eigenpyandpackages.${system}.defaultas before - define
pkgs.pkgs-eigen5as anotherpkgsinstance but whereeigenis overriden everywhere byeigen_5 - define
packages.${system}.pkgs-eigen5, equivalent topackages.${system}.defaultbut with eigen 5 - add scoped everything else, eg.
packages.${system}.pkgs-eigen5.py-eigenpy(technicallypackages.${system}.pkgs-eigen5.passthru.py-eigenpy) - define
devShells.${system}.pkgs-eigen5
So in your CI, you can build . and .#pkgs-eigen5 to check all your stack with both eigen 3.4.1 and 5.0.1.
Also, you can either echo 'use flake .' > .envrc or echo 'use flake .#pkgs-eigen5' > .envrc, and follow your usual cmake -B build && cmake --build build workflow.