Skip to content

Commit 9b72a75

Browse files
authored
Add support for using NativeAOT. (#17374)
Add support for using NativeAOT on all our platforms. This contains numerous changes in a lot of places to add support for NativeAOT: * build logic * runtime * managed code * tests And it all pretty much consists of special-casing NativeAOT everywhere we need to. Note: NativeAOT doesn't work on macOS yet, because a dotnet/runtime fix is required, and thus the corresponding test variations for monotouch-test have been commented out. This PR is best reviewed commit-by-commit. This contributes towards #17339.
2 parents 1893fc0 + b4e3361 commit 9b72a75

36 files changed

+600
-108
lines changed

.gitmodules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
[submodule "external/Touch.Unit"]
1414
path = external/Touch.Unit
1515
url = ../../spouliot/Touch.Unit.git
16-
branch = main
16+
branch = net8.0
1717
[submodule "external/Xamarin.MacDev"]
1818
path = external/Xamarin.MacDev
1919
url = ../../xamarin/Xamarin.MacDev
2020
branch = main
2121
[submodule "external/MonoTouch.Dialog"]
2222
path = external/MonoTouch.Dialog
2323
url = ../../migueldeicaza/MonoTouch.Dialog
24-
branch = dotnet
24+
branch = net8.0
2525
[submodule "api-tools"]
2626
path = external/api-tools
2727
url = ../../rolfbjarne/api-tools

Make.config

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,12 @@ DOTNET_MIN_TVOS_SDK_VERSION=11.0
288288
DOTNET_MIN_MACCATALYST_SDK_VERSION=13.1
289289
DOTNET_MIN_MACOS_SDK_VERSION=10.15
290290

291+
# Minimum OS versions when using NativeOAT - these are at least the general min versions above (but may be higher).
292+
DOTNET_MIN_NATIVEAOT_IOS_SDK_VERSION=12.2
293+
DOTNET_MIN_NATIVEAOT_TVOS_SDK_VERSION=12.2
294+
DOTNET_MIN_NATIVEAOT_MACCATALYST_SDK_VERSION=13.1
295+
DOTNET_MIN_NATIVEAOT_MACOS_SDK_VERSION=10.15
296+
291297
# The min simulator version available in the Xcode we're using
292298
MIN_IOS_SIMULATOR_VERSION=13.7
293299
MIN_WATCHOS_SIMULATOR_VERSION=7.0
@@ -712,6 +718,7 @@ DOTNET_PLATFORMS=
712718
ifdef INCLUDE_IOS
713719
DOTNET_PLATFORMS+=iOS
714720
DOTNET_IOS_BITNESSES+=64
721+
DOTNET_NATIVEAOT_PLATFORMS+=iOS
715722

716723
# 32-bit architectures
717724
ifdef IOS_SUPPORTS_32BIT_ARCHITECTURES
@@ -735,6 +742,7 @@ endif # INCLUDE_IOS
735742
ifdef INCLUDE_TVOS
736743
DOTNET_PLATFORMS+=tvOS
737744
DOTNET_TVOS_BITNESSES+=64
745+
DOTNET_NATIVEAOT_PLATFORMS+=tvOS
738746
ifdef INCLUDE_DEVICE
739747
DOTNET_TVOS_RUNTIME_IDENTIFIERS=tvos-arm64 tvossimulator-x64 tvossimulator-arm64
740748
else
@@ -758,6 +766,7 @@ endif
758766
ifdef INCLUDE_MACCATALYST
759767
DOTNET_PLATFORMS+=MacCatalyst
760768
DOTNET_MACCATALYST_BITNESSES+=64
769+
DOTNET_NATIVEAOT_PLATFORMS+=MacCatalyst
761770
DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS=maccatalyst-x64 maccatalyst-arm64
762771
DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS_64+=$(DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS)
763772
endif
@@ -766,6 +775,7 @@ ifdef INCLUDE_MAC
766775
DOTNET_PLATFORMS+=macOS
767776
DOTNET_CORECLR_PLATFORMS+=macOS
768777
DOTNET_MACOS_BITNESSES+=64
778+
DOTNET_NATIVEAOT_PLATFORMS+=macOS
769779
DOTNET_MACOS_RUNTIME_IDENTIFIERS=osx-x64 osx-arm64
770780
DOTNET_MACOS_RUNTIME_IDENTIFIERS_64=$(DOTNET_MACOS_RUNTIME_IDENTIFIERS)
771781
endif

dotnet/generate-target-platforms.csharp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ var doc = new XmlDocument ();
2424
doc.Load (plistPath);
2525
var nodes = doc.SelectNodes ($"/plist/dict/key[text()='KnownVersions']/following-sibling::dict[1]/key[text()='{platform}']/following-sibling::array[1]/string");
2626

27+
var allLines = File.ReadAllLines ("../Make.config");
28+
2729
var minSdkVersionName = $"DOTNET_MIN_{platform.ToUpper ()}_SDK_VERSION";
28-
var minSdkVersionString = File.ReadAllLines ("../Make.config").Single (v => v.StartsWith (minSdkVersionName + "=", StringComparison.Ordinal)).Substring (minSdkVersionName.Length + 1);
30+
var minSdkVersionString = allLines.Single (v => v.StartsWith (minSdkVersionName + "=", StringComparison.Ordinal)).Substring (minSdkVersionName.Length + 1);
2931
var minSdkVersion = Version.Parse (minSdkVersionString);
3032

33+
var minNativeAotSdkVersionName = $"DOTNET_MIN_NATIVEAOT_{platform.ToUpper ()}_SDK_VERSION";
34+
var minNativeAotSdkVersionString = allLines.Single (v => v.StartsWith (minNativeAotSdkVersionName + "=", StringComparison.Ordinal)).Substring (minNativeAotSdkVersionName.Length + 1);
35+
var minNativeAotSdkVersion = Version.Parse (minNativeAotSdkVersionString);
36+
3137
using (TextWriter writer = new StreamWriter (outputPath)) {
3238
writer.WriteLine ($"<!-- This file contains a generated list of the {platform} platform versions that are supported for this SDK -->");
3339
writer.WriteLine ($"<!-- Generation script: https://github.com/xamarin/xamarin-macios/blob/main/dotnet/generate-target-platforms.csharp -->");
@@ -36,17 +42,23 @@ using (TextWriter writer = new StreamWriter (outputPath)) {
3642

3743
foreach (XmlNode n in nodes) {
3844
var version = n.InnerText;
39-
if (Version.Parse (version) < minSdkVersion)
45+
var parsedVersion = Version.Parse (version);
46+
if (parsedVersion < minSdkVersion)
4047
continue;
41-
writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" />");
48+
if (parsedVersion < minNativeAotSdkVersion) {
49+
writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" Condition=\"!('$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true')\" />");
50+
} else {
51+
writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" />");
52+
}
4253
}
4354

4455
writer.WriteLine ("\t</ItemGroup>");
4556
writer.WriteLine ("\t<ItemGroup>");
4657
writer.WriteLine ($"\t\t<SdkSupportedTargetPlatformVersion Condition=\"'$(TargetPlatformIdentifier)' == '{platform}'\" Include=\"@({platform}SdkSupportedTargetPlatformVersion)\" />");
4758
writer.WriteLine ("\t</ItemGroup>");
4859
writer.WriteLine ("\t<PropertyGroup>");
49-
writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion>{minSdkVersionString}</{platform}MinSupportedOSPlatformVersion>");
60+
writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion Condition=\"!('$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true')\">{minSdkVersionString}</{platform}MinSupportedOSPlatformVersion>");
61+
writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion Condition=\"'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true'\">{minNativeAotSdkVersionString}</{platform}MinSupportedOSPlatformVersion>");
5062
writer.WriteLine ("\t</PropertyGroup>");
5163
writer.WriteLine ("</Project>");
5264
}

dotnet/targets/Xamarin.Shared.Sdk.DefaultItems.targets

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,17 @@
1111
<EnableDefaultmacOSItems Condition=" '$(_PlatformName)' == 'macOS' And '$(EnableDefaultmacOSItems)' == '' ">$(EnableDefaultItems)</EnableDefaultmacOSItems>
1212
<EnableDefaultMacCatalystItems Condition=" '$(_PlatformName)' == 'MacCatalyst' And '$(EnableDefaultMacCatalystItems)' == '' ">$(EnableDefaultItems)</EnableDefaultMacCatalystItems>
1313

14-
<UseMonoRuntime Condition=" '$(UseMonoRuntime)' == '' And '$(_PlatformName)' != 'macOS'">true</UseMonoRuntime>
14+
<!--
15+
PublishAot should only take effect when doing 'dotnet publish', not when doing 'dotnet build'. We distinguish these cases using the '_IsPublishing' property,
16+
but it's rather annoying to always have to check both PublishAot and _IsPublishing to see if we're using NativeAOT, so introduce a third property that's
17+
only set to true if both PublishAot=true and _IsPublishing=true
18+
-->
19+
<_UseNativeAot Condition="'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true'">true</_UseNativeAot>
20+
1521
<UseMonoRuntime Condition=" '$(UseMonoRuntime)' == '' And '$(_PlatformName)' == 'macOS'">false</UseMonoRuntime>
22+
<UseMonoRuntime Condition=" '$(UseMonoRuntime)' == '' And '$(_UseNativeAot)' == 'true'">false</UseMonoRuntime>
23+
<UseMonoRuntime Condition=" '$(UseMonoRuntime)' == ''">true</UseMonoRuntime>
24+
1625
</PropertyGroup>
1726

1827
<ItemGroup>

dotnet/targets/Xamarin.Shared.Sdk.props

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@
5858

5959
<!-- Explicitly export symbols using clang command-line option "-exported_symbols_list export_list" -->
6060
<_ExportSymbolsExplicitly Condition="'$(_ExportSymbolsExplicitly)' == ''">true</_ExportSymbolsExplicitly>
61+
62+
<!--
63+
Some runtime libraries feature switches defaults that need to be set early
64+
Available feature switches: https://github.com/dotnet/runtime/blob/master/docs/workflow/trimming/feature-switches.md
65+
-->
66+
<!-- AutoreleasePoolSupport needs to be set earlier than other switches, so that illink doesn't override it - https://github.com/dotnet/runtime/pull/86753 - so it's set here, instead of in Xamarin.Shared.Sdk.targets -->
67+
<AutoreleasePoolSupport Condition="'$(AutoreleasePoolSupport)' == ''">true</AutoreleasePoolSupport>
6168
</PropertyGroup>
6269

6370
<!-- Set the default RuntimeIdentifier if not already specified. -->
@@ -95,6 +102,20 @@
95102
<SelfContained>true</SelfContained>
96103
</PropertyGroup>
97104

105+
<!--
106+
107+
SelfContained is automatically enabled if PublishAot is true, and that
108+
doesn't work properly (restore fails because RuntimeIdentifier is not
109+
set) when doing the outer build of a universal apps (when
110+
RuntimeIdentifier=''), so manually disable SelfContained in that case.
111+
112+
This might not be necessary after: https://github.com/dotnet/sdk/pull/33229
113+
114+
-->
115+
<PropertyGroup Condition="'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true' And '$(RuntimeIdentifiers)' != '' And '$(RuntimeIdentifier)' == '' And '$(SelfContained)' == ''">
116+
<SelfContained>false</SelfContained>
117+
</PropertyGroup>
118+
98119
<!--
99120
Enable LLVM by default for mobile release builds.
100121
@@ -105,4 +126,22 @@
105126
<PropertyGroup Condition="'$(MtouchUseLlvm)' == '' And '$(Configuration)' == 'Release' And ('$(_PlatformName)' == 'iOS' Or '$(_PlatformName)' == 'tvOS')">
106127
<MtouchUseLlvm>true</MtouchUseLlvm>
107128
</PropertyGroup>
129+
130+
<!-- Various options when using NativeAOT -->
131+
<PropertyGroup Condition="'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true'">
132+
<!-- Disable our own assembly IL stripping logic, because ILC does that already -->
133+
<EnableAssemblyILStripping>false</EnableAssemblyILStripping>
134+
135+
<!-- We're using our own native main function when using NativeAOT -->
136+
<CustomNativeMain>true</CustomNativeMain>
137+
138+
<!-- We must find the BCL libraries using the runtime pack instead of using the built-in NativeAOT BCL -->
139+
<PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
140+
141+
<!-- This turns off some NativeAOT logic we don't want nor need -->
142+
<NativeCompilationDuringPublish>false</NativeCompilationDuringPublish>
143+
144+
<!-- This works around an issue in NativeAOT: https://github.com/dotnet/runtime/issues/86186 -->
145+
<IlcKeepManagedDebuggerSupport>true</IlcKeepManagedDebuggerSupport>
146+
</PropertyGroup>
108147
</Project>

0 commit comments

Comments
 (0)