Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Apple Silicon User Experience #182

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

Closed
wants to merge 2 commits into from
Closed

Conversation

sdmaclea
Copy link
Contributor

Moving dotnet/runtime#48628 here.

This is a verbatim copy of the initial draft for Apple Silicon from dotnet/runtime#48628. I will address the feedback in subsequent commits.

I have dropped the Windows UX draft version at least for now... If there is something to say, I can create a separate PR.

I have put the docs in a user-experience folder...


## User Experience Designs

### Mixed Architecture Side By Side Installs
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to drive to consensus around this section. At least from here to the primary design alternative described in Open Questions below.

As I wrote the Open Questions, it was clear the second alternative may be easier and perhaps more preferable. This alternative may make it easier to support publishing universal binaries.

@sdmaclea
Copy link
Contributor Author

sdmaclea commented Mar 2, 2021

I have substantially rewritten this doc. I would appreciate more feedback.


## User Experience Designs

### Mixed Architecture Side By Side Installs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are other runtimes/SDKs with global installs planning to address this problem?

It may be useful to look at Java, golang, python, rust, ... to see whether there is a trend.

Copy link
Contributor Author

@sdmaclea sdmaclea Mar 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I couldn't find an Oracle JDK for Apple Silicon.
  • Zulu OpenJDK was arch specific.
  • golang was arch specific.
  • Python was a universal binary (signed by Apple)
  • Python3 was arch specific from a homebrew cask.
  • Rust looks like it is not ready. They are still protoyping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our muxer architecture, readytorun story, and legacy mixed architecture make it more complicated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From this list, it sounds like arch specific is the norm and we won't be an outlier if we stick with the simpler arch-specific as well.


#### Dotnet Publish as Universal Binaries

- This scenario is also supported for Xamarin iOS workloads. This is a slightly different scenario as Xamarin iOS apps are native binaries (not JIT binaries)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Xamarin.Mac is what runs on Apple Silicon (and it's jitted):

Suggested change
- This scenario is also supported for Xamarin iOS workloads. This is a slightly different scenario as Xamarin iOS apps are native binaries (not JIT binaries)
- This scenario is also supported for Xamarin Mac workloads.


#### Signing

- dotnet publish for Xamarin workloads handles signing automatically.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- dotnet publish for Xamarin workloads handles signing automatically.
- dotnet publish for UI based workloads handles signing automatically.

#### Signing

- dotnet publish for Xamarin workloads handles signing automatically.
- dotnet publish for CoreClr console apps do not handle signing automatically. The developer would need to explicitly sign after publishing for Apple Silicon. The signing command is relatively simple `codesign -s <signature> --entitlements <app-entitlements-path> <app-path>`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- dotnet publish for CoreClr console apps do not handle signing automatically. The developer would need to explicitly sign after publishing for Apple Silicon. The signing command is relatively simple `codesign -s <signature> --entitlements <app-entitlements-path> <app-path>`.
- dotnet publish for console apps do not handle signing automatically. The developer would need to explicitly sign after publishing for Apple

#### Dotnet Publish as Universal Binaries

- This scenario is also supported for Xamarin iOS workloads. This is a slightly different scenario as Xamarin iOS apps are native binaries (not JIT binaries)
- CoreCLR runtime apps have no mechanism to publish universal binaries.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that the correct message if we considering coreclr JIT to be backend for Xamarin.Mac ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we would need to make this work as part of adding support for coreclr w/ Xamarin.Mac.

Comment on lines +242 to +248
### Publishing Universal Binary Apps

No planned support for publishing CoreCLR universal binaries in .NET 6.

This represent the current CoreCLR runtime team plan.

Pursuing a universal CoreCLR runtime would affect this design and might allow us to at least specify a manual method to produce a universal app.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be better to fold this into https://github.com/dotnet/designs/pull/182/files#diff-f9955dc1a401114b9383fdfecab5a55da35312f33af1af21d4d46a0246fa7e16R158 section. It also needs clarification of what is exactly not supported.

Comment on lines +85 to +87
- .NET 6 x64 with .NET 6 Apple Silicon. This scenario is not absolutely critical, but may be required by some customers.
- It enables moving legacy Apps with x64 dependent apps to .NET 6.
- It enables testing macOS x64 apps under the Rosetta 2 emulator.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running apps via dotnet app if both x64 and arm64 is supported by the dotnet - this is currently problematic because there's nothing in the app.runtimeconfig.json which would hint the dotnet/hostfxr which architecture the app needs.

  • We would either have to add this information somewhere (.runtimeconfig.json is probably the most natural place for this)
  • Rely on app (executable) instead
    • Currently this is disabled by default for MacOS RID targets (if I remember correctly) - this fact is not discussed anywhere in this doc either
    • Requires signing - as mentioned above

The universal muxer should default to one architecture if it doesn't know better (probably arm64)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's nothing in the app.runtimeconfig.json which would hint the dotnet/hostfxr which architecture the app needs.

This is intentional design. We talk about these as cross-platform apps that can run anywhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know of the existence of "portable apps" - that's why the muxer will need a "default" architecture (for those apps). The point was about current state of things where we don't generate apphost for apps on MacOS and thus they're executed via dotnet app.dll. Those apps may not be portable, but currently there's no way to tell which RID they were built for (if any) and will break in bad ways if run on the wrong architecture (for example if they have native dependencies).

If we solve the signing problem and turn on apphost by default for MacOS, then this problem becomes much less important and we can probably continue to ignore it (just like we ignore it on Win x86/x64 today).

- Modify .NET 5 installers to allow installation without breaking universal `dotnet`.
- Modify .NET 6 installer to overwrite the x64 `dotnet`

#### Open Questions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My personal preference:

  • Choose a different location for installation of x64 .NET 6+ runtime - something like dotnet_x64. The existence of this is transient and in some not so distant future release will go away
  • The primary install location for .NET 6+ will be arm64 only (for the most part)
    • Keep the muxer/hostfxr as universal binaries in the main install location
    • Add some logic to also look for runtimes/SDKs in the dotnet_x64 location - the universal muxer/hostfxr would use this to get the right runtime if asked to run x64 app
  • The primary location would be the only one registered (in config file and so on) and it would be the only one on "path".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading this document, the above statement by @vitek-karas would be my preference for a solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a different location for installation of x64 .NET 6+ runtime - something like dotnet_x64.

Are you proposing we backport this change to the 3.1/5.0 branches.

I was thinking we could only do this for the .NET 6+ branches.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the advantage of @vitek-karas's approach would be that we just need to teach the installer to alter the install path for x64 on Apple Silicon.

That seems easier that fixing it overwriting the dotnet and hostfxr universal binaries.

That said, I am leanig to @vitek's approach too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we never install .NET 6+ x64 into global location (we simply don't produce the installers for this) then the dotnet_x64 approach is not much different from keeping everything in dotnet. Obviously this is ignoring the potential problems with overwriting the dotnet (note that hostfxr doesn't have a problem since it's installed into a version specific directory, so the older installers will never overwrite the newer one).

The only true advantage of having dotnet_x64 is that it would allow to install both .NET 6 x64 and .NET 6 arm64 side by side.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only true advantage of having dotnet_x64 is that it would allow to install both .NET 6 x64 and .NET 6 arm64 side by side.

It would also give us a pattern to follow - which is important here. Having a process that we can fallback on is important for our customers and ourselves when we rediscover this problem in 18 months.

- Modify the runtime probing to be consistent with the new `hostpolicy` probing.
- Modify the build system to build the Universal Binaries
- Modify installers
- Modify .NET 5 installers to allow installation without breaking universal `dotnet`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Modify .NET 5 installers to allow installation without breaking universal `dotnet`.
- Modify .NET 3.1 and .NET 5 installers to allow installation without breaking universal `dotnet`.

? .NET 5 goes out of support short after .NET 6 ships. .NET 3.1 is supported for much longer.


#### Apple Store requires universal binaries

I have heard that publishing native Apple Silicon (or Apps supporting multiple architectures) apps to the Apple store will require them to be published as Universal binaries. I have not been able to find public documentation of this, so the details are not clear.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rolfbjarne @marek-safar Is this requirement documented anywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't heard anything about it, but it wouldn't surprise me if Apple made it required at some point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK it's the default setup for xcode projects but still a recommendation. I agree with Rolf that this can change in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not yet formally required by Apple, but something we fully expect to be required later this year. As an example, Apple started mandating that all apps have 64-bit slices in their universal binaries about a year before they started telling people that 32-bit was ending. We know they will stop building Intel-based Macs within the next 18 months or so, so we expect them to start requiring Arm slices this summer.


XCode 12 adhoc signs native binaries. These anonymous signature are sufficient to prevent these from being killed (on the machine that compiled them at least.)

I haven't found the documentation exactly how and what changed. These behavior descriptions have been through experimentation and debugging.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you seen the work we have done on this? https://docs.microsoft.com/en-us/dotnet/core/install/macos-notarization-issues

When running the equivalent unsigned binary from a Rosetta 2 emulated process the process is not killed.

I think that this is temporary to allow easier transition and it will be locked down.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@odhanson Might be able to provide more context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try gather more information both about the signing and the Apple store requirements and comment back here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a link:
https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-universal-apps-release-notes

Code Signing
New Features
New in macOS 11 on Macs with Apple silicon, and starting in macOS Big Sur 11 beta 6, the operating system enforces that any executable must be signed before it’s allowed to run. There isn’t a specific identity requirement for this signature: a simple ad-hoc signature is sufficient. This new behavior doesn’t change the long-established policy that our users and developers can run arbitrary code on their Macs, and is designed to simplify the execution policies on Macs with Apple silicon and enable the system to better detect code modifications. This new policy doesn’t apply to translated x86 binaries running under Rosetta 2, nor does it apply to macOS 11 running on Intel-based platforms.

@sdmaclea
Copy link
Contributor Author

I believe @vitek-karas is going to drive this. Closing.

@sdmaclea sdmaclea closed this Apr 15, 2021
@sdmaclea sdmaclea deleted the AppleSilicon branch June 10, 2021 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants