diff --git a/book/src/building/swiftc-and-cargo/README.md b/book/src/building/swiftc-and-cargo/README.md index 45dc9fab..aece912e 100644 --- a/book/src/building/swiftc-and-cargo/README.md +++ b/book/src/building/swiftc-and-cargo/README.md @@ -70,7 +70,7 @@ func run() { ``` ```sh -# briding-header.h +# bridging-header.h #ifndef BridgingHeader_h #define BridgingHeader_h @@ -134,25 +134,13 @@ chmod +x build-swiftc-links-rust.sh ## Rust links to a Swift native library -Unlike the when we had `swiftc` in the Rust code, you do not need to set the `crate-type` +Unlike when we had `swiftc` linking in the Rust code, you do not need to set the `crate-type` when you have `Cargo` linking in the Swift code. ```rust // build.rs -use std::path::PathBuf; - fn main() { - let out_dir = PathBuf::from("./generated"); - - let bridges = vec!["src/lib.rs"]; - for path in &bridges { - println!("cargo:rerun-if-changed={}", path); - } - - swift_bridge_build::parse_bridges(bridges) - .write_all_concatenated(out_dir, env!("CARGO_PKG_NAME")); - - println!("cargo:rustc-link-lib=static=swiftc_link_rust"); + println!("cargo:rustc-link-lib=static=my_swift"); println!("cargo:rustc-link-search=./"); } ``` @@ -163,9 +151,10 @@ fn main() { #!/bin/bash set -e -# The swift-bridge CLI does not exist yet. Open an issue if you need to use -# this approach and I'll happily whip up the CLI. -swift-bridge -f src/lib.rs > generated +# Generate the bridging headers. +# Multiple files can be supplied with "-f" flag, e.g. "-f file1 -f file2". +# Substitute for the crate name in your Cargo.toml file. +swift-bridge-cli parse-bridges --crate-name -f src/lib.rs -o generated swiftc -emit-library -static -module-name my_swift -import-objc-header bridging-header.h \ lib.swift ./generated/swift-and-rust/swift-and-rust.swift diff --git a/crates/swift-bridge-cli/src/clap_app.rs b/crates/swift-bridge-cli/src/clap_app.rs index df7af06b..31166dd6 100644 --- a/crates/swift-bridge-cli/src/clap_app.rs +++ b/crates/swift-bridge-cli/src/clap_app.rs @@ -1,4 +1,4 @@ -use clap::{Arg, Command}; +use clap::{Arg, ArgAction, Command}; /// The CLI application pub fn cli() -> Command<'static> { @@ -7,6 +7,7 @@ pub fn cli() -> Command<'static> { .version(env!("CARGO_PKG_VERSION")) .subcommand_required(true) .subcommand(create_package_command()) + .subcommand(create_bridges_command()) } /// The command for creating a Swift Package @@ -101,3 +102,35 @@ fn create_package_command() -> Command<'static> { .help("The name for the Swift Package"), ) } + +fn create_bridges_command() -> Command<'static> { + Command::new("parse-bridges") + .about("Parse bridge library files and output generated headers") + .arg( + Arg::new("crate-name") + .action(ArgAction::Set) + .help( + "Crate name for which the bridging headers are generated; \ + used as a part of header names", + ) + .long("--crate-name") + .required(true), + ) + .arg( + Arg::new("source-file") + .action(ArgAction::Append) + .help("source file(s) containing #[swift_bridge::bridge] macro") + .long("file") + .short('f') + .required(true), + ) + .arg( + Arg::new("output") + .action(ArgAction::Set) + .help("Output destination folder") + .long("output") + .short('o') + .value_name("PATH") + .required(true), + ) +} diff --git a/crates/swift-bridge-cli/src/clap_exec.rs b/crates/swift-bridge-cli/src/clap_exec.rs index 7f76087a..096cf916 100644 --- a/crates/swift-bridge-cli/src/clap_exec.rs +++ b/crates/swift-bridge-cli/src/clap_exec.rs @@ -1,13 +1,16 @@ use clap::ArgMatches; use std::collections::HashMap; use std::path::{Path, PathBuf}; -use swift_bridge_build::{create_package, ApplePlatform, CreatePackageConfig}; +use swift_bridge_build::{create_package, parse_bridges, ApplePlatform, CreatePackageConfig}; /// Executes the correct function depending on the cli input pub fn handle_matches(matches: ArgMatches) { match matches.subcommand_name() { - Some("create-package") => { - handle_create_package(matches.subcommand_matches("create-package").unwrap()) + Some(cmd @ "create-package") => { + handle_create_package(matches.subcommand_matches(cmd).unwrap()) + } + Some(cmd @ "parse-bridges") => { + handle_parse_bridges(matches.subcommand_matches(cmd).unwrap()) } _ => unreachable!("No subcommand or unknown subcommand given"), // Shouldn't happen } @@ -16,7 +19,7 @@ pub fn handle_matches(matches: ArgMatches) { /// Executes the `create-package` command fn handle_create_package(matches: &ArgMatches) { let bridges_dir = matches.value_of("bridges-dir").unwrap(); // required - let out_dir = matches.value_of("out-dir").map(|p| Path::new(p)).unwrap(); // required + let out_dir = matches.value_of("out-dir").map(Path::new).unwrap(); // required let name = matches.value_of("name").unwrap(); // required let mut config = CreatePackageConfig { @@ -34,3 +37,12 @@ fn handle_create_package(matches: &ArgMatches) { create_package(config); } + +/// Executes the `parse-bridges` command +fn handle_parse_bridges(matches: &ArgMatches) { + let crate_name = matches.get_one::("crate-name").unwrap(); // required + let source_files: Vec<&String> = matches.get_many("source-file").unwrap().collect(); // required + let output = matches.get_one::("output").map(Path::new).unwrap(); // required + + parse_bridges(source_files.iter().map(Path::new)).write_all_concatenated(output, crate_name); +} diff --git a/crates/swift-bridge-macro/tests/ui/args-into-argument-not-found.rs b/crates/swift-bridge-macro/tests/ui/args-into-argument-not-found.rs index d0d58c21..fa424698 100644 --- a/crates/swift-bridge-macro/tests/ui/args-into-argument-not-found.rs +++ b/crates/swift-bridge-macro/tests/ui/args-into-argument-not-found.rs @@ -15,12 +15,12 @@ mod ffi { } } -fn some_function(arg: u8) {} +fn some_function(_arg: u8) {} struct SomeType; impl SomeType { - fn some_method(&self, foo: u8) {} + fn some_method(&self, _foo: u8) {} } fn main() {}