-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide commands to support using multiple uniffi packages #1
Open
crazytonyli
wants to merge
19
commits into
main
Choose a base branch
from
real-stuff
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This Rust library provides a command line interface to build Rust packages into one xcframework and generate a Package.swift that describes the dependencies among the Rust packages' Swift public modules (i.e. WordPressAPI, JetpackAPI) and internal ones (which include uniffi swift bindings).
I'd love to get feedback regarding the general solution. The code is messy, but you are welcome to review them in detail as usual.
Try it yourself
I have opened PR on Automattic/jetpack-rs#1 and Automattic/wordpress-rs#451 to integration this library. If you want to see this library in action, you can check out those PRs locally and execute this command to run their Swift tests on macOS:
There is a known issue: you'll need to manually install nightly keychain to build on tvOS and watchOS.
Example
Take jetpack-rs projects as an example, the Swift packages structure looks like the diagram below. Sorry about the huge diagram. I didn't find a way to make it more compact.
The structure on the wordpress-rs project looks very similar, except without the Jetpack packages.
Commands
This library provides two commands:
build --profile <release | dev> [--only-ios | --only-macos]
generate-package --project-name <git-repo-name>
build
The
build
command is equivalent to themake xcframework
in wordpress-rs. It cross-compiles Rust packages on Apple platforms and puts the static libraries into an xcframework. It also generates uniffi bindings files.It handles building and "packaging" on Linux, too. So now we don't have separate commands to build on Apple platforms and Linux like wordpress-rs.
generate Package.swift
This
generate-package
command is a new thing. It generatesPackage.swift
based on the uniffi packages dependencies. By "uniffi packages", I mean Rust packages that expose Swift API via uniffi-rs.The code generation is based on one fact/assumption(*): no matter how many uniffi packages we are going to have, they will always be in a tree structure where there is a root node (top-level package) and a bunch of dependencies at the leaves.
(*) If it's not the case in the future, we can easily create a skeleton root-level package to make uniffi packages into a tree.
All these uniffi packages will be built into one static library. There will be multiple swift binding files though, one for each uniffi packages.
If we consider wordpress-rs and jetpack-rs as their own standalone library, each library has two targets in
Package.swift
: public (i.e., WordPressAPI) and internal one (i.e., WordPressAPIInternal). When we have multiple uniffi packages and they have dependencies among them, their binding files would also have the same dependencies. That means we'll need to map the Rust package dependencies onto the targets in Package.swift.Having to sort out their dependencies on Package.swift is why I chose to generate the Package.swift file, instead of hand-wire them.
However, I really don't think we should be doing that, because auto-generating Package.swift puts lots of pressure on the code to be flexible enough to support customization (like adding other Swift Packages as dependencies). If we think the solution here is heading to the right direction, I think we should refactor this part to providing Swift Package targets, instead of generating the whole Package.swift file.