-
Notifications
You must be signed in to change notification settings - Fork 34
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
Rust build plugin #1443
base: main
Are you sure you want to change the base?
Rust build plugin #1443
Conversation
@y4ssi and I have been discussing this approach privately. I'd like to share some thoughts I had We originally moved out of the "build system" approach because of (swift) developer friction points:
the second point is a "philosophy" thing more than anything. Would you mandate Swift developers to download Rust, cargo and rustup to their environment just for them to contribute a pure Swift change your project? I believe it was unreasonable from my part as a maintainer. I'm not a maintainer of this repo anymore so, you decide 😅. The rest are "concrete" concerns. Build reproducibility The problem is mostly Local reproducibility, because of the RustLang environment every developer has. I don't know how you folks are deploying Zashi to Testflight, but if you were to deploy manually from source, then Zashi would build the SDK, the SDK would build Rust via a Plugin, and that would be then archived and uploaded to testflight. Is there a way that we can set up the environment so that every developer working on the SDK has the same cargo and rust toolchain? Is that possible to enforce to CI runners as well? I recall this problem was solved in Ruby by a tool call Bundler. It was used in iOS and Mac development to make reproducible CocoaPods builds as well. Is there something like that for Rust? Build Reliability Build times adding the rust tooling will definitely increase CI build times. I guess that the assessment is that the time spent waiting on builds will be fairly compensated by the time spent working on two different repos. Future-proof approach Two problems that this PR seems to be trying to address
Problem 1 can be addressed with some approach like the one explored there Problem 2 is more complex. I think that some questions are worth to be asked and answered:
Overall comments I think its worth exploring. But a unified FFI approach with better test surface would be the best.
This can possibly be achieved by using conditional compilation within the Package.swift file so that there's an environment variable on the release CI job that is passed to the build, that will make the compiler use the plugin or just compile using a |
Yes, because this is not a pure Swift project; it is a hybrid Swift/Rust project. (And they don't even need to do that if they don't build locally and instead rely on CI to check their changes.) As a Rust developer, I will never have the luxury of not using Xcode (I wish I did) or Swift to contribute a pure Rust change if I want to test that it works. Moreover, the majority of functionality changes in this project require Rust changes, and the current process is so hostile to Rust development that I have on multiple occasions considered quitting entirely. Why should we expect contributors to be more willing to contribute? Not requiring downstream users of the SDK to install Rust is a much more reasonable goal.
Yes, and we already use it. The FFI repo has a If you aren't using
There's a bunch of caching we can apply to CI to improve Rust build times (that we already apply in our other repos to great effect). It will be slightly finicky due to building multiple targets at once, but that can be handled. Moreover, I think for local development it should be possible to only build the target you are deploying to (the simulator, or your local iOS device). That would greatly speed up local recompilations.
Even in the grand future of UniFFI or Diplomat unifying the Rust backends of the Swift and Kotlin SDKs (which I do want to move towards), we still have the issue of enabling feature branches where the SDKs have partially-implemented features with potentially-breaking changes still to come. Developers need to be able to use any revision of the Rust backend, without requiring it to be in a state suitable for public consumption and subject to backwards compatibility requirements. This requires either that we build and cache binaries for every single commit (including across force-pushes to branches, and across arbitrary forks) that ever occurs on the Rust backend (to ensure that the pure Swift developers can reliably compile no matter what code they checked out), or we need to use local developer compilation. We do not have the devops resources for the former, and my proposal here is the latter. |
As a Swift developer, I will never have the luxury of not using Xcode (I wish I did) 😂 Thanks for the comments @str4d ! |
This is an experiment to try and recreate the CocoaPods build scripts (that were removed in 86d1257) as a Swift Package Manager build plugin. If we can do so, then we can use that for regular development, and swap it out with a
binaryTarget
in release PRs (the tagged release commits would use the binary targets, and then the commit immediately afterwards reverts to using the build plugin).To test this draft PR, create a symlink in the root directory named
rust
, pointing to therust
folder in a local checkout ofzcash-light-client-ffi
at the correct tag. Once we get the build plugin fully working, I will rework this PR to import the Rust code fromzcash-light-client-ffi
(after which we can archive that repository).Part of Electric-Coin-Company/zcash-light-client-ffi#96.
This code review checklist is intended to serve as a starting point for the author and reviewer, although it may not be appropriate for all types of changes (e.g. fixing a spelling typo in documentation). For more in-depth discussion of how we think about code review, please see Code Review Guidelines.
Author
Reviewer