Skip to content

Commit

Permalink
Bundle all headers and swift files for multi-crate UniFFI setups
Browse files Browse the repository at this point in the history
  • Loading branch information
KingOfDog committed Apr 4, 2024
1 parent ddbdbcc commit e21a2fd
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 28 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }

Expand Down
33 changes: 19 additions & 14 deletions src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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(())
}
7 changes: 3 additions & 4 deletions src/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down Expand Up @@ -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())
})
}
Expand Down Expand Up @@ -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(|| {
Expand Down
28 changes: 19 additions & 9 deletions src/swiftpackage.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use askama::Template;
use glob::glob;
use std::fs::{copy, create_dir_all, write};

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 {
Expand All @@ -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(())
}
Expand Down

0 comments on commit e21a2fd

Please sign in to comment.