Merge pull request #16 from nixops4/downstream-settings
Add module for downstream setup
This commit is contained in:
commit
7a187fda7a
4 changed files with 224 additions and 47 deletions
33
README.md
33
README.md
|
|
@ -3,6 +3,39 @@
|
||||||
|
|
||||||
Use the Nix [C API] from Rust.
|
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
|
## Hacking
|
||||||
|
|
||||||
The following will open a shell with dependencies, and install pre-commit for automatic formatting.
|
The following will open a shell with dependencies, and install pre-commit for automatic formatting.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
lib,
|
|
||||||
inputs,
|
inputs,
|
||||||
withSystem,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
|
@ -10,8 +8,14 @@
|
||||||
inputs.hercules-ci-effects.flakeModule
|
inputs.hercules-ci-effects.flakeModule
|
||||||
];
|
];
|
||||||
perSystem =
|
perSystem =
|
||||||
{ config, pkgs, ... }:
|
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
inputs',
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
nix-bindings-rust.nixPackage = inputs'.nix.packages.default;
|
||||||
|
|
||||||
pre-commit.settings.hooks.nixfmt-rfc-style.enable = true;
|
pre-commit.settings.hooks.nixfmt-rfc-style.enable = true;
|
||||||
# Temporarily disable rustfmt due to configuration issues
|
# Temporarily disable rustfmt due to configuration issues
|
||||||
|
|
@ -86,7 +90,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
herculesCI =
|
herculesCI =
|
||||||
hci@{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
ciSystems = [ "x86_64-linux" ];
|
ciSystems = [ "x86_64-linux" ];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
178
flake.nix
178
flake.nix
|
|
@ -13,14 +13,160 @@
|
||||||
outputs =
|
outputs =
|
||||||
inputs@{ self, flake-parts, ... }:
|
inputs@{ self, flake-parts, ... }:
|
||||||
flake-parts.lib.mkFlake { inherit inputs; } (
|
flake-parts.lib.mkFlake { inherit inputs; } (
|
||||||
{
|
toplevel@{
|
||||||
lib,
|
lib,
|
||||||
|
withSystem,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
/**
|
||||||
|
Makes perSystem.nix-bindings-rust available.
|
||||||
|
*/
|
||||||
|
flake-parts-modules.basic =
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
flake-parts-lib,
|
||||||
|
withSystem,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
_file = ./flake.nix;
|
||||||
|
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, ... }:
|
||||||
|
{
|
||||||
|
_file = ./flake.nix;
|
||||||
|
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 = [
|
imports = [
|
||||||
inputs.nix-cargo-integration.flakeModule
|
inputs.nix-cargo-integration.flakeModule
|
||||||
inputs.flake-parts.flakeModules.partitions
|
inputs.flake-parts.flakeModules.partitions
|
||||||
|
inputs.flake-parts.flakeModules.modules
|
||||||
|
# dogfood
|
||||||
|
flake-parts-modules.tested
|
||||||
./nci.nix
|
./nci.nix
|
||||||
];
|
];
|
||||||
systems = [
|
systems = [
|
||||||
|
|
@ -44,10 +190,40 @@
|
||||||
partitionedAttrs.devShells = "dev";
|
partitionedAttrs.devShells = "dev";
|
||||||
partitionedAttrs.checks = "dev";
|
partitionedAttrs.checks = "dev";
|
||||||
partitionedAttrs.herculesCI = "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.extraInputsFlake = ./dev;
|
||||||
partitions.dev.module = {
|
partitions.dev.module = {
|
||||||
imports = [ ./dev/flake-module.nix ];
|
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 = {
|
nci.projects.nix-bindings = {
|
||||||
path = ./.;
|
path = ./.;
|
||||||
drvConfig = {
|
drvConfig = {
|
||||||
|
imports = [
|
||||||
|
# Downstream projects import this into depsDrvConfig instead
|
||||||
|
config.nix-bindings-rust.nciBuildConfig
|
||||||
|
];
|
||||||
|
# Extra settings for running the tests
|
||||||
mkDerivation = {
|
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.
|
# Prepare the environment for Nix to work.
|
||||||
# Nix does not provide a suitable environment for running itself in
|
# Nix does not provide a suitable environment for running itself in
|
||||||
# the sandbox - not by default. We configure it to use a relocated store.
|
# 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"
|
echo "experimental-features = ca-derivations flakes" > "$NIX_CONF_DIR/nix.conf"
|
||||||
|
|
||||||
# Init ahead of time, because concurrent initialization is flaky
|
# Init ahead of time, because concurrent initialization is flaky
|
||||||
${
|
${config.nix-bindings-rust.nixPackage}/bin/nix-store --init
|
||||||
# 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
|
|
||||||
|
|
||||||
echo "Store initialized."
|
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