-
Notifications
You must be signed in to change notification settings - Fork 144
Support cross-compilation for iOS #60
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
c592a32 to
d5e290d
Compare
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 seems reasonable, but I'm a little worried that I have no way to test it ... ideally there would be a way to cross-compile from Linux, but I know Apple makes that hard - I know some people at cloudflare with Macs, could you post instructions for how to build for iOS using a Mac?
.github/workflows/ci.yml
Outdated
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.
Why this change? If it's because the tests were failing, why didn't they fail before this PR?
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.
It's not possible to run cargo test when building for iOS. It would produce test binaries, but they can't be executed on the host macOS. You'd need to start an iOS Simulator, wrap the binaries into iOS apps, upload the apps to the simulator, run them there, extract results, and post those back. That's too much hassle. I believe it's okay to skip this step until Rust ecosystem catches up.
So for iOS builds the tests are skipped, only checking that boring-sys is able to compile BoringSSL and that rustc can compile Rust code that should be using the library.
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.
Also, this reminds me. When CI does cargo test, it compiles for the host. That is, I believe that tests for Android targets are actually testing on the host Linux – not the Android 🤔
I guess I'll make another change to the CI to unify tests into three groups:
- build only (maybe possible to run via emulation?)
- build and run
- build and run (except for hyper/tokio)
Ugh. When I added --target to other tests, basically only "stable", "macos-x86_64", "i686-msvc", "x86_64-msvc" ended up working. Everything else fails for one reason or the other: missing compilers, wrong linkers, etc.
It's theoretically possible – I know people who did this some time ago with C code – but it's technically tedious (you gotta have Xcode SDKs, ideally the same clang, and ideally code signing setup). IIRC, it used to be legally dubious too, but nowadays Apple might be cool even if you produce binaries on non-Apple hardware. But however challenging this is, nobody publishing actual apps for iOS would go through this ordeal.
Since Here's the sample that I'm using: https://github.com/ilammy/boring-example That's a stub that calls SHA-256 via |
f996653 to
f42e53e
Compare
|
I've pushed one more commit to work around rust-lang/rust-bindgen#1651 on CI. |
The architecture alone is not enough. aarch64-apple-ios and aarch-apple-ios-sim are both building for aarch64, but they need slightly different CMake flags.
"aarch64-apple-ios" is for iOS devices running ARM64. "aarch64-apple-ios-sim" is for iOS Simulator running on M1 macs.
When bindgen generates bindings for iOS, it must be told to use iOS sysroot with all the standard C headers. Otherwise it tries using the host macOS headers and fails miserably.
cfg!() is evaluated for the host OS executing build.rs script. What we need here is to look whether we are building *for* macOS. Otherwise, for example, builds for iOS on macOS will try to add this flag, causing warnings since rustc does not build cdylibs on iOS.
As pointed out in the comment, bindgen generates tests that cause compiler warnings about misaligned references. bindgen people are aware of the issue, but we have to deal with our warnings that are treated as errors. For the time being, suppress alignment tests on platforms that are known to be triggering UB. I suspect that other non-x86 platforms are affected as well, but I can't get the tests to compile for those tests at the moment, so I'm not sure. Dealing with the issues one platform at a time.
Even if "cargo test --target ${arch}-apple-ios" cross-compiles tests,
it's not possible to actually run them on the host macOS, as that's
a different execution environment.
Although, I guess, we could try only building tests with "--no-run",
GitHub Actions do not make it easy to construct command lines based
on matrix parameters. Thus it's easier to disable these steps, and
the following commit adds a "--no-run" step with "--target".
While it's possible to build Rust tests into an iOS app, start up a simulator instance, upload the tests there, and launch them -- that's a bit involved process. For now, just check that BoringSSL compiles for the specified target. Use "--all-targets" to check all targets, including the unit tests.
6c30f52 to
c4e7827
Compare
|
I've rebased the branch to resolve some conflicts with recently merged FIPS support. |
|
@cjmakes do you have a Mac? Can you test out https://github.com/ilammy/boring-example using the instructions in its readme? |
|
@ilammy, could you do the same magic for arm and aarch64 (Linux) target? Can't cross-compile for these platforms from x86_64 Linux host. Looks like it's not supported since https://github.com/cloudflare/quiche/blob/master/quiche/src/build.rs has specific parts related to arm/arm64 Linux while boring-sys doesn't have such parts. I can test on aarch64 if you don't have such device. |
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.
Sorry for the long delay. Could have sworn I merged this ...
There was some prior work for iOS support, but it did not really produce a successful build because running
bindgenfailed on macOS (#22). That's because bindgen tried using macOS headers instead of iOS ones, and those don't really match. Proper-isysrootflag needs to be passed to clang invocations made by bindgen, pointing it into the right direction.aarch64-apple-ios– iOS devices running ARM64aarch64-apple-ios-sim– iOS simulator running on Apple M1x86_64-apple-ios– iOS simulator running on x86_64cargo build, nocargo test, since that's way more involved.I don't have M1 hardware so I have no idea whether
aarch64-apple-ios-simtarget actually works. Cargo says it builds though. Testing would be much appreciated.