diff --git a/Cargo.toml b/Cargo.toml index 7fedfd2..0573f6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,10 @@ version = "0.4.1" authors = ["Steve Myers ", "Sudarsan Balaji "] edition = "2018" +[workspace] +members = [".","bdk-ffi-bindgen"] +default-members = [".", "bdk-ffi-bindgen"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["staticlib", "cdylib"] @@ -17,13 +21,6 @@ rusqlite = { version = "0.25.3", features = ["bundled"] } 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 -uniffi_bindgen = "0.16.0" -structopt = "0.3" [build-dependencies] uniffi_build = { version = "0.16.0", features = ["builtin-bindgen"] } - -[[bin]] -name = "generate-bindings" diff --git a/bdk-ffi-bindgen/Cargo.toml b/bdk-ffi-bindgen/Cargo.toml new file mode 100644 index 0000000..994fc15 --- /dev/null +++ b/bdk-ffi-bindgen/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "bdk-ffi-bindgen" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "=1.0.45" # remove after upgrading to next version of uniffi +structopt = "0.3" +uniffi_bindgen = "0.16.0" diff --git a/src/bin/generate-bindings.rs b/bdk-ffi-bindgen/src/main.rs similarity index 73% rename from src/bin/generate-bindings.rs rename to bdk-ffi-bindgen/src/main.rs index 04f69f2..4e26f37 100644 --- a/src/bin/generate-bindings.rs +++ b/bdk-ffi-bindgen/src/main.rs @@ -1,10 +1,9 @@ use std::fmt; +use std::path::PathBuf; use std::str::FromStr; use structopt::StructOpt; use uniffi_bindgen; -pub const BDK_UDL: &str = "src/bdk.udl"; - #[derive(Debug, PartialEq)] pub enum Language { KOTLIN, @@ -47,7 +46,7 @@ impl FromStr for Language { fn generate_bindings(opt: &Opt) -> anyhow::Result<(), anyhow::Error> { uniffi_bindgen::generate_bindings( - &format!("{}/{}", env!("CARGO_MANIFEST_DIR"), BDK_UDL), + &opt.udl_file, None, vec![opt.language.to_string().as_str()], Some(&opt.out_dir), @@ -57,16 +56,16 @@ fn generate_bindings(opt: &Opt) -> anyhow::Result<(), anyhow::Error> { Ok(()) } -fn fixup_python_lib_path>( - out_dir: O, - lib_name: &str, +fn fixup_python_lib_path( + out_dir: &PathBuf, + lib_name: &PathBuf, ) -> Result<(), Box> { use std::fs; use std::io::Write; const LOAD_INDIRECT_DEF: &str = "def loadIndirect():"; - let bindings_file = out_dir.as_ref().join("bdk.py"); + let bindings_file = out_dir.join("bdk.py"); let mut data = fs::read_to_string(&bindings_file)?; let pos = data.find(LOAD_INDIRECT_DEF).expect(&format!( @@ -82,7 +81,7 @@ def loadIndirect(): return getattr(ctypes.cdll, glob.glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), '{}.*'))[0]) def _loadIndirectOld():"#, - lib_name + &lib_name.to_str().expect("lib name") ); data.replace_range(range, &replacement); @@ -97,34 +96,39 @@ def _loadIndirectOld():"#, #[derive(Debug, StructOpt)] #[structopt( - name = "generate-bindings", + name = "bdk-ffi-bindgen", about = "A tool to generate bdk-ffi language bindings" )] struct Opt { + /// UDL file + #[structopt(env = "BDKFFI_BINDGEN_UDL", short, long, default_value("src/bdk.udl"), parse(try_from_str = PathBuf::from_str))] + udl_file: PathBuf, + /// Language to generate bindings for - #[structopt(env = "UNIFFI_BINDGEN_LANGUAGE", short, long, possible_values(&["kotlin","swift","python"]), parse(try_from_str = Language::from_str))] + #[structopt(env = "BDKFFI_BINDGEN_LANGUAGE", short, long, possible_values(&["kotlin","swift","python"]), parse(try_from_str = Language::from_str))] language: Language, /// Output directory to put generated language bindings - #[structopt(env = "UNIFFI_BINDGEN_OUTPUT_DIR", short, long)] - out_dir: String, + #[structopt(env = "BDKFFI_BINDGEN_OUTPUT_DIR", short, long, parse(try_from_str = PathBuf::from_str))] + out_dir: PathBuf, /// Python fix up lib path - #[structopt(env = "UNIFFI_BINDGEN_PYTHON_FIXUP_PATH", short, long)] - python_fixup_path: Option, + #[structopt(env = "BDKFFI_BINDGEN_PYTHON_FIXUP_PATH", short, long, parse(try_from_str = PathBuf::from_str))] + python_fixup_path: Option, } fn main() -> Result<(), Box> { let opt = Opt::from_args(); + println!("Input UDL file is {:?}", opt.udl_file); println!("Chosen language is {}", opt.language); - println!("Output directory is {}", opt.out_dir); + println!("Output directory is {:?}", opt.out_dir); generate_bindings(&opt)?; if opt.language == Language::PYTHON { - if let Some(path) = &opt.python_fixup_path { - println!("Fixing up python lib path, {}", &path); + if let Some(path) = opt.python_fixup_path { + println!("Fixing up python lib path, {:?}", &path); fixup_python_lib_path(&opt.out_dir, &path)?; } } diff --git a/src/bin/generate.rs b/src/bin/generate.rs deleted file mode 100644 index fc6ecf8..0000000 --- a/src/bin/generate.rs +++ /dev/null @@ -1,67 +0,0 @@ -pub const BDK_UDL: &str = "src/bdk.udl"; - -#[cfg(feature = "generate-python")] -fn fixup_python_lib_path>( - out_dir: O, - lib_name: &str, -) -> Result<(), Box> { - use std::fs; - use std::io::Write; - - 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(()) -} - -#[cfg(feature = "generate-python")] -fn generate_python() -> Result<(), Box> { - use std::env; - - let out_path = env::var("GENERATE_PYTHON_BINDINGS_OUT") - .map_err(|_| String::from("`GENERATE_PYTHON_BINDINGS_OUT` env variable missing"))?; - uniffi_bindgen::generate_bindings( - &format!("{}/{}", env!("CARGO_MANIFEST_DIR"), BDK_UDL), - None, - vec!["python"], - Some(&out_path), - false, - )?; - - if let Some(name) = env::var("GENERATE_PYTHON_BINDINGS_FIXUP_LIB_PATH").ok() { - fixup_python_lib_path(&out_path, &name)?; - } - - Ok(()) -} - -fn main() -> Result<(), Box> { - #[cfg(feature = "generate-python")] - generate_python()?; - Ok(()) -}