diff --git a/Cargo.toml b/Cargo.toml index b8593e3..6724e28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,11 @@ name = "bdkffi" [dependencies] bdk = { version = "0.14", features = ["all-keys", "use-esplora-ureq"] } -uniffi_macros = "0.16.0" -uniffi = "0.16.0" +uniffi_macros = { version = "0.16.0", features = ["builtin-bindgen"] } +uniffi = { version = "0.16.0", features = ["builtin-bindgen"] } thiserror = "1.0" anyhow = "=1.0.45" # remove after upgrading to next version of uniffi [build-dependencies] -uniffi_build = "0.16.0" +uniffi_build = { version = "0.16.0", features = ["builtin-bindgen"] } +uniffi_bindgen = { version = "0.16.0" } diff --git a/build.rs b/build.rs index 153077f..d72ea90 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,47 @@ -fn main() { - uniffi_build::generate_scaffolding("src/bdk.udl").unwrap(); +use std::fs; +use std::env; +use std::io::Write; +use std::path::Path; + +const BDK_UDL: &str = "src/bdk.udl"; + +fn fixup_python_lib_path>(out_dir: O, lib_name: &str) -> Result<(), Box> { + const LOAD_INDIRECT_DEF: &str = "def loadIndirect():"; + + let bindings_file = out_dir.as_ref().join("bdk.py"); + let mut data = fs::read_to_string(&bindings_file)?; + + let pos = data.find(LOAD_INDIRECT_DEF).expect(&format!("loadIndirect not found in `{}`", bindings_file.display())); + let range = pos..pos + LOAD_INDIRECT_DEF.len(); + + let replacement = format!(r#" +def loadIndirect(): + import glob + return getattr(ctypes.cdll, glob.glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), '{}.*'))[0]) + +def _loadIndirectOld():"#, lib_name); + data.replace_range(range, &replacement); + + let mut file = fs::OpenOptions::new().write(true).truncate(true).open(&bindings_file)?; + file.write(data.as_bytes())?; + + Ok(()) +} + +fn main() { + uniffi_build::generate_scaffolding(BDK_UDL).unwrap(); + + if let Some(lang) = env::var("GENERATE_BINDINGS_LANG").ok() { + let out_path = env::var("GENERATE_BINDINGS_OUT").expect("GENERATE_BINDINGS_OUT must be set when GENERATE_BINDINGS_LANG is"); + uniffi_bindgen::generate_bindings(BDK_UDL, None, vec![&lang], Some(&out_path), false).unwrap(); + + match (lang.as_ref(), env::var("GENERATE_BINDINGS_FIXUP_LIB_PATH").ok()) { + ("python", Some(name)) => fixup_python_lib_path(&out_path, &name).unwrap(), + _ => {}, + } + } + + println!("cargo:rerun-if-changed=GENERATE_BINDINGS_LANG"); + println!("cargo:rerun-if-changed=GENERATE_BINDINGS_OUT"); + println!("cargo:rerun-if-changed=GENERATE_BINDINGS_FIXUP_LIB_PATH"); }