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

Fix default link mode for NativeAOT #18530

Closed
wants to merge 1 commit into from

Conversation

filipnavara
Copy link
Contributor

No description provided.

@dalexsoto
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build] Windows Integration Tests passed 💻

All Windows Integration Tests passed.

Pipeline on Agent
Hash: f49d290a0139837c4d91121000c3d680f9420021 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Big Sur (11.5) passed 💻

All tests on macOS M1 - Mac Big Sur (11.5) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📚 [PR Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS M1 - Mac Ventura (13.0) passed 💻

All tests on macOS M1 - Mac Ventura (13.0) passed.

Pipeline on Agent
Hash: [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)
  • iOS: (empty diff detected)
  • tvOS: (empty diff detected)
  • MacCatalyst: (empty diff detected)
  • macOS: (empty diff detected)

✅ API diff vs stable

.NET (No breaking changes)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: f49d290a0139837c4d91121000c3d680f9420021 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🚀 [CI Build] Test results 🚀

Test results

✅ All tests passed on VSTS: simulator tests.

🎉 All 92 tests passed 🎉

Tests counts

⚠️ bcl: No tests selected. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests: All 1 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ framework: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 1 tests passed. Html Report (VSDrops) Download
✅ interdependent_binding_projects: All 4 tests passed. Html Report (VSDrops) Download
⚠️ install_source: No tests selected. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker: All 40 tests passed. Html Report (VSDrops) Download
⚠️ mac_binding_project: No tests selected. Html Report (VSDrops) Download
⚠️ mmp: No tests selected. Html Report (VSDrops) Download
⚠️ mononative: No tests selected. Html Report (VSDrops) Download
✅ monotouch: All 26 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
⚠️ mtouch: No tests selected. Html Report (VSDrops) Download
⚠️ xammac: No tests selected. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: f49d290a0139837c4d91121000c3d680f9420021 [PR build]

@@ -1583,7 +1583,7 @@
<_DefaultLinkMode>TrimMode</_DefaultLinkMode>
</PropertyGroup>
<PropertyGroup Condition="'$(TrimMode)' == ''">
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true'">Full</_DefaultLinkMode> <!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true'">Full</_DefaultLinkMode> <!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that the comment does not match how _DefaultLinkMode is set, but I think there is more to this and that the introduced change only works because we explicitly pass:

<IlcArg Include="--defaultrooting" />

Copy link
Contributor Author

@filipnavara filipnavara Jul 3, 2023

Choose a reason for hiding this comment

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

Without this fix _DefaultLinkMode is not set. Then you get to the _ComputeLinkMode target here:

<Target Name="_ComputeLinkMode" DependsOnTargets="$(_ComputeLinkModeDependsOn)">
<PropertyGroup>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">$(LinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">$(MtouchLink)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == ''">$(_DefaultLinkMode)</_LinkMode> <!-- Let the .NET targets chime in -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">None</_LinkMode> <!-- Linking is off by default for macOS apps -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">SdkOnly</_LinkMode> <!-- Default linking is SdkOnly for iOS/tvOS/watchOS apps -->
</PropertyGroup>
</Target>

On iOS-like platform you end up in the SdkOnly code path which translates to partial TrimMode iirc and somehow ends up doing mostly the right thing. On macOS, however, you get the None mode in the fallback. This results in copy TrimMode which does no linking at all and then passes all the assemblies as --root:<assembly name> to ILCompiler. That in turns results in compilation of the whole world, and in Debug version of ILC it asserts on trying to compile Array<T>. That's definitely wrong.

This is all irrespective of --defaultrooting which is already filed as issue #18482.

Copy link
Contributor

Choose a reason for hiding this comment

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

What I meant is (considering just iOS):

So I just wanted to draw the attention that the above change only works in the current setup, as we are explicitly passing --defaultrooting to ILC

Copy link
Contributor

Choose a reason for hiding this comment

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

Additionally, this means that for iOS/tvOS/watchOS (in case of NativeAOT) the default linking mode becomes Full which is not how ILLink is configured in the noNativeAOT mode for these platforms: https://github.com/xamarin/xamarin-macios/pull/18530/files#diff-2e24f1b6f44df7580244d00f106fa1a9e2257536fbca9d7bbdc74571549324a9R1591

This could start breaking the apps with NativeAOT that work normally in noNativeAOT mode, as the change enables ILLink to trim more than what is the current default mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, what do you propose the default to be?

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 just think that we should not change ILLink default trimming modes just because NativeAOT compilation later fails.

Also, just in case it's not clear, this is currently changing the default ONLY when PublishAot=true AND you are running dotnet publish...

Maybe the right fix would be to "intercept" the build and set the right properties for NativeAOT, after ILLink has finished its work and before ILC compilation starts.

... so the end effect is not really any different than this. It doesn't matter whether ILLink trims it first, or NativeAOT trims it later. In the end you still need the trimming to take place.

Copy link
Contributor

@ivanpovazan ivanpovazan Jul 10, 2023

Choose a reason for hiding this comment

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

Also, just in case it's not clear, this is currently changing the default ONLY when PublishAot=true AND you are running dotnet publish...

Thanks, I did understand this exactly as you explained, but again I just want to emphasise that with this change we will start trimming the user code which was not marked with IsTrimmable=true (at least in case of iOS-like platforms) and the reasons for potential regressions that this could bring will not be necessarily related to the fact that we are using NativeAOT as a deployment toolchain-runtime, but rather to the fact that we started trimming something that was never trimmed before - meaning it is not something NativeAOT trimmer/compiler brought in, but how we configured the whole toolchain

Copy link
Contributor Author

@filipnavara filipnavara Jul 10, 2023

Choose a reason for hiding this comment

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

I don't have a problem setting a different default as long as some default is set and it's not None (which is the underlying problem for me).

Copy link
Contributor Author

@filipnavara filipnavara Jul 10, 2023

Choose a reason for hiding this comment

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

I, however, feel that defaulting to partial (current default for iOS-like platforms without this PR) is weird when .NET 7+ default for other platforms is full and it's documented that you can change it, and how.

That said, either partial (SdkOnly) or full would work to solve the macOS issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

I, however, feel that defaulting to partial (current default for iOS-like platforms without this PR) is weird when .NET 7+ default for other platforms is full and it's documented that you can change it, and how.

That is something that should be checked with @rolfbjarne

As for the NativeAOT story regarding macOS, I believe something like:

<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true' And '$(_PlatformName)' == 'macOS'">Full</_DefaultLinkMode>
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true' And '$(_PlatformName)' != 'macOS'">SdkOnly</_DefaultLinkMode>

and

<IlcArg Condition="''$(_PlatformName)' != 'macOS'" Include="--defaultrooting" />

should be tested, as in the current set up NativeAOT trimming is disabled, due to:

  1. ILLink removing IsTrimmable attributes from assemblies
  2. NativeAOT operating in --defaultrooting mode

dalexsoto pushed a commit that referenced this pull request Jul 20, 2023
@filipnavara
Copy link
Contributor Author

Superceded by #18560

@filipnavara filipnavara deleted the patch-10 branch July 20, 2023 15:13
@rolfbjarne rolfbjarne added the community Community contribution ❤ label Aug 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community Community contribution ❤
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants