feat: Expose module for setting up the build and test environment.
This commit is contained in:
parent
62d4eb37a2
commit
26b7cb2116
4 changed files with 221 additions and 44 deletions
33
README.md
33
README.md
|
|
@ -3,6 +3,39 @@
|
|||
|
||||
Use the Nix [C API] from Rust.
|
||||
|
||||
## Build with `nix-cargo-integration`
|
||||
|
||||
The development environment and building with Nix are taken care of by [nix-cargo-integration](https://github.com/90-008/nix-cargo-integration#readme) ([options](https://flake.parts/options/nix-cargo-integration.html)).
|
||||
|
||||
The dependency on Nix is taken care of with the [`nix-bindings-rust` flake-parts module]().
|
||||
|
||||
Example usage:
|
||||
|
||||
```nix
|
||||
{
|
||||
outputs =
|
||||
inputs@{ self, flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; }
|
||||
{
|
||||
imports = [
|
||||
inputs.nix-cargo-integration.flakeModule
|
||||
inputs.nix-bindings-rust.modules.flake.default
|
||||
];
|
||||
|
||||
perSystem = { config, pkgs, ... }: {
|
||||
# optional:
|
||||
nix-bindings-rust.nixPackage = pkgs.nix;
|
||||
|
||||
nci.projects."myproject" = {
|
||||
depsDrvConfig = {
|
||||
imports = [ config.nix-bindings-rust.nciBuildConfig ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Hacking
|
||||
|
||||
The following will open a shell with dependencies, and install pre-commit for automatic formatting.
|
||||
|
|
|
|||
|
|
@ -10,8 +10,14 @@
|
|||
inputs.hercules-ci-effects.flakeModule
|
||||
];
|
||||
perSystem =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
inputs',
|
||||
...
|
||||
}:
|
||||
{
|
||||
nix-bindings-rust.nixPackage = inputs'.nix.packages.default;
|
||||
|
||||
pre-commit.settings.hooks.nixfmt-rfc-style.enable = true;
|
||||
# Temporarily disable rustfmt due to configuration issues
|
||||
|
|
|
|||
176
flake.nix
176
flake.nix
|
|
@ -13,14 +13,158 @@
|
|||
outputs =
|
||||
inputs@{ self, flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } (
|
||||
{
|
||||
toplevel@{
|
||||
lib,
|
||||
withSystem,
|
||||
...
|
||||
}:
|
||||
let
|
||||
/**
|
||||
Makes perSystem.nix-bindings-rust available.
|
||||
*/
|
||||
flake-parts-modules.basic =
|
||||
{
|
||||
config,
|
||||
flake-parts-lib,
|
||||
withSystem,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.perSystem = flake-parts-lib.mkPerSystemOption (
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.nix-bindings-rust;
|
||||
in
|
||||
{
|
||||
options.nix-bindings-rust = {
|
||||
nixPackage = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.nix;
|
||||
defaultText = lib.literalMD "pkgs.nix";
|
||||
description = ''
|
||||
The Nix package to use when building the `nix-bindings-...` crates.
|
||||
'';
|
||||
};
|
||||
nciBuildConfig = lib.mkOption {
|
||||
type = lib.types.deferredModule;
|
||||
description = ''
|
||||
A module to load into your nix-cargo-integration
|
||||
[`perSystem.nci.projects.<name>.depsDrvConfig`](https://flake.parts/options/nix-cargo-integration.html#opt-perSystem.nci.projects._name_.depsDrvConfig) or similar such options.
|
||||
|
||||
Example:
|
||||
```nix
|
||||
perSystem = perSystem@{ config, ... }: {
|
||||
nci.projects."my_project".depsDrvConfig = perSystem.config.nix-bindings-rust.nciBuildConfig;
|
||||
}
|
||||
```
|
||||
'';
|
||||
};
|
||||
};
|
||||
config.nix-bindings-rust = {
|
||||
nciBuildConfig = {
|
||||
mkDerivation = {
|
||||
buildInputs = [
|
||||
# stdbool.h
|
||||
pkgs.stdenv.cc
|
||||
]
|
||||
++ (
|
||||
if cfg.nixPackage ? libs then
|
||||
let
|
||||
l = cfg.nixPackage.libs;
|
||||
in
|
||||
[
|
||||
l.nix-expr-c
|
||||
l.nix-store-c
|
||||
l.nix-util-c
|
||||
l.nix-fetchers-c or null # Nix >= 2.29
|
||||
l.nix-flake-c
|
||||
]
|
||||
else
|
||||
[ cfg.nixPackage ]
|
||||
);
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkg-config
|
||||
];
|
||||
# bindgen uses clang to generate bindings, but it doesn't know where to
|
||||
# find our stdenv cc's headers, so when it's gcc, we need to tell it.
|
||||
postConfigure = lib.optionalString pkgs.stdenv.cc.isGNU ''
|
||||
source ${./bindgen-gcc.sh}
|
||||
'';
|
||||
};
|
||||
# NOTE: duplicated in flake.nix devShell
|
||||
env = {
|
||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.buildPackages.llvmPackages.clang-unwrapped ];
|
||||
BINDGEN_EXTRA_CLANG_ARGS =
|
||||
# Work around missing [[deprecated]] in clang
|
||||
"-x c++ -std=c++2a";
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.cc.isGNU {
|
||||
# Avoid cc wrapper, because we only need to add the compiler/"system" dirs
|
||||
NIX_CC_UNWRAPPED = "${pkgs.stdenv.cc.cc}/bin/gcc";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
Adds flake checks that test the bindings with the provided nix package.
|
||||
*/
|
||||
flake-parts-modules.tested =
|
||||
# Consumer toplevel
|
||||
{ options, config, ... }:
|
||||
{
|
||||
imports = [ flake-parts-modules.basic ];
|
||||
config.perSystem =
|
||||
# Consumer perSystem
|
||||
consumerPerSystem@{
|
||||
lib,
|
||||
config,
|
||||
system,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# nix-bindings-rust's perSystem, but with the consumer's `pkgs`
|
||||
nix-bindings-rust-perSystemConfig =
|
||||
# Extending our own perSystem, not the consumer's perSystem!
|
||||
toplevel.config.partitions.testing-support.module.nix-bindings-rust.internalWithSystem system
|
||||
({ extendModules, ... }: extendModules)
|
||||
{
|
||||
modules = [
|
||||
{
|
||||
config = {
|
||||
# Overriding our `perSystem` to use the consumer's `pkgs`
|
||||
_module.args.pkgs = lib.mkForce consumerPerSystem.pkgs;
|
||||
# ... and `nixPackage`
|
||||
nix-bindings-rust.nixPackage = lib.mkForce consumerPerSystem.config.nix-bindings-rust.nixPackage;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
key = "nix-bindings-rust-add-checks";
|
||||
config.checks = lib.concatMapAttrs (
|
||||
k: v:
|
||||
lib.optionalAttrs (lib.strings.hasPrefix "nix-bindings-" k && !lib.strings.hasSuffix "-clippy" k) {
|
||||
"dependency-${k}" = v;
|
||||
}
|
||||
) nix-bindings-rust-perSystemConfig.config.checks;
|
||||
};
|
||||
};
|
||||
|
||||
flake-parts-modules.default = flake-parts-modules.tested;
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
inputs.nix-cargo-integration.flakeModule
|
||||
inputs.flake-parts.flakeModules.partitions
|
||||
inputs.flake-parts.flakeModules.modules
|
||||
# dogfood
|
||||
flake-parts-modules.tested
|
||||
./nci.nix
|
||||
];
|
||||
systems = [
|
||||
|
|
@ -44,10 +188,40 @@
|
|||
partitionedAttrs.devShells = "dev";
|
||||
partitionedAttrs.checks = "dev";
|
||||
partitionedAttrs.herculesCI = "dev";
|
||||
# Packages are basically just checks in this project; a library by
|
||||
# itself is not useful. That's just not how the Rust integration works.
|
||||
# By taking `packages` from `dev` we benefit from this dev-only definition:
|
||||
# nix-bindings-rust.nixPackage = inputs'.nix.packages.default;
|
||||
partitionedAttrs.packages = "dev";
|
||||
|
||||
partitions.dev.extraInputsFlake = ./dev;
|
||||
partitions.dev.module = {
|
||||
imports = [ ./dev/flake-module.nix ];
|
||||
};
|
||||
|
||||
# A partition that doesn't dogfood the flake-parts-modules.tested module
|
||||
# so that we can actually retrieve `checks` without infinite recursions
|
||||
# from trying to include the dogfooded attrs.
|
||||
partitions.testing-support.module =
|
||||
{ withSystem, ... }:
|
||||
{
|
||||
# Make a clean withSystem available for consumers
|
||||
options.nix-bindings-rust.internalWithSystem = lib.mkOption { internal = true; };
|
||||
config = {
|
||||
nix-bindings-rust.internalWithSystem = withSystem;
|
||||
perSystem = {
|
||||
# Remove dogfooded checks. This configuration's checks are
|
||||
# *consumed* by nix-bindings-rust-add-checks, so they should
|
||||
# *NOT* also be *produced* by it.
|
||||
disabledModules = [ { key = "nix-bindings-rust-add-checks"; } ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# flake output attributes
|
||||
flake = {
|
||||
modules.flake = flake-parts-modules;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
48
nci.nix
48
nci.nix
|
|
@ -11,33 +11,12 @@
|
|||
nci.projects.nix-bindings = {
|
||||
path = ./.;
|
||||
drvConfig = {
|
||||
imports = [
|
||||
# Downstream projects import this into depsDrvConfig instead
|
||||
config.nix-bindings-rust.nciBuildConfig
|
||||
];
|
||||
# Extra settings for running the tests
|
||||
mkDerivation = {
|
||||
buildInputs = [
|
||||
# stdbool.h
|
||||
pkgs.stdenv.cc
|
||||
]
|
||||
++ (
|
||||
if config.packages.nix ? libs then
|
||||
let
|
||||
l = config.packages.nix.libs;
|
||||
in
|
||||
[
|
||||
l.nix-expr-c
|
||||
l.nix-store-c
|
||||
l.nix-util-c
|
||||
l.nix-flake-c
|
||||
]
|
||||
else
|
||||
[ config.packages.nix ]
|
||||
);
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkg-config
|
||||
];
|
||||
# bindgen uses clang to generate bindings, but it doesn't know where to
|
||||
# find our stdenv cc's headers, so when it's gcc, we need to tell it.
|
||||
postConfigure = lib.optionalString pkgs.stdenv.cc.isGNU ''
|
||||
source ${./bindgen-gcc.sh}
|
||||
'';
|
||||
# Prepare the environment for Nix to work.
|
||||
# Nix does not provide a suitable environment for running itself in
|
||||
# the sandbox - not by default. We configure it to use a relocated store.
|
||||
|
|
@ -61,26 +40,11 @@
|
|||
echo "experimental-features = ca-derivations flakes" > "$NIX_CONF_DIR/nix.conf"
|
||||
|
||||
# Init ahead of time, because concurrent initialization is flaky
|
||||
${
|
||||
# Not using nativeBuildInputs because this should (hopefully) be
|
||||
# the only place where we need a nix binary. Let's stay in control.
|
||||
pkgs.buildPackages.nix
|
||||
}/bin/nix-store --init
|
||||
${config.nix-bindings-rust.nixPackage}/bin/nix-store --init
|
||||
|
||||
echo "Store initialized."
|
||||
'';
|
||||
};
|
||||
# NOTE: duplicated in flake.nix devShell
|
||||
env = {
|
||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.buildPackages.llvmPackages.clang-unwrapped ];
|
||||
BINDGEN_EXTRA_CLANG_ARGS =
|
||||
# Work around missing [[deprecated]] in clang
|
||||
"-x c++ -std=c++2a";
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.cc.isGNU {
|
||||
# Avoid cc wrapper, because we only need to add the compiler/"system" dirs
|
||||
NIX_CC_UNWRAPPED = "${pkgs.stdenv.cc.cc}/bin/gcc";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue