produce libnixide-c bindings

This commit is contained in:
do butterflies cry? 2026-04-10 11:51:27 +10:00
parent 93d76c002e
commit 9f90e0c323
Signed by: cry
GPG key ID: F68745A836CA0412
7 changed files with 60 additions and 40 deletions

View file

@ -1,5 +1,6 @@
use std::env;
use std::fs;
use std::iter;
use std::path::PathBuf;
use bindgen::RustEdition;
@ -76,36 +77,41 @@ impl ParseCallbacks for BindfmtCallbacks {
}
}
const LIBS: &[&'static str] = &[
const FEATURES: &[&'static str] = &[
#[cfg(feature = "nix-util-c")]
"nix-util-c",
"util",
#[cfg(feature = "nix-store-c")]
"nix-store-c",
"store",
#[cfg(feature = "nix-expr-c")]
"nix-expr-c",
"expr",
#[cfg(feature = "nix-fetchers-c")]
"nix-fetchers-c",
"fetchers",
#[cfg(feature = "nix-flake-c")]
"nix-flake-c",
"flake",
#[cfg(feature = "nix-main-c")]
"nix-main-c",
"main",
];
fn main() {
let libs: Vec<pkg_config::Library> = LIBS
let libs: Vec<pkg_config::Library> = FEATURES
.iter()
.map(|&name| {
.map(|&feature| {
let name = &format!("nix-{feature}-c");
pkg_config::probe_library(name).expect(&format!("Unable to find .pc file for {}", name))
})
.collect();
#[allow(unused)]
let include_paths: Vec<PathBuf> = libs
.clone()
.into_iter()
.map(|lib| lib.include_paths)
.flatten()
.chain(iter::once(fs::canonicalize("./libnixide-c").unwrap()))
.unique()
.collect();
#[allow(unused)]
let link_paths: Vec<PathBuf> = libs
.clone()
.into_iter()
@ -114,20 +120,7 @@ fn main() {
.unique()
.collect();
// ::DEBUG:DEBUG::
// for path in link_paths {
// println!("cargo::rustc-link-lib={}", path.display());
// }
// ::DEBUG:DEBUG::
let clang_args: Vec<String> = vec!["-x", "c++", "-std=c++23"]
.into_iter()
.map(|s: &str| s.to_owned())
.chain(include_paths.iter().map(|p| format!("-I{}", p.display())))
.collect();
dbg!(&clang_args);
// build the libnixide-c extension
cc::Build::new()
// .cargo_output(true)
// .cargo_warnings(true)
@ -135,15 +128,19 @@ fn main() {
// .cargo_debug(cfg!(debug_assertions))
.cpp(true)
.std("c++23") // libnix compiles against `-std=c++23`
.cpp_link_stdlib("stdc++") // use libstdc++
.flags(["-fconcepts-diagnostics-depth=2"])
.file("libnixide-c/nixide_api_flake.cc")
.file("libnixide-c/nixide_api_fetchers.cc")
// .files(LIBS.iter().map(|s| (*s).strip_prefix("nix-").unwrap().strip_suffix("-c").unwrap()))
.cpp_link_stdlib("c++") // libstdc++ for GNU, c++ for Clang
.opt_level((!cfg!(debug_assertions)) as u32 * 3)
.files(FEATURES.iter().map(|&feature| format!("libnixide-c/nixide_api_{feature}.cc")))
.includes(&include_paths)
.compile("nixide");
.compile("nixide-c"); // libnixide-c
let clang_args: Vec<String> = vec!["-x", "c++", "-std=c++23"]
.into_iter()
.map(|s: &str| s.to_owned())
.chain(include_paths.iter().map(|p| format!("-I{}", p.display())))
.collect();
dbg!(&clang_args);
let mut builder = bindgen::Builder::default()
.rust_edition(RustEdition::Edition2024)
.clang_args(clang_args)
@ -156,8 +153,8 @@ fn main() {
.rustfmt_configuration_file(std::fs::canonicalize("rustfmt.toml").ok())
// Control allow/block listing
.allowlist_recursively(true)
// .allowlist_file(r".*nix_api_[a-z]+(_internal)?\.h")
.allowlist_file(r".*nix_api_[a-z]+(/[a-z_]+)?\.h")
.allowlist_file(r".*nixide_api_[a-z]+(/[a-z_]+)?\.h")
// .layout_tests(false) // DEBUG
.use_core() // use ::core instead of ::std
@ -181,10 +178,10 @@ fn main() {
.raw_line("/** These bindings were auto-generated for the Nixide project (https://github.com/cry128/nixide) */");
// Register the input headers we would like to generate bindings for
builder = LIBS
builder = FEATURES
.iter()
.map(|lib| {
let path = format!("include/{}.h", lib.strip_suffix("-c").unwrap());
.map(|&feature| {
let path = format!("include/nix-{feature}.h");
assert!(fs::exists(&path).unwrap());
// Invalidate the built crate if the binding headers change
println!("cargo::rerun-if-changed={path}");

View file

@ -2,8 +2,8 @@
#define NIXIDE_EXPR
// Nix C API for the Nix expressions evaluator.
//
#include <nix_api_expr.h>
// #include <nix_api_expr_internal.h>
// Nix C API for value manipulation.
//
@ -13,4 +13,8 @@
//
#include <nix_api_external.h>
// Nixide C API extensions for the Nix expressions evaluator.
//
#include <nixide_api_expr.h>
#endif

View file

@ -1,10 +1,12 @@
#ifndef NIXIDE_FETCHERS
#define NIXIDE_FETCHERS
// #include <nix_api_fetchers_internal.hh>
// Nix C API for fetcher operations.
//
#include <nix_api_fetchers.h>
// Nixide C API extensions for fetcher operations.
//
#include <nixide_api_fetchers.h>
#endif

View file

@ -1,10 +1,12 @@
#ifndef NIXIDE_FLAKE
#define NIXIDE_FLAKE
// #include <nix_api_flake_internal.hh>
// Nix C API for flake support.
//
#include <nix_api_flake.h>
// Nixide C API extensions for flake support.
//
#include <nixide_api_flake.h>
#endif

View file

@ -5,4 +5,8 @@
//
#include <nix_api_main.h>
// Nixide C API extensions for CLI support.
//
#include <nixide_api_main.h>
#endif

View file

@ -4,9 +4,17 @@
// Nix C API for store operations.
//
#include <nix_api_store.h>
// #include <nix_api_store_internal.h>
// Nix C API for derivation operations that don't require a store.
//
#include <nix_api_store/derivation.h>
// Nix C API for store path operations that don't require a store.
//
#include <nix_api_store/store_path.h>
// Nixide C API extensions for store operations.
//
#include <nixide_api_store.h>
#endif

View file

@ -8,6 +8,9 @@
// the Nix C APIs for error handling.
//
#include <nix_api_util.h>
// #include <nix_api_util_internal.h>
// Nixide C API extensions for utilities.
//
#include <nixide_api_util.h>
#endif