Generate bindings for Python in build.rs

This commit is contained in:
Alekos Filini 2021-12-16 15:14:05 +01:00
parent 15c0dac622
commit edfcde1cc6
2 changed files with 50 additions and 5 deletions

View File

@ -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" }

View File

@ -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<O: AsRef<Path>>(out_dir: O, lib_name: &str) -> Result<(), Box<dyn std::error::Error>> {
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");
}