diff --git a/Cargo.lock b/Cargo.lock index f142d83..b02e9ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "askama" @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "encode_unicode" @@ -532,18 +532,18 @@ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -640,9 +640,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.58" +version = "2.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" dependencies = [ "proc-macro2", "quote", @@ -832,13 +832,14 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -847,42 +848,48 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/src/commands/package.rs b/src/commands/package.rs index 20d74fb..230be3d 100644 --- a/src/commands/package.rs +++ b/src/commands/package.rs @@ -12,13 +12,13 @@ use execute::{command, Execute}; use indicatif::MultiProgress; use crate::bindings::generate_bindings; +use crate::console::*; use crate::console::{run_step, run_step_with_commands}; use crate::lib_type::LibType; use crate::metadata::{metadata, MetadataExt}; use crate::swiftpackage::{create_swiftpackage, recreate_output_dir}; use crate::targets::*; use crate::xcframework::create_xcframework; -use crate::console::*; #[derive(ValueEnum, Debug, Clone)] #[value()] @@ -48,6 +48,14 @@ impl From for Option { } } +#[derive(Debug, Clone)] +pub struct FeatureOptions { + pub features: Option>, + pub all_features: bool, + pub no_default_features: bool, +} + +#[allow(clippy::too_many_arguments)] pub fn run( platforms: Option>, package_name: Option, @@ -55,6 +63,7 @@ pub fn run( config: Config, mode: Mode, lib_type_arg: LibTypeArg, + features: FeatureOptions, skip_toolchains_check: bool, ) -> Result<()> { // TODO: Allow path as optional argument to take other directories than current directory @@ -72,6 +81,7 @@ pub fn run( &config, mode, lib_type_arg, + features, skip_toolchains_check, ); } else if package_name.is_some() { @@ -90,6 +100,7 @@ pub fn run( &config, mode, lib_type_arg.clone(), + features.clone(), skip_toolchains_check, ) }) @@ -107,6 +118,7 @@ fn run_for_crate( config: &Config, mode: Mode, lib_type_arg: LibTypeArg, + features: FeatureOptions, skip_toolchains_check: bool, ) -> Result<()> { let lib = current_crate @@ -123,7 +135,7 @@ fn run_for_crate( if lib_type == LibType::Dynamic { warning!( - &config, + &config, "Building as dynamic library is discouraged. It might prevent apps that use this library from publishing to the App Store." ); } @@ -157,7 +169,7 @@ fn run_for_crate( let crate_name = lib.name.replace('-', "_"); for target in &targets { - build_with_output(target, &crate_name, mode, lib_type, config)?; + build_with_output(target, &crate_name, mode, lib_type, config, &features)?; } generate_bindings_with_output(&targets, &crate_name, mode, lib_type, config)?; @@ -372,8 +384,9 @@ fn build_with_output( mode: Mode, lib_type: LibType, config: &Config, + features: &FeatureOptions, ) -> Result<()> { - let mut commands = target.commands(lib_name, mode, lib_type); + let mut commands = target.commands(lib_name, mode, lib_type, features); for command in &mut commands { command.env("CARGO_TERM_COLOR", "always"); } diff --git a/src/lib.rs b/src/lib.rs index 6f3985a..1ab79a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,9 +31,9 @@ mod targets; mod templating; mod xcframework; -pub use commands::*; pub use crate::console::error::Result; pub use crate::console::Config; +pub use commands::*; pub use lib_type::LibType; pub use targets::*; diff --git a/src/main.rs b/src/main.rs index f212c9d..fcc0ef0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,10 @@ use std::process::ExitCode; -use cargo_swift::{init, package, Config, LibType, Mode}; +use cargo_swift::{ + init, + package::{self, FeatureOptions}, + Config, LibType, Mode, +}; use clap::{Parser, Subcommand}; #[derive(Parser)] @@ -88,6 +92,15 @@ enum Action { #[arg(long)] /// Disable toolchains check skip_toolchains_check: bool, + + #[arg(short = 'F', long, trailing_var_arg = true)] + features: Option>, + + #[arg(long)] + all_features: bool, + + #[arg(long)] + no_default_features: bool, }, } @@ -111,6 +124,9 @@ fn main() -> ExitCode { release, lib_type, skip_toolchains_check, + features, + all_features, + no_default_features, } => package::run( platforms, package_name, @@ -118,6 +134,11 @@ fn main() -> ExitCode { config, if release { Mode::Release } else { Mode::Debug }, lib_type, + FeatureOptions { + features, + all_features, + no_default_features, + }, skip_toolchains_check, ), }; diff --git a/src/targets.rs b/src/targets.rs index c6f93ae..85cd7e1 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -5,6 +5,7 @@ use nonempty::{nonempty, NonEmpty}; use crate::lib_type::LibType; use crate::metadata::{metadata, MetadataExt}; +use crate::package::FeatureOptions; pub trait TargetInfo { fn target(&self) -> Target; @@ -41,15 +42,32 @@ impl Display for Mode { } impl Target { - fn cargo_build_commands(&self, mode: Mode) -> Vec { - let flag = match mode { - Mode::Debug => "", - Mode::Release => "--release", - }; - + fn cargo_build_commands(&self, mode: Mode, features: &FeatureOptions) -> Vec { self.architectures() .into_iter() - .map(|arch| command(format!("cargo build --target {arch} {flag}"))) + .map(|arch| { + let mut cmd = command("cargo build"); + cmd.arg("--target").arg(arch); + + match mode { + Mode::Debug => {} + Mode::Release => { + cmd.arg("--release"); + } + } + + if let Some(features) = &features.features { + cmd.arg("--features").arg(features.join(",")); + } + if features.all_features { + cmd.arg("--all-features"); + } + if features.no_default_features { + cmd.arg("--no-default-features"); + } + + cmd + }) .collect() } @@ -96,8 +114,14 @@ impl Target { /// /// This function returns a list of commands that should be executed in their given /// order to build this target (and bundle architecture targets with lipo if it is a universal target). - pub fn commands(&self, lib_name: &str, mode: Mode, lib_type: LibType) -> Vec { - self.cargo_build_commands(mode) + pub fn commands( + &self, + lib_name: &str, + mode: Mode, + lib_type: LibType, + features: &FeatureOptions, + ) -> Vec { + self.cargo_build_commands(mode, features) .into_iter() .chain(self.lipo_commands(lib_name, mode, lib_type)) .chain(self.rpath_install_id_commands(lib_name, mode, lib_type))