Skip to content

Conversation

@ilammy
Copy link
Contributor

@ilammy ilammy commented Dec 30, 2021

There was some prior work for iOS support, but it did not really produce a successful build because running bindgen failed on macOS (#22). That's because bindgen tried using macOS headers instead of iOS ones, and those don't really match. Proper -isysroot flag needs to be passed to clang invocations made by bindgen, pointing it into the right direction.

  • Fix building for all iOS targets that rustc supports:
    • aarch64-apple-ios – iOS devices running ARM64
    • aarch64-apple-ios-sim – iOS simulator running on Apple M1
    • x86_64-apple-ios – iOS simulator running on x86_64
  • Teach CI to test building for aforementioned targets
    • Only cargo build, no cargo test, since that's way more involved.
  • Suppress some Clippy warnings so that the build gets green

I don't have M1 hardware so I have no idea whether aarch64-apple-ios-sim target actually works. Cargo says it builds though. Testing would be much appreciated.

Copy link
Contributor

@jyn514 jyn514 left a 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?

Comment on lines -155 to +171
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

@ilammy ilammy Jan 1, 2022

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.

@ilammy
Copy link
Contributor Author

ilammy commented Dec 31, 2021

ideally there would be a way to cross-compile from Linux, but I know Apple makes that hard

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.

I know some people at cloudflare with Macs, could you post instructions for how to build for iOS using a Mac?

Since boring is just a Rust library, it's a bit involved: you need to build a staticlib exporting C API for iOS app to actually use. The build step itself is simply cargo build --target <suitable-target>.

Here's the sample that I'm using:

https://github.com/ilammy/boring-example

That's a stub that calls SHA-256 via boring.

@ilammy ilammy force-pushed the ios-cross-compile branch 2 times, most recently from f996653 to f42e53e Compare January 1, 2022 03:41
@ilammy
Copy link
Contributor Author

ilammy commented Jan 1, 2022

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.
@ilammy ilammy force-pushed the ios-cross-compile branch from 6c30f52 to c4e7827 Compare February 5, 2022 12:30
@ilammy
Copy link
Contributor Author

ilammy commented Feb 5, 2022

I've rebased the branch to resolve some conflicts with recently merged FIPS support.

@jyn514
Copy link
Contributor

jyn514 commented Feb 6, 2022

@cjmakes do you have a Mac? Can you test out https://github.com/ilammy/boring-example using the instructions in its readme?

@eager-signal
Copy link
Contributor

eager-signal commented May 19, 2022

@ilammy @jyn514 I ran throughboring-example with the iOS Simulator on an M1 Mac and an iOS device, and both worked just fine 👍 . (I did have to update the boring submodule ref to c4e782719aa8b6b10fa19541b356db90f67d06c4.)

@avently
Copy link

avently commented Jun 3, 2022

@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.

Copy link
Contributor

@jyn514 jyn514 left a 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 ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants