From e21a2fd790bb6caddf278c5aa4353f53c0649f41 Mon Sep 17 00:00:00 2001 From: KingOfDog Date: Thu, 4 Apr 2024 14:27:37 +0200 Subject: [PATCH] Bundle all headers and swift files for multi-crate UniFFI setups --- Cargo.lock | 3 ++- Cargo.toml | 1 + src/bindings.rs | 33 +++++++++++++++++++-------------- src/commands/package.rs | 7 +++---- src/swiftpackage.rs | 28 +++++++++++++++++++--------- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe68615..83ca837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "cargo-swift" -version = "0.6.1" +version = "0.7.0" dependencies = [ "anyhow", "askama", @@ -152,6 +152,7 @@ dependencies = [ "convert_case", "dialoguer", "execute", + "glob", "indicatif", "itertools", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 07816b1..b6fbf17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ camino = "1.1.6" cargo_metadata = "0.18.1" clap = { version = "4.5.4", features = ["derive"] } convert_case = "0.6.0" +glob = "0.3.1" nonempty = "0.10.0" serde = { version = "1.0.197", features = ["derive"] } diff --git a/src/bindings.rs b/src/bindings.rs index 174ff07..abe4bc0 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -7,7 +7,7 @@ use uniffi_bindgen::bindings::swift::gen_swift::SwiftBindingGenerator; use crate::recreate_dir; /// Generates UniFFI bindings for crate and returns the .udl namespace -pub fn generate_bindings(lib_path: &Utf8Path, crate_name: &str) -> Result<()> { +pub fn generate_bindings(lib_path: &Utf8Path) -> Result<()> { let out_dir = Utf8Path::new("./generated"); let headers = out_dir.join("headers"); let sources = out_dir.join("sources"); @@ -16,26 +16,31 @@ pub fn generate_bindings(lib_path: &Utf8Path, crate_name: &str) -> Result<()> { create_dir(&headers)?; create_dir(&sources)?; - uniffi_bindgen::library_mode::generate_bindings( + let uniffi_outputs = uniffi_bindgen::library_mode::generate_bindings( lib_path, - Some(crate_name.to_owned()), + None, &SwiftBindingGenerator {}, None, out_dir, false, )?; - fs::copy( - out_dir.join(format!("{crate_name}.swift")), - sources.join(format!("{crate_name}.swift")), - )?; - - let header = format!("{crate_name}FFI.h"); - fs::copy(out_dir.join(&header), headers.join(&header))?; - fs::copy( - out_dir.join(format!("{crate_name}FFI.modulemap")), - headers.join("module.modulemap"), - )?; + for output in uniffi_outputs { + let file_name = output.config.module_name(); + fs::copy( + out_dir.join(format!("{file_name}.swift")), + sources.join(format!("{file_name}.swift")), + )?; + + fs::copy( + out_dir.join(output.config.header_filename()), + headers.join(output.config.header_filename()), + )?; + fs::copy( + out_dir.join(output.config.modulemap_filename()), + headers.join(output.config.modulemap_filename()), + )?; + } Ok(()) } diff --git a/src/commands/package.rs b/src/commands/package.rs index 2418ca7..20d74fb 100644 --- a/src/commands/package.rs +++ b/src/commands/package.rs @@ -164,7 +164,7 @@ fn run_for_crate( recreate_output_dir(&package_name).expect("Could not create package output directory!"); create_xcframework_with_output(&targets, &crate_name, &package_name, mode, lib_type, config)?; - create_package_with_output(&package_name, &crate_name, disable_warnings, config)?; + create_package_with_output(&package_name, disable_warnings, config)?; Ok(()) } @@ -361,7 +361,7 @@ fn generate_bindings_with_output( let arch = archs.first(); let lib_path: Utf8PathBuf = format!("{target}/{arch}/{mode}/{lib_file}").into(); - generate_bindings(&lib_path, lib_name) + generate_bindings(&lib_path) .map_err(|e| format!("Could not generate UniFFI bindings for udl files due to the following error: \n {e}").into()) }) } @@ -415,14 +415,13 @@ fn create_xcframework_with_output( fn create_package_with_output( package_name: &str, - namespace: &str, disable_warnings: bool, config: &Config, ) -> Result<()> { run_step( config, format!("Creating Swift Package '{package_name}'..."), - || create_swiftpackage(package_name, namespace, disable_warnings), + || create_swiftpackage(package_name, disable_warnings), )?; let spinner = config.silent.not().then(|| { diff --git a/src/swiftpackage.rs b/src/swiftpackage.rs index 9230f57..4547652 100644 --- a/src/swiftpackage.rs +++ b/src/swiftpackage.rs @@ -1,4 +1,5 @@ use askama::Template; +use glob::glob; use std::fs::{copy, create_dir_all, write}; use crate::{recreate_dir, templating, Result}; @@ -6,7 +7,7 @@ use crate::{recreate_dir, templating, Result}; /// Create artifacts for a swift package given the package name /// /// **Note**: This method assumes that a directory with the package name and the .xcframework already exists -pub fn create_swiftpackage(package_name: &str, namespace: &str, disable_warnings: bool) -> Result<()> { +pub fn create_swiftpackage(package_name: &str, disable_warnings: bool) -> Result<()> { // TODO: Instead of assuming the directory and the xcframework, let this manage directory // recreation and let it copy the xcframework let package_manifest = templating::PackageSwift { @@ -23,14 +24,23 @@ pub fn create_swiftpackage(package_name: &str, namespace: &str, disable_warnings create_dir_all(format!("{}/Sources/{}", package_name, package_name)) .map_err(|e| format!("Could not create module sources directory: \n {e}"))?; - copy( - format!("./generated/sources/{namespace}.swift"), - format!( - "{}/Sources/{}/{}.swift", - package_name, package_name, namespace - ), - ) - .map_err(|e| format!("Could not copy generated swift source files: \n {e}"))?; + for swift_file in glob("./generated/sources/*.swift") + .map_err(|e| format!("Could not find generated swift source files: \n {e}"))? + { + let swift_file = swift_file + .map_err(|e| format!("Could not find generated swift source file: \n {e}"))?; + let file_name = swift_file + .file_name() + .ok_or("Could not get file name")? + .to_str() + .ok_or("Could not convert file name to string")? + .to_string(); + copy( + swift_file, + format!("{}/Sources/{}/{}", package_name, package_name, file_name), + ) + .map_err(|e| format!("Could not copy generated swift source files: \n {e}"))?; + } Ok(()) }