feat: consume the vendor's generated FFI bindings in waku-sys

nim-ffi 0.2.0 generates the Rust bindings from the Nim source, so
bindgen over the hand-written headers is no longer the source of truth
-- and could not be, since those headers describe the pre-CBOR ABI.

The generated sources are referenced in place under vendor rather than
copied, so regenerating them in logos-delivery flows straight through
with nothing to keep in sync. They stay sibling modules because api.rs
resolves its neighbours through `super::`.

build.rs keeps driving the build: it runs the vendor's make target,
scans for the version-and-hash-named nimble package dirs and librln, and
emits the miniupnpc / natpmp / c++ link flags. The generated build.rs
does none of that (it runs a bare `nim c --mm:orc` against a path that
does not resolve here), so only the bindgen half is dropped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ivan FB 2026-07-16 00:56:16 +02:00
parent 96499cc735
commit 98d005c9e1
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270
4 changed files with 30 additions and 36 deletions

View File

@ -31,8 +31,12 @@ exclude = [
crate-type = ["rlib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# Mirrors the Cargo.toml the vendor's genBindings() emits alongside the sources.
[dependencies]
serde = { version = "1", features = ["derive"] }
ciborium = "0.2"
flume = { version = "0.11", default-features = false, features = ["async"] }
tokio = { version = "1", features = ["sync", "time"] }
[build-dependencies]
bindgen = "0.64"
cc = "1.0.73"

View File

@ -112,14 +112,15 @@ fn find_librln(nwaku_path: &Path) -> String {
})
}
fn generate_bindgen_code(project_dir: &Path) {
fn emit_link_flags(project_dir: &Path) {
let nwaku_path = project_dir.join("vendor");
// The kernel header includes the stable one, so this single entry point
// yields both the low-level waku_* tier and the logosdelivery_* messaging
// and reliable-channel surface.
let header_path = nwaku_path.join("library/liblogosdelivery_kernel.h");
println!("cargo:rerun-if-changed={}", header_path.display());
// The FFI surface is generated by the vendor's genBindings() rather than
// bindgen, so the sources it emits are what invalidates this crate.
println!(
"cargo:rerun-if-changed={}",
nwaku_path.join("library/rust_bindings/src").display()
);
println!(
"cargo:rustc-link-search={}",
nwaku_path.join("build").display()
@ -166,25 +167,6 @@ fn generate_bindgen_code(project_dir: &Path) {
.file("src/cmd.c") // Compile the C file
.compile("cmditems"); // Compile it as a library
println!("cargo:rustc-link-lib=static=cmditems");
// Generate waku bindings with bindgen
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header(format!("{}", header_path.display()))
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
#[cfg(not(doc))]
@ -193,5 +175,5 @@ fn main() {
submodules_init(&project_dir);
build_nwaku_lib(&project_dir);
generate_bindgen_code(&project_dir);
emit_link_flags(&project_dir);
}

View File

@ -1,9 +1,17 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::derive_partial_eq_without_eq)]
#![allow(clippy::useless_transmute)]
#![allow(clippy::too_many_arguments)]
#![allow(improper_ctypes)]
//! Bindings to liblogosdelivery, generated by nim-ffi's `genBindings()` from the
//! vendor's `library/liblogosdelivery.nim`.
//!
//! The generated sources are consumed in place rather than copied, so
//! regenerating them in the vendor flows through here directly. `api.rs`
//! resolves its siblings through `super::`, so the three have to stay sibling
//! modules of this root.
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
#[path = "../vendor/library/rust_bindings/src/ffi.rs"]
mod ffi;
#[path = "../vendor/library/rust_bindings/src/types.rs"]
mod types;
#[path = "../vendor/library/rust_bindings/src/api.rs"]
mod api;
pub use api::*;
pub use types::*;

@ -1 +1 @@
Subproject commit 77cb8a6c7a199b7823e5149bb72f8ce384883b8f
Subproject commit 7080a629da867f37b0e2e5f6012c5cffc150671d