antoniusnaumann / cargo-swift Goto Github PK
View Code? Open in Web Editor NEWA cargo plugin to easily build Swift packages from Rust code
Home Page: https://crates.io/crates/cargo-swift
License: Apache License 2.0
A cargo plugin to easily build Swift packages from Rust code
Home Page: https://crates.io/crates/cargo-swift
License: Apache License 2.0
Hello,
Firstly, a heartfelt thank you for the incredible work you've done!
I'd like to express my interest in proc-macro support, eliminating the need for a .udl file. I believe this enhancement could significantly simplify the initial learning curve for those venturing into a shared codebase in Rust.
I recognize that this is a substantial request, and a "spoiled" one, but I hope you bear with me.
i run cargo swift package -p=ios my lib
Load command 10
cmd LC_BUILD_VERSION
cmdsize 32
platform IOS
minos 17.4
sdk 17.4
ntools 1
tool LD
version 1053.12
Load command 11
cmd LC_SOURCE_VERSION
cmdsize 16
version 0.0
how can i set minos to 14
Rebuilding the Swift package every time is not practical for use cases where custom Swift code or tests on Swift side should be added.
There are multiple solutions to this:
Hi, i noticed that the build fails because it complains about unsafe build flags. This change was introduced by the SPM team. I am running Xcode 15.0.1. Here i get this error. However, the fix seems pretty simple. Pull Request is on its way
Hello,
I apologize if this isn't ideal to open a issue for this inquiry. I'm new to Rust and attempting to work through the example provided.
cargo swift init test
cd test
cargo swift package --name Test --platforms ios
Then Im getting this error:
โ Generating Swift bindings...
x Building target iOS
cargo build --target aarch64-apple-ios --target-dir ./target
Failed due to the following error:
Updating crates.io index
Compiling proc-macro2 v1.0.67
Compiling unicode-ident v1.0.12
Compiling serde v1.0.188
Compiling thiserror v1.0.48
Compiling serde_json v1.0.107
Compiling camino v1.1.6
Compiling semver v1.0.18
Compiling anyhow v1.0.75
Compiling version_check v0.9.4
Compiling paste v1.0.14
Compiling minimal-lexical v0.2.1
Compiling unicase v2.7.0
Compiling itoa v1.0.9
Compiling memchr v2.6.3
Compiling ryu v1.0.15
Compiling nom v7.1.3
Compiling mime v0.3.17
Compiling once_cell v1.18.0
Compiling bytes v1.5.0
Compiling log v0.4.20
Compiling siphasher v0.3.11
Compiling askama_escape v0.10.3
Compiling fs-err v2.9.0
Compiling plain v0.2.3
Compiling weedle2 v4.0.0
Compiling heck v0.4.1
Compiling glob v0.3.1
error[E0463]: can't find crate for `core`
|
= note: the `aarch64-apple-ios` target may not be installed
= help: consider downloading the target with `rustup target add aarch64-apple-ios`
error[E0463]: can't find crate for `compiler_builtins`
error[E0463]: can't find crate for `core`
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:45:5
|
45 | use core::mem::{self, MaybeUninit};
| ^^^^ can't find crate
|
= note: the `aarch64-apple-ios` target may not be installed
= help: consider downloading the target with `rustup target add aarch64-apple-ios`
error[E0463]: can't find crate for `core`
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:46:5
|
46 | use core::{ptr, slice, str};
| ^^^^ can't find crate
|
= note: the `aarch64-apple-ios` target may not be installed
= help: consider downloading the target with `rustup target add aarch64-apple-ios`
error: cannot find macro `debug_assert_eq` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/udiv128.rs:44:5
|
44 | debug_assert_eq!(quot, n / d as u128);
| ^^^^^^^^^^^^^^^
error: cannot find macro `debug_assert_eq` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/udiv128.rs:45:5
|
45 | debug_assert_eq!(rem as u128, n % d as u128);
| ^^^^^^^^^^^^^^^
error[E0405]: cannot find trait `Default` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:64:6
|
64 | impl Default for Buffer {
| ^^^^^^^ not found in this scope
error[E0405]: cannot find trait `Copy` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:71:6
|
71 | impl Copy for Buffer {}
| ^^^^ not found in this scope
error[E0405]: cannot find trait `Clone` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:73:6
|
73 | impl Clone for Buffer {
| ^^^^^ not found in this scope
error[E0405]: cannot find trait `Copy` in this scope
--> /Users/mha/.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.9/src/lib.rs:109:23
|
109 | pub trait Sealed: Copy {
| ^^^^ not found in this scope
Some errors have detailed explanations: E0405, E0463.
For more information about an error, try `rustc --explain E0405`.
error: could not compile `itoa` (lib) due to 10 previous errors
warning: build failed, waiting for other jobs to finish...
I can't figure out what Im missing.
rustup target list | grep installed
gives me this output:
aarch64-apple-darwin (installed)
aarch64-apple-ios (installed)
aarch64-apple-ios-sim (installed)
x86_64-apple-darwin (installed)
x86_64-apple-ios (installed)
And my active toolchain looks fine as well:
rustup show
Default host: aarch64-apple-darwin
rustup home: /Users/mha/.rustup
installed targets for active toolchain
--------------------------------------
aarch64-apple-darwin
aarch64-apple-ios
aarch64-apple-ios-sim
x86_64-apple-darwin
x86_64-apple-ios
active toolchain
----------------
stable-aarch64-apple-darwin (default)
rustc 1.72.0 (5680fa18f 2023-08-23)
I have of course also tried cargo clean
.
Would you be able to guide me or point me in the right direction?
Hello,
It would be nice if the "generated" .swift
file could be formatted.
Maybe if that isn't enough it could be nice if it was possible to specific some settings to the Package.swift.
Something like:
swiftSettings: [
.unsafeFlags(["-suppress-warnings"]),
]),
I know it is really nice to have ๐ . I just don't like when I get some warnings on my CI ๐
It should be --vcs [one of: git, none] like cargo does with git being the default option that is assumed if not set. (both for backwards compatibility reasons and because it is a sane default)
Create more complex example xcode projects in swift-examples/ to make automated testing more robust & to provide a better reference for beginners.
XCode currently can't use generated package unless xcode project support ios platform.
Discuss which one should be assumed by default. Follow cargo and use debug by default or assume release as default since the package is intended for use in external project?
โฏ cargo swift init test
โ Creating Rust library package...
โ Initializing git repository...
โฏ cd test
โฏ cargo swift package
! Building as dynamic library is discouraged. It might prevent apps that use this library from publishing to the App Store.
โ Swift Package Name ยท Idstool
โ Select Target Platforms ยท macOS, iOS
x Building target macOS
cargo build --target x86_64-apple-darwin
Failed due to the following error:
Updating crates.io index
Compiling proc-macro2 v1.0.78
Compiling unicode-ident v1.0.12
Compiling serde v1.0.196
Compiling anyhow v1.0.79
Compiling version_check v0.9.4
Compiling memchr v2.7.1
Compiling minimal-lexical v0.2.1
Compiling camino v1.1.6
Compiling serde_json v1.0.113
Compiling semver v1.0.21
Compiling autocfg v1.1.0
Compiling thiserror v1.0.56
Compiling unicase v2.7.0
Compiling nom v7.1.3
Compiling fs-err v2.11.0
Compiling itoa v1.0.10
Compiling ryu v1.0.16
Compiling paste v1.0.14
Compiling bytes v1.5.0
Compiling once_cell v1.19.0
Compiling quote v1.0.35
Compiling mime v0.3.17
Compiling askama_parser v0.2.1
Compiling smawk v0.3.2
Compiling unicode-linebreak v0.1.5
Compiling log v0.4.20
Compiling syn v2.0.48
Compiling unicode-width v0.1.11
Compiling siphasher v0.3.11
Compiling mime_guess v2.0.4
Compiling textwrap v0.16.0
Compiling weedle2 v5.0.0
Compiling askama_escape v0.10.3
Compiling plain v0.2.3
Compiling heck v0.4.1
Compiling glob v0.3.1
Compiling oneshot-uniffi v0.1.6
Compiling static_assertions v1.1.0
error[E0463]: can't find crate for `core`
|
= note: the `x86_64-apple-darwin` target may not be installed
= help: consider downloading the target with `rustup target add x86_64-apple-darwin`
error[E0463]: can't find crate for `compiler_builtins`
error[E0463]: can't find crate for `core`
--> /Users/blacktop/.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.20/src/lib.rs:335:1
|
335 | extern crate core as std;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
|
= note: the `x86_64-apple-darwin` target may not be installed
= help: consider downloading the target with `rustup target add x86_64-apple-darwin`
libunwind: malformed __unwind_info at 0x1885DFCA8 bad second level page
<SNIP>
error[E0425]: cannot find function, tuple struct or tuple variant `Some` in this scope
--> /Users/blacktop/.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.20/src/__private_api.rs:29:19
|
29 | .line(Some(line))
| ^^^^ not found in this scope
Some errors have detailed explanations: E0405, E0412, E0425, E0463, E0531.
For more information about an error, try `rustc --explain E0405`.
error: could not compile `log` (lib) due to 89 previous errors
warning: build failed, waiting for other jobs to finish...
This is useful for CI builds.
Discuss whether this should be a "yes to all" option or a "fail if prompt appears" option. The former makes it more robust in CI use cases but is at risk of triggering unexpected actions (e.g. downloading toolchains).
I ran into this error on iOS but not the simulator:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: DYLD 1 Library missing
Library not loaded: /Users/*/librecipes2_lib.dylib
Referenced from: <CF59FA6C-EF6F-3660-B1DA-DA21ADF8B67A> /Volumes/VOLUME/*/recipes^2.app/recipes^2
Reason: tried: '/Users/*/librecipes2_lib.dylib' (no such file), '/private/preboot/Cryptexes/OS/Users/*/librecipes2_lib.dylib' (no such file), '/Users/*/librecipes2_lib.dylib' (no such file), '/usr/local/lib/librecipes2_lib.dylib' (no such file), '/usr/lib/librecipes2_lib.dylib' (no such file, not in dyld cache)
(terminated at launch; ignore backtrace)
After extensive searching I realized the issue is that my rust library had its install id as <my_path>/target/aarch64-apple-ios/debug/deps/librecipes2_lib.dylib
With the help of these articles:
I realized changing it to @rpath/librecipes2_lib.dylib
and rebuilding my XCode project fixed the issue since now the install id could be resolved using the runpath parameter.
My question: is this normal or is something wrong with my rust setup? If this is normal should the id remapping be part of this tool?
I remapped my id by running this on my library:
install_name_tool -id @rpath/librecipes2_lib.dylib librecipes2_lib.dylib
Running cargo build
from current main branch fails with error:
cargo build
Compiling cargo-swift v0.5.1 (/Users/mo/code/cargo-swift)
error[E0659]: `console` is ambiguous
--> src/lib.rs:35:9
|
35 | pub use console::error::Result;
| ^^^^^^^ ambiguous name
|
= note: ambiguous because of multiple potential import sources
= note: `console` could refer to a crate passed with `--extern`
= help: use `::console` to refer to this crate unambiguously
note: `console` could also refer to the module defined here
--> src/lib.rs:7:1
|
7 | / pub(crate) mod console {
8 | | mod command;
9 | | pub mod config;
10 | | pub mod error;
... |
22 | | pub use theme::*;
23 | | }
| |_^
= help: use `crate::console` to refer to this module unambiguously
error[E0659]: `console` is ambiguous
--> src/lib.rs:36:9
|
36 | pub use console::Config;
| ^^^^^^^ ambiguous name
|
= note: ambiguous because of multiple potential import sources
= note: `console` could refer to a crate passed with `--extern`
= help: use `::console` to refer to this crate unambiguously
note: `console` could also refer to the module defined here
--> src/lib.rs:7:1
|
7 | / pub(crate) mod console {
8 | | mod command;
9 | | pub mod config;
10 | | pub mod error;
... |
22 | | pub use theme::*;
23 | | }
| |_^
= help: use `crate::console` to refer to this module unambiguously
For more information about this error, try `rustc --explain E0659`.
error: could not compile `cargo-swift` (lib) due to 2 previous errors
$ cargo version
cargo 1.70.0 (ec8a8a0ca 2023-04-25)
$ rustc --version
rustc 1.70.0 (90c541806 2023-05-31)
cargo swift package does not abort execution when cargo build fails, but instead continues execution, leading to a failed build while the tool reports that the package was built successfully.
Expected behavior:
cargo swift package aborts on build error and prints the error message.
The end-to-end tests should cover all cross products of possible command line arguments to detect regressions or defects early.
This was pretty easy to use! I hit one issue following the instructions and building with a new iOS app.
The package generated by cargo swift package
fails to build when included in an iOS app due to the default Swift settings.
swiftSettings: [
.unsafeFlags(["-suppress-warnings"]),
]
Everything builds and runs if the flags are removed.
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.
// Swift Package: asdf
import PackageDescription;
let package = Package(
name: "asdf",
platforms: [
.iOS(.v13),
.macOS(.v10_15)
],
products: [
.library(
name: "asdf",
targets: ["asdf"]
)
],
dependencies: [ ],
targets: [
.binaryTarget(name: "RustFramework", path: "./RustFramework.xcframework"),
.target(
name: "asdf",
dependencies: [
.target(name: "RustFramework")
],
swiftSettings: [ ]
)
]
)
App Store Publishing fails for apps that use a package that includes a dylib as mentioned in #35
Either deprecate --lib-type dynamic or find out if there is a way to publish apps that contain packages build with this option.
Currently, the init command always initializes a new git repository. This behavior is undesirable, if the parent directory is already contained in a git repository. Either add a --no-git (or --vcs, like cargo init) option or detect automatically if contained in a git repository.
This project currently relies on UniFFI v0.23.0 while the current version is v0.24.3
Therefore we should:
...and look for potential changes required that are required with the new version.
This is a breaking change as UniFFI bindgen v0.24.3 might not be backwards compatible with older versions.
Instead of prompting for build platforms or package name every time, check for a .toml config that allows storing those values.
Description:
I've encountered a version mismatch issue between the uniffi_contract_version generated by the uniffi 0.26 library and the bindings_contract_version generated by cargo swift. This mismatch leads to compatibility problems and runtime errors when attempting to use generated bindings with the Rust library.
This is feasible once #32 is implemented.
Currently blocked by the uniffi::setup_scaffolding!() macro not being included in a crates.io release (as of UniFFI 24.3)
Add a --save flag to the package command, to store selected options on first run.
This issue is closely related to #5
After selecting the desired target platforms, the package command should check whether all required toolchains are already installed and ask the user if they want to install the toolchains, if some are missing. If the user declines, packaging should be aborted with a warning.
As cargo swift
depends on uniffi-bindgen, it might be possible that users try to
Cargo.toml
Hi, thanks for this tool! I was building something similar and found this.
I'm moving from cbindgen and simple xcframeworks to using uniffi and cargo-swift to generate the swift package.
My Rust crate has some differences between the API's exposed for iOS and macOS.
This works fine with xcframeworks, since each target platform has its own set of headers and library within the xcframework.
The generated Greeter
swift package for the hello-world
example only a single header file, but does contain an xcframework.
This code in package.rs
seems to generate bindings for the first provided architecture only:
let archs = targets
.first()
.ok_or("Could not generate UniFFI bindings: No target platform selected!")?
.architectures();
let arch = archs.first();
let lib_path: Utf8PathBuf = format!("{target}/{arch}/{mode}/{lib_file}").into();
Question: Is this due to a limitation of swift packages, or can the generated swift package have multiple swift files, with conditional expressions to indicate which target platform each file is for?
Update: I found this document which indicates that conditional target dependencies are supported by swift packages.
In light of the above, could we please change cargo-swift to emit swift files with conditional dependencies per target os?
As mentioned in the UniFFI docs, library mode, which was introduced in UniFFI 0.24 will become the default.
Currently, cargo swift just assumes that there is exactly one .udl file named lib.udl, resulting in an error when not present. Omitting the udl file might be desirable for crates that exclusively use proc-macros as mentioned in #26.
UniFFI library mode locates the .udl files itself, removing the need for cargo swift to take care of this.
Currently, cargo swift enforces the target directory to be located in the crates top-level directory, which may be undesirable for crates that are part of a workspace. This behavior was introduced as a quick fix to #24.
Instead, cargo swift should locate the target directory. This is possible by invoking cargo metadata --no-deps --format-version 1
Hello,
I'm encountering an issue while trying to upload to the AppStore.
Previously, I've successfully uploaded the app even with a shared Rust codebase. The main difference this time is that I'm using cargo swift
instead of building the .xcframework
myself ๐ฆ.
After the upload, I received this error:
ITMS-90426: Invalid Swift Support - The SwiftSupport folder is missing.
Rebuild your app using the current public (GM) version of Xcode and resubmit it.
I've explored various solutions online to no avail. I'm uncertain if this is related to cargo swift
๐ค
Any insights or suggestions would be greatly appreciated! ๐
It currently builds for different platforms, for example:
cargo build --target x86_64-apple-darwin
cargo build --target aarch64-apple-darwin
How can I enable some features for aarch64
specifically?
Thanks
Hi, team
I am getting the error with the example provided in readme.
When I build the package for ios. It throws the exception:
cargo swift package
โ Select Target Platforms ยท iOS
x Building target iOS
cargo build --target aarch64-apple-ios
error: instruction requires: fullfp16
--> /Users/testuser/.cargo/registry/src/index.crates.io-6f17d22bba15001f/gemm-common-0.16.15/src/simd.rs:1981:18
|
1981 | "fmla {0:v}.8h, {1:v}.8h, {2:v}.h[0]",
| ^
|
note: instantiated into assembly here
--> <inline asm>:1:2
|
1 | fmla v0.8h, v1.8h, v2.h[0]
| ^
^
...
error: could not compile `gemm-f16` (lib) due to 11 previous errors
Am I doing something wrong?
Right now we lose a lot of information contained in the anyhow
errors coming back from uniffi. Ex:
Failed due to the following error:
Could not generate UniFFI bindings for udl files due to the following error:
Failed to parse UDL
doesn't explain why the parsing failed.
Changing: https://github.com/antoniusnaumann/cargo-swift/blob/main/src/error.rs#L37 to
impl From<anyhow::Error> for Error {
fn from(value: anyhow::Error) -> Self {
Self::new(format!("{value:#}"))
}
}
gives this error:
Failed due to the following error:
Could not generate UniFFI bindings for udl files due to the following error:
Failed to parse UDL: Enum variant names must not shadow type names: "Drop"
Which tells us what was wrong in our UDL file.
Currently, inferring information about compiled artifacts e.g. library path for a target platform requires repeatedly passing additional information such as "debug or release mode", the library name and the target architecture. These should be bundled into a struct that represents a compiled artifact for later reuse.
This might occur because an invoked function is producing additional output on stdout.
Introduce a --plain/-p flag to initialize a project with the minimum required boilerplate without example code
Currently, this tool implicitly assumes that compilation results can be found in a /target directory at the crate level. This is not true for crates that are part of a workspace as those share a /target directory in the workspace top-level.
To get this fixed, we should (somehow) detect if a crate is part of a workspace and if so we should use the workspaces target directory instead.
Considering #7, maybe the generated package should be located in the workspace top-level directory as well.
This is not a breaking change, as currently only cdylibs are supported and crate-type = ["cdylib"]
needs to be set.
Currently, cargo-swift's commands do not get autocompleted. Figure out how to change this. Look at this crate to get started: https://crates.io/crates/clap_autocomplete
Hi! I ran into this error during the "Generating Swift bindings..." phase:
Could not generate UniFFI bindings for udl files due to the following error: No such file or directory
My library uses proc macros, not udl files. Is that the reason for this? Seems like a bug.
If more flags are introduced to cargo swift init in the future, the current approach (separate template files for flags such as plain) would not allow to combine multiple unrelated flags, e.g. --plain --macro to init a project without boilerplate that only uses UniFFI proc-macros.
To make this feasible, a templating library such as askama should be used that allows including blocks conditionally.
Right now, when invoking cargo swift package --lib-type dynamic
when only
[lib]
crate-type = ["staticlib"]
is specified, cargo swift will silently fall back to building a static library (and vice-versa). This should be made explicit by showing a warning, clearly stating why this fallback is invoked. It is probably a good idea to also display the relevant section in the users' Cargo.toml in a rustc-style warning message
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.