-
Notifications
You must be signed in to change notification settings - Fork 3
Speed up building xcframework for local development #61
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
Conversation
xcframework-only-macos: $(build-apple-platform-macos) | ||
xcframework-only-ios: $(build-apple-platform-ios) | ||
xcframework-only-tvos: $(build-apple-platform-tvos) | ||
xcframework-only-watchos: $(build-apple-platform-watchos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to consolidate all of the above into one wildcard target: xcframework-only-%
, but couldn't get it to work. Let me know if you have any ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@crazytonyli I went through the Rust implementation and left you some non-blocking notes. In some cases, I stopped duplicating some of the comments as the earlier ones applied elsewhere as well. I can mention them in my follow up review if necessary.
tools/src/xcframework.rs
Outdated
|
||
use crate::Action; | ||
|
||
static LIBRARY_FILENAME: &str = "libwordpress.a"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static LIBRARY_FILENAME: &str = "libwordpress.a"; | |
const LIBRARY_FILENAME: &str = "libwordpress.a"; |
I assume this value is not supposed to be modified with a 'static
lifetime? If so, we should use const
instead.
tools/src/xcframework.rs
Outdated
std::fs::create_dir_all(dir) | ||
.with_context(|| format!("Failed to create directory: {:?}", dir))?; | ||
|
||
Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::fs::create_dir_all(dir) | |
.with_context(|| format!("Failed to create directory: {:?}", dir))?; | |
Ok(()) | |
std::fs::create_dir_all(dir).with_context(|| format!("Failed to create directory: {:?}", dir)) |
You can return the result directly since create_dir_all
returns std.io::Result<()>
.
tools/src/xcframework.rs
Outdated
|
||
impl XCFramework { | ||
fn new(targets: &Vec<String>, profile: &str) -> Result<Self> { | ||
let headers = PathBuf::from("target/swift-bindings/headers"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should "target/swift-bindings/headers" be a const?
tools/src/xcframework.rs
Outdated
return Err(Error::msg(format!( | ||
"Headers not found: {}", | ||
headers.display() | ||
))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Err(Error::msg(format!( | |
"Headers not found: {}", | |
headers.display() | |
))); | |
anyhow::bail!("Headers not found: {}", headers.display()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL!
tools/src/xcframework.rs
Outdated
let mut parts = target.split('-'); | ||
_ /* arch */= parts.next(); | ||
if parts.next() != Some("apple") { | ||
return Err(Error::msg(format!("{} is not an Apple platform", target))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Err(Error::msg(format!("{} is not an Apple platform", target))); | |
anyhow::bail!("{} is not an Apple platform", target); |
tools/src/xcframework.rs
Outdated
let os = match parts.next() { | ||
Some("darwin") => ApplePlatform::MacOS, | ||
Some("ios") => ApplePlatform::IOS, | ||
Some("tvos") => ApplePlatform::TvOS, | ||
Some("watchos") => ApplePlatform::WatchOS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably worth implementing as ApplePlatform::from_str
.
tools/src/xcframework.rs
Outdated
let llvm_target = json | ||
.get("llvm-target") | ||
.and_then(|t| t.as_str()) | ||
.ok_or(Error::msg("No llvm-target in command output"))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use with_context
for consistency?
.ok_or(Error::msg("No llvm-target in command output"))?; | |
.with_context(|| format!("No llvm-target in command output"))?; |
tools/src/xcframework.rs
Outdated
let mut libraries: Vec<PathBuf> = Vec::new(); | ||
for lib in &self.libraries { | ||
libraries.push(lib.create(temp_dir)?); | ||
} | ||
Ok(libraries) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut libraries: Vec<PathBuf> = Vec::new(); | |
for lib in &self.libraries { | |
libraries.push(lib.create(temp_dir)?); | |
} | |
Ok(libraries) | |
self.libraries | |
.iter() | |
.map(|lib| lib.create(temp_dir)) | |
.collect() |
|
||
impl Action for CreateXCFramework { | ||
fn run(&self) -> Result<()> { | ||
let temp_dir = std::env::temp_dir().join("wp-rs-xcframework"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should wp-rs-xcframework
be a const
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave this string local to the function, because it's a temporary directory name which can change without affecting anyone.
recreate_directory(&dest)?; | ||
std::fs::rename(temp_dest, &dest).with_context(|| "Failed to move xcframework")?; | ||
|
||
println!("xcframework created at {}", &dest.display()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
println!("xcframework created at {}", &dest.display()); | |
println!("xcframework created at {}", dest.display()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chatted about whether we want to use this or a different scripting language for this (ruby, because it's our release tooling language, or Swift because this tool is for folks writing swift code)
We'll land it as-is for now (with Oguz's comments addressed), and we can adjust later if we need to.
Thanks Tony!
@oguzkocer Thanks for your review. I have addressed all your comments. I'll merge this PR after CI jobs pass. Happy to address any further comments in follow up PRs. |
At the moment, we run
make xcframework
when we update the rust code and need to use them in the Swift package. The command builds the rust library against all Apple platforms (11 targets in total). But in reality, most of the time, we really only need libraries for one platform or one target—the one we choose in Xcode.Alternatives to the
make xcframework
commandThis PR introduces a couple of new things:
make xcframework-only-<ios|macos|..>
to create a xcframework for a given platform, which will save us from building rust library for other platforms that we don't need during development.dev
profile) during development and use release configuration on CI, which will also save us build time during development because dev build is about 1.2 times faster than release build.New
tools
cargo binary packageThis PR adds a new
tools
binary package to Cargo. It's a command line application, which for the moment only has acreate-xcframework
command. We may need to add more later (for example, release process).The
create-xcframework
command is a more convenient way to callxcodebuild -create-xcframework
. It takes a list of cargo targets(which should have been built by this point), combine some of them into fat libraries if needed, and then call thexcodebuild
command to create a xcframework. That enables us easily creating xcframework for selected targets/platforms from Makefile.By using this tool, Makefile now only builds targets and the
tools create-xcframework
command takes care of creating an xcframework from built targets.Test Instructions
The existing
make xcframework
should be covered by CI.You can run
[CARGO_PROFILE=dev|release] make clean xcframework-only-<platform>
locally to verify xcframework is built accordingly.You can also try calling the
create-xcframework
tool directly, but you'll need to build some targets before passing them to command line.