Skip to content
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

Add new rustc target for Arm64 machines that can target the iphonesimulator #81966

Merged
merged 2 commits into from
Feb 21, 2021

Conversation

deg4uss3r
Copy link
Contributor

@deg4uss3r deg4uss3r commented Feb 10, 2021

This PR lands a new target (aarch64-apple-ios-sim) that targets arm64 iphone simulator, previously unreachable from Apple Silicon machines.

resolves #81632

r? @shepmaster

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 10, 2021
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@deg4uss3r deg4uss3r force-pushed the degausser/aarch64_apple_ios_sim branch from e74e5c0 to 07663fd Compare February 10, 2021 16:54
@badboy
Copy link
Member

badboy commented Feb 12, 2021

tl;dr: I finally made this work with my static libraries to work inside the iOS simulator on an M1 macbook pro. I had to use the triple arm64-apple-ios7.0.0-simulator to make it behave.

heads up: This is based on #81451 to get LLVM 12. I have not tested yet if that's required.

Details on how I got there:

First I looked at what the difference is between C code compiled for arm64 iOS and for arm64 iOS Simulator:

❯ cat t.c
#include <stdio.h>

int foo()
{
  printf("hello world\n");
  return 0;
}

❯ clang -target arm64-apple-ios-simulator t.c -c -o t-sim.o -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
❯ clang -target arm64-apple-ios t.c -c -o t-ios.o -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
❯ otool -l t-sim.o | rg 'VERSION|platform|version'
      cmd LC_BUILD_VERSION
 platform 7
❯ otool -l t-ios.o | rg 'VERSION|platform|version'
      cmd LC_VERSION_MIN_IPHONEOS
  version 7.0

As you can see the simulator one uses LC_BUILD_VERSION, whereas the iOS one uses LC_VERSION_MIN_IPHONEOS.

After a bunch of tries, trying to trace the rustc and LLVM code I was unable to fully determine how LLVM decides which way to use.
No matter what I did the objects falling out of rustc used LC_VERSION_MIN_IPHONEOS.

So I went back to look at the C code again.
This time comparing the LLVM IR.

Here's the relevant difference between t.c compiled with clang -emit-llvm for iOS or iOS-simulator:

❯ diff -u t-ios.ll t-sim.ll  | head -8
--- t-ios.ll	2021-02-12 11:10:21.000000000 +0100
+++ t-sim.ll	2021-02-12 11:10:03.000000000 +0100
@@ -1,7 +1,7 @@
 ; ModuleID = 't.c'
 source_filename = "t.c"
 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
-target triple = "arm64-apple-ios7.0.0"
+target triple = "arm64-apple-ios7.0.0-simulator"

Low and behold: the triple has the version in it.

So I swapped out the triple in aarch64_apple_ios_sim.rs, recompiled my compiler, then used that to build my test library:

❯ cat src/lib.rs
#[no_mangle]
pub extern "C" fn hello_world() -> u32 {
    1+1
}
❯ rustc +stage1 --target aarch64-apple-ios-sim src/lib.rs --crate-type staticlib
❯ otool -l liblib.a | rg 'VERSION|platform|version' | head -2
      cmd LC_BUILD_VERSION
 platform 7

There we go!

Now it turns out: for macOS we do the same: we put the deployment target version into the triple:

fn macos_deployment_target() -> (u32, u32) {
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
let version = deployment_target
.as_ref()
.and_then(|s| s.split_once('.'))
.and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok());
version.unwrap_or((10, 7))
}

I guess we need to start doing that for iOS too? I can work on integrating that into the code of this PR.
(Side note: I took my rustc build to my iOS project and I can now run tests using the simulator, there's more work ahead on our side because of course we can't build one fat library anymore for hardware and simulator targets ...)

@deg4uss3r
Copy link
Contributor Author

Awesome detective work @badboy !!!!

Looks like we'll need LLVM12 still I tried building against the latest master with the triple changed to arm64-apple-ios7.0.0-simulator

and I'm still getting:

Showing All Messages
In /Users/rth/work/core/target/aarch64-apple-ios-sim/debug/libcore.a(sqlite3.o), building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

@badboy
Copy link
Member

badboy commented Feb 13, 2021

Awesome detective work @badboy !!!!

Looks like we'll need LLVM12 still I tried building against the latest master with the triple changed to arm64-apple-ios7.0.0-simulator

and I'm still getting:

Showing All Messages
In /Users/rth/work/core/target/aarch64-apple-ios-sim/debug/libcore.a(sqlite3.o), building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Well, that one might be because sqlite3 is built with the wrong target. If sqlite3 is built using the cc crate you might need a export CFLAGS_aarch64_apple_ios_sim="-target arm64-apple-ios7.0.0-simulator" (or TARGET_CFLAGS="...") to make it work.

I should fine some time tomorrow to extend this PR with the necessary steps and also look into cc and whether it needs changes to make it work out of the box.

@deg4uss3r
Copy link
Contributor Author

💯 adding that flag to my build script works I can run my app, this is awesome @badboy 😃

I'll let you add your commits as I am sure it's much cleaner than my branch is now lol

@badboy
Copy link
Member

badboy commented Feb 15, 2021

not sure if you noticed, but I sent a PR to your branch here: deg4uss3r#1
If you merge that it should show up here and from there it can get proper review.

@shepmaster
Copy link
Member

Seems believable, and it sounds like two separate people got it to work, so that's about as good of testing as I'd expect for this level.

Would you mind squashing the commits (don't really need the intermediate "fix formatting") and then we can merge!

@deg4uss3r deg4uss3r force-pushed the degausser/aarch64_apple_ios_sim branch 4 times, most recently from 1b40a9c to df142b6 Compare February 19, 2021 18:14
@deg4uss3r deg4uss3r force-pushed the degausser/aarch64_apple_ios_sim branch from df142b6 to e36eef8 Compare February 19, 2021 18:17
@deg4uss3r
Copy link
Contributor Author

@shepmaster ungracefully done!

@LingMan
Copy link
Contributor

LingMan commented Feb 19, 2021

@deg4uss3r You can squash the typo fix, too. I really don't care about credit for something that minor.

LLVM picks the right things to put into the compiled object file based
on the target deployment version.
We need to communicate it through the target triple.
Only with that LLVM will use the right commands in the file to make it
look and behave like code compiled for the arm64 iOS simulator target.
@deg4uss3r deg4uss3r force-pushed the degausser/aarch64_apple_ios_sim branch from e36eef8 to 8d6ad11 Compare February 20, 2021 21:47
@shepmaster
Copy link
Member

@bors r+ rollup

Thanks!

@bors
Copy link
Contributor

bors commented Feb 21, 2021

📌 Commit 8d6ad11 has been approved by shepmaster

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 21, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 21, 2021
Rollup of 11 pull requests

Successful merges:

 - rust-lang#81300 (BTree: share panicky test code & test panic during clear, clone)
 - rust-lang#81706 (Document BinaryHeap unsafe functions)
 - rust-lang#81833 (parallelize x.py test tidy)
 - rust-lang#81966 (Add new `rustc` target for Arm64 machines that can target the iphonesimulator)
 - rust-lang#82154 (Update RELEASES.md 1.50 to include methods stabilized in rust-lang#79342)
 - rust-lang#82177 (Do not delete bootstrap.exe on Windows during clean)
 - rust-lang#82181 (Add check for ES5 in CI)
 - rust-lang#82229 (Add [A-diagnostics] bug report template)
 - rust-lang#82233 (try-back-block-type test: Use TryFromSliceError for From test)
 - rust-lang#82302 (Remove unsafe impl Send for CompletedTest & TestResult)
 - rust-lang#82349 (test: Print test name only once on timeout)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 882fd69 into rust-lang:master Feb 21, 2021
@rustbot rustbot added this to the 1.52.0 milestone Feb 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create a aarch64-apple-ios-sim target for rustc
8 participants