2024-02-08 15:34:43 +01:00
{
2024-11-26 13:42:34 +01:00
description = " R u s t b i n d i n g s f o r t h e N i x C A P I " ;
2024-02-08 15:34:43 +01:00
inputs = {
flake-parts . url = " g i t h u b : h e r c u l e s - c i / f l a k e - p a r t s " ;
2025-04-02 18:54:19 +02:00
nix . url = " g i t h u b : N i x O S / n i x " ;
2024-02-16 09:14:15 +01:00
nix . inputs . nixpkgs . follows = " n i x p k g s " ;
2025-12-16 01:48:19 +01:00
nix-cargo-integration . url = " g i t h u b : 9 0 - 0 0 8 / n i x - c a r g o - i n t e g r a t i o n " ;
2024-02-08 16:58:45 +01:00
nix-cargo-integration . inputs . nixpkgs . follows = " n i x p k g s " ;
2024-02-08 15:34:43 +01:00
nixpkgs . url = " g i t h u b : N i x O S / n i x p k g s / n i x o s - u n s t a b l e " ;
} ;
2025-08-26 14:52:12 +02:00
outputs =
2025-12-05 16:51:15 -05:00
inputs @ { flake-parts , . . . }:
2025-08-26 14:52:12 +02:00
flake-parts . lib . mkFlake { inherit inputs ; } (
2025-10-27 01:37:18 +01:00
toplevel @ {
2025-08-26 14:52:12 +02:00
lib ,
. . .
} :
2025-10-27 01:37:18 +01:00
let
/* *
Makes perSystem . nix-bindings-rust available .
* /
flake-parts-modules . basic =
{
flake-parts-lib ,
. . .
} :
{
2025-10-27 14:59:29 +01:00
_file = ./flake.nix ;
2025-10-27 01:37:18 +01:00
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 " p k g s . n i x " ;
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 . " m y _ p r o j e c t " . depsDrvConfig = perSystem . config . nix-bindings-rust . nciBuildConfig ;
}
` ` `
'' ;
} ;
} ;
config . nix-bindings-rust = {
nciBuildConfig = {
2025-11-01 15:19:37 -07:00
mkDerivation = rec {
2025-10-27 01:37:18 +01:00
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 }
'' ;
2025-11-01 15:19:37 -07:00
shellHook = postConfigure ;
2025-10-27 01:37:18 +01:00
} ;
# 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 + + - s t d = c + + 2 a " ;
}
// 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 } / b i n / g c c " ;
} ;
} ;
} ;
}
) ;
} ;
/* *
2025-12-28 18:10:36 +01:00
A flake-parts module for dependents to import . Also dogfooded locally
( extra , not required for normal CI ) .
Adds flake checks that test the nix-bindings crates with the
dependent's nix package .
See https://github.com/nixops4/nix-bindings-rust?tab=readme-ov-file #integration-with-nix-projects
2025-10-27 01:37:18 +01:00
* /
flake-parts-modules . tested =
# Consumer toplevel
2025-12-06 15:07:48 -05:00
{ . . . }:
2025-10-27 01:37:18 +01:00
{
2025-10-27 14:59:29 +01:00
_file = ./flake.nix ;
2025-10-27 01:37:18 +01:00
imports = [ flake-parts-modules . basic ] ;
config . perSystem =
# Consumer perSystem
2025-12-06 15:07:48 -05:00
{
2025-10-27 01:37:18 +01:00
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`
2025-12-06 15:07:48 -05:00
_module . args . pkgs = lib . mkForce pkgs ;
2025-10-27 01:37:18 +01:00
# ... and `nixPackage`
2025-12-06 15:07:48 -05:00
nix-bindings-rust . nixPackage = lib . mkForce config . nix-bindings-rust . nixPackage ;
2025-10-27 01:37:18 +01:00
} ;
}
] ;
} ;
in
{
key = " n i x - b i n d i n g s - r u s t - a d d - c h e c k s " ;
2025-12-28 18:10:36 +01:00
# Exclude clippy checks; those are part of this repo's local CI.
# This module is for dependents (and local dogfooding), which
# don't need to run clippy on nix-bindings-rust.
2025-10-27 01:37:18 +01:00
config . checks = lib . concatMapAttrs (
k : v :
2025-12-28 18:10:36 +01:00
lib . optionalAttrs ( lib . strings . hasPrefix " n i x - b i n d i n g s - " k && ! lib . strings . hasSuffix " - c l i p p y " k ) {
2025-10-27 01:37:18 +01:00
" d e p e n d e n c y - ${ k } " = v ;
}
) nix-bindings-rust-perSystemConfig . config . checks ;
} ;
} ;
flake-parts-modules . default = flake-parts-modules . tested ;
in
2025-08-26 14:52:12 +02:00
{
2024-02-08 15:34:43 +01:00
imports = [
2024-02-08 16:58:45 +01:00
inputs . nix-cargo-integration . flakeModule
2024-08-29 16:58:18 +02:00
inputs . flake-parts . flakeModules . partitions
2025-10-27 01:37:18 +01:00
inputs . flake-parts . flakeModules . modules
# dogfood
flake-parts-modules . tested
2025-10-26 23:29:13 +01:00
./nci.nix
2024-02-08 15:34:43 +01:00
] ;
2025-08-26 14:52:12 +02:00
systems = [
" x 8 6 _ 6 4 - l i n u x "
" a a r c h 6 4 - l i n u x "
" x 8 6 _ 6 4 - d a r w i n "
" a a r c h 6 4 - d a r w i n "
] ;
perSystem =
{
inputs' ,
. . .
} :
{
packages . nix = inputs' . nix . packages . nix ;
} ;
2024-08-29 16:58:18 +02:00
partitionedAttrs . devShells = " d e v " ;
partitionedAttrs . checks = " d e v " ;
partitionedAttrs . herculesCI = " d e v " ;
2025-10-27 01:37:18 +01:00
# 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 = " d e v " ;
2024-08-29 16:58:18 +02:00
partitions . dev . extraInputsFlake = ./dev ;
partitions . dev . module = {
imports = [ ./dev/flake-module.nix ] ;
2024-03-19 15:08:52 +01:00
} ;
2025-10-27 01:37:18 +01:00
# 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 = " n i x - b i n d i n g s - r u s t - a d d - c h e c k s " ; } ] ;
} ;
} ;
} ;
# flake output attributes
flake = {
modules . flake = flake-parts-modules ;
} ;
2025-08-26 14:52:12 +02:00
}
) ;
2024-02-08 15:34:43 +01:00
}