diff --git a/.gitmodules b/.gitmodules index eefd1092b6d4..5a50d28b9224 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ [submodule "external/Touch.Unit"] path = external/Touch.Unit url = ../../spouliot/Touch.Unit.git - branch = main + branch = net8.0 [submodule "external/Xamarin.MacDev"] path = external/Xamarin.MacDev url = ../../xamarin/Xamarin.MacDev @@ -21,7 +21,7 @@ [submodule "external/MonoTouch.Dialog"] path = external/MonoTouch.Dialog url = ../../migueldeicaza/MonoTouch.Dialog - branch = dotnet + branch = net8.0 [submodule "api-tools"] path = external/api-tools url = ../../rolfbjarne/api-tools diff --git a/Make.config b/Make.config index 4e5873937c81..2c2747c4950e 100644 --- a/Make.config +++ b/Make.config @@ -273,6 +273,12 @@ DOTNET_MIN_TVOS_SDK_VERSION=11.0 DOTNET_MIN_MACCATALYST_SDK_VERSION=13.1 DOTNET_MIN_MACOS_SDK_VERSION=10.15 +# Minimum OS versions when using NativeOAT - these are at least the general min versions above (but may be higher). +DOTNET_MIN_NATIVEAOT_IOS_SDK_VERSION=12.2 +DOTNET_MIN_NATIVEAOT_TVOS_SDK_VERSION=12.2 +DOTNET_MIN_NATIVEAOT_MACCATALYST_SDK_VERSION=13.1 +DOTNET_MIN_NATIVEAOT_MACOS_SDK_VERSION=10.15 + # The min simulator version available in the Xcode we're using MIN_IOS_SIMULATOR_VERSION=13.7 MIN_WATCHOS_SIMULATOR_VERSION=7.0 @@ -682,6 +688,7 @@ DOTNET_PLATFORMS= ifdef INCLUDE_IOS DOTNET_PLATFORMS+=iOS DOTNET_IOS_BITNESSES+=64 +DOTNET_NATIVEAOT_PLATFORMS+=iOS # 32-bit architectures ifdef IOS_SUPPORTS_32BIT_ARCHITECTURES @@ -705,6 +712,7 @@ endif # INCLUDE_IOS ifdef INCLUDE_TVOS DOTNET_PLATFORMS+=tvOS DOTNET_TVOS_BITNESSES+=64 +DOTNET_NATIVEAOT_PLATFORMS+=tvOS ifdef INCLUDE_DEVICE DOTNET_TVOS_RUNTIME_IDENTIFIERS=tvos-arm64 tvossimulator-x64 tvossimulator-arm64 else @@ -728,6 +736,7 @@ endif ifdef INCLUDE_MACCATALYST DOTNET_PLATFORMS+=MacCatalyst DOTNET_MACCATALYST_BITNESSES+=64 +DOTNET_NATIVEAOT_PLATFORMS+=MacCatalyst DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS=maccatalyst-x64 maccatalyst-arm64 DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS_64+=$(DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS) endif @@ -736,6 +745,7 @@ ifdef INCLUDE_MAC DOTNET_PLATFORMS+=macOS DOTNET_CORECLR_PLATFORMS+=macOS DOTNET_MACOS_BITNESSES+=64 +DOTNET_NATIVEAOT_PLATFORMS+=macOS DOTNET_MACOS_RUNTIME_IDENTIFIERS=osx-x64 osx-arm64 DOTNET_MACOS_RUNTIME_IDENTIFIERS_64=$(DOTNET_MACOS_RUNTIME_IDENTIFIERS) endif diff --git a/dotnet/generate-target-platforms.csharp b/dotnet/generate-target-platforms.csharp index ddd6a5a0aa1a..9e0a1b82628f 100755 --- a/dotnet/generate-target-platforms.csharp +++ b/dotnet/generate-target-platforms.csharp @@ -24,10 +24,16 @@ var doc = new XmlDocument (); doc.Load (plistPath); var nodes = doc.SelectNodes ($"/plist/dict/key[text()='KnownVersions']/following-sibling::dict[1]/key[text()='{platform}']/following-sibling::array[1]/string"); +var allLines = File.ReadAllLines ("../Make.config"); + var minSdkVersionName = $"DOTNET_MIN_{platform.ToUpper ()}_SDK_VERSION"; -var minSdkVersionString = File.ReadAllLines ("../Make.config").Single (v => v.StartsWith (minSdkVersionName + "=", StringComparison.Ordinal)).Substring (minSdkVersionName.Length + 1); +var minSdkVersionString = allLines.Single (v => v.StartsWith (minSdkVersionName + "=", StringComparison.Ordinal)).Substring (minSdkVersionName.Length + 1); var minSdkVersion = Version.Parse (minSdkVersionString); +var minNativeAotSdkVersionName = $"DOTNET_MIN_NATIVEAOT_{platform.ToUpper ()}_SDK_VERSION"; +var minNativeAotSdkVersionString = allLines.Single (v => v.StartsWith (minNativeAotSdkVersionName + "=", StringComparison.Ordinal)).Substring (minNativeAotSdkVersionName.Length + 1); +var minNativeAotSdkVersion = Version.Parse (minNativeAotSdkVersionString); + using (TextWriter writer = new StreamWriter (outputPath)) { writer.WriteLine ($""); writer.WriteLine ($""); @@ -36,9 +42,14 @@ using (TextWriter writer = new StreamWriter (outputPath)) { foreach (XmlNode n in nodes) { var version = n.InnerText; - if (Version.Parse (version) < minSdkVersion) + var parsedVersion = Version.Parse (version); + if (parsedVersion < minSdkVersion) continue; - writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" />"); + if (parsedVersion < minNativeAotSdkVersion) { + writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" Condition=\"!('$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true')\" />"); + } else { + writer.WriteLine ($"\t\t<{platform}SdkSupportedTargetPlatformVersion Include=\"{n.InnerText}\" />"); + } } writer.WriteLine ("\t"); @@ -46,7 +57,8 @@ using (TextWriter writer = new StreamWriter (outputPath)) { writer.WriteLine ($"\t\t"); writer.WriteLine ("\t"); writer.WriteLine ("\t"); - writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion>{minSdkVersionString}"); + writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion Condition=\"!('$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true')\">{minSdkVersionString}"); + writer.WriteLine ($"\t\t<{platform}MinSupportedOSPlatformVersion Condition=\"'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true'\">{minNativeAotSdkVersionString}"); writer.WriteLine ("\t"); writer.WriteLine (""); } diff --git a/dotnet/targets/Xamarin.Shared.Sdk.DefaultItems.targets b/dotnet/targets/Xamarin.Shared.Sdk.DefaultItems.targets index d100091037f5..c13dc5def78a 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.DefaultItems.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.DefaultItems.targets @@ -11,8 +11,17 @@ $(EnableDefaultItems) $(EnableDefaultItems) - true + + <_UseNativeAot Condition="'$(PublishAot)' == 'true' And '$(_IsPublishing)' == 'true'">true + false + false + true + diff --git a/dotnet/targets/Xamarin.Shared.Sdk.props b/dotnet/targets/Xamarin.Shared.Sdk.props index 3bff654e6993..050a40c1736d 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.props +++ b/dotnet/targets/Xamarin.Shared.Sdk.props @@ -58,6 +58,13 @@ <_ExportSymbolsExplicitly Condition="'$(_ExportSymbolsExplicitly)' == ''">true + + + + true @@ -95,6 +102,20 @@ true + + + false + + + + + false + + + true + + + true + + + false + + + true + diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index 496a66b7537b..d62eb17660e3 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -130,7 +130,7 @@ true false true - true + <_AggressiveAttributeTrimming Condition="'$(_AggressiveAttributeTrimming)' == ''">true false false @@ -153,6 +153,11 @@ + + <_GlobalizationDataFileLocation Condition="'$(_UseNativeAot)' == 'true'">Resource + <_GlobalizationDataFileLocation Condition="'$(_UseNativeAot)' != 'true'">Assembly + + @@ -424,7 +429,13 @@ _ComputeLinkMode; _ComputeFrameworkVariables; _ComputeFrameworkAssemblies; + + <_ComputeLinkerArgumentsDependsOn Condition="'$(_UseNativeAot)' != 'true'"> + $(_ComputeLinkerArgumentsDependsOn); ComputeResolvedFilesToPublishList; + + <_ComputeLinkerArgumentsDependsOn> + $(_ComputeLinkerArgumentsDependsOn); _ParseBundlerArguments; _ComputeVariables; _CreateRuntimeConfiguration; @@ -433,9 +444,50 @@ _DetectAppManifest; _ReadAppManifest; _WriteAppManifest; + _ComputeLinkerFeatures; + + Compile;_ComputeLinkerArguments;_ComputeManagedAssemblyToLink;SetupOSSpecificProps;PrepareForILLink;_XamarinComputeIlcCompileInputs + + + + + + managed-static + + + true + + + + + <_IsSimulatorFeature Condition="('$(_PlatformName)' == 'iOS' Or '$(_PlatformName)' == 'tvOS') And '$(_SdkIsSimulator)' == 'true'">true + <_IsSimulatorFeature Condition="'$(_IsSimulatorFeature)' == ''">false + + + <_IsManagedStaticRegistrarFeature Condition="'$(Registrar)' == 'managed-static'">true + <_IsManagedStaticRegistrarFeature Condition="'$(Registrar)' != 'managed-static'">false + + + <_IsNativeAOTFeature Condition="'$(_XamarinRuntime)' == 'NativeAOT'">true + <_IsNativeAOTFeature Condition="'$(_XamarinRuntime)' != 'NativeAOT'">false + + + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.Arch.IsSimulator $(_IsSimulatorFeature) + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.IsManagedStaticRegistrar $(_IsManagedStaticRegistrarFeature) + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.IsNativeAOT $(_IsNativeAOTFeature) + + + + + + + + + + @@ -443,6 +495,11 @@ + + + + + <_CustomLinkerOptionsFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)custom-linker-options.txt')) @@ -456,9 +513,6 @@ <_LinkerCacheDirectory>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)linker-cache')) <_LinkerCacheDirectory Condition="'$(BuildSessionId)' != ''">$(IntermediateOutputPath)linker-cache - <_XamarinRuntime Condition="'$(UseMonoRuntime)' == 'true'">MonoVM - <_XamarinRuntime Condition="'$(UseMonoRuntime)' != 'true'">CoreCLR - $(TrimMode) copy @@ -562,14 +616,6 @@ <_ExtraTrimmerArgs Condition="'$(_BundlerDebug)' != 'true' And '$(MtouchInterpreter)' == '' And '$(_RunAotCompiler)' == 'true' And '$(_PlatformName)' != 'macOS'">$(_ExtraTrimmerArgs) --enable-opt sealer - - <_ExtraTrimmerArgs Condition="('$(_PlatformName)' == 'iOS' Or '$(_PlatformName)' == 'tvOS') And '$(_SdkIsSimulator)' == 'true'">$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.Arch.IsSimulator true - <_ExtraTrimmerArgs Condition="('$(_PlatformName)' == 'iOS' Or '$(_PlatformName)' == 'tvOS') And '$(_SdkIsSimulator)' != 'true'">$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.Arch.IsSimulator false - - - <_ExtraTrimmerArgs Condition="'$(Registrar)' == 'managed-static'">$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.IsManagedStaticRegistrar true - <_ExtraTrimmerArgs Condition="'$(Registrar)' != 'managed-static'">$(_ExtraTrimmerArgs) --feature ObjCRuntime.Runtime.IsManagedStaticRegistrar false - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --enable-serialization-discovery @@ -853,7 +899,12 @@ - <_PackageIdInfix Condition="'$(UseMonoRuntime)' == 'true'">Mono. + <_XamarinRuntime Condition="'$(UseMonoRuntime)' == 'true'">MonoVM + <_XamarinRuntime Condition="'$(UseMonoRuntime)' != 'true' And '$(_UseNativeAot)' != 'true'">CoreCLR + <_XamarinRuntime Condition="'$(UseMonoRuntime)' != 'true' And '$(_UseNativeAot)' == 'true'">NativeAOT + + <_PackageIdInfix Condition="'$(_XamarinRuntime)' == 'MonoVM'">Mono. + <_PackageIdInfix Condition="'$(_XamarinRuntime)' == 'NativeAOT'">NativeAOT. <_MonoNugetPackageId>Microsoft.NETCore.App.Runtime.$(_PackageIdInfix)$(RuntimeIdentifier) <_XamarinNugetPackageId>Microsoft.$(_PlatformName).Runtime.$(RuntimeIdentifier) @@ -871,8 +922,9 @@ <_XamarinRefAssemblyDirectory>$(_XamarinRefPackageDirectory)/ref/net8.0/ <_XamarinRefAssemblyPath>$(_XamarinRefAssemblyDirectory)$(_PlatformAssemblyName).dll - <_LibPartialStaticRegistrar Condition="'$(UseMonoRuntime)' == 'true'">$(_XamarinNativeLibraryDirectory)/Microsoft.$(_PlatformName).registrar.a - <_LibPartialStaticRegistrar Condition="'$(UseMonoRuntime)' != 'true'">$(_XamarinNativeLibraryDirectory)/Microsoft.$(_PlatformName).registrar.coreclr.a + <_LibPartialStaticRegistrar Condition="'$(_XamarinRuntime)' == 'MonoVM'">$(_XamarinNativeLibraryDirectory)/Microsoft.$(_PlatformName).registrar.a + <_LibPartialStaticRegistrar Condition="'$(_XamarinRuntime)' == 'CoreCLR'">$(_XamarinNativeLibraryDirectory)/Microsoft.$(_PlatformName).registrar.coreclr.a + <_LibPartialStaticRegistrar Condition="'$(_XamarinRuntime)' == 'NativeAOT'">$(_XamarinNativeLibraryDirectory)/Microsoft.$(_PlatformName).registrar.nativeaot.a <_MonoRuntimePackPath>%(_MonoFrameworkReference.RuntimePackPath)/runtimes/$(RuntimeIdentifier)/ @@ -901,13 +953,16 @@ publish (except the merged app bundle, which we'll handle ourselves). --> - <_ComputeVariablesDependsOn Condition="'$(RuntimeIdentifiers)' == ''">$(_ComputeVariablesDependsOn);ComputeResolvedFilesToPublishList + <_ComputeVariablesDependsOn Condition="'$(RuntimeIdentifiers)' == '' And '$(_UseNativeAot)' != 'true'">$(_ComputeVariablesDependsOn);ComputeResolvedFilesToPublishList <_RunAotCompiler>false + + + <_RunAotCompiler Condition="'$(_SdkIsSimulator)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst'">true @@ -952,7 +1007,9 @@ <_LibXamarinLinkMode Condition="'$(_LibXamarinLinkMode)' == ''">static <_LibXamarinExtension Condition="'$(_LibXamarinLinkMode)' == 'dylib'">dylib <_LibXamarinExtension Condition="'$(_LibXamarinLinkMode)' == 'static'">a - <_LibXamarinRuntime Condition="'$(UseMonoRuntime)' != 'true'">-coreclr + <_LibXamarinRuntime Condition="'$(_XamarinRuntime)' == 'MonoVM'"> + <_LibXamarinRuntime Condition="'$(_XamarinRuntime)' == 'CoreCLR'">-coreclr + <_LibXamarinRuntime Condition="'$(_XamarinRuntime)' == 'NativeAOT'">-nativeaot <_LibXamarinDebug Condition="'$(_BundlerDebug)' == 'true'">-debug <_LibXamarinName Condition="'$(_LibXamarinName)' == ''">libxamarin-dotnet$(_LibXamarinRuntime)$(_LibXamarinDebug).$(_LibXamarinExtension) @@ -1121,6 +1178,117 @@ + + + + static + + + + + + + + + + + + + + + + <_UpdatedManagedAssemblyToLink Include="@(ManagedAssemblyToLink->'$(IntermediateLinkDir)%(Filename)%(Extension)')" Condition="Exists('$(IntermediateLinkDir)%(Filename)%(Extension)')" /> + + + + + + + + + + + + + + + <_NativeExecutableObjectFiles Include="$(NativeObject)" /> + + + + + <_TrimmerRootAssemblyButOnlyIntermediateAssembly Include="@(TrimmerRootAssembly)" Condition="'@(TrimmerRootAssembly)' == '@(IntermediateAssembly)' And '%(Identity)' != ''" /> + + + + + + + <_LinkerArgsSplitBySemiColon>@(LinkerArg->Replace(' ',';')) + + + <_CustomLinkFlags Include="$(_LinkerArgsSplitBySemiColon.Split(';'))" /> + + + + + + + + + + <_GenerateBindingsDependsOn> _ComputeBindingVariables; @@ -1165,6 +1333,11 @@ _ComputeNativeExecutableInputs; _AOTCompile; + + <_CompileNativeExecutableDependsOn Condition="'$(_UseNativeAot)' == 'true'"> + $(_CompileNativeExecutableDependsOn); + IlcCompile; + TrimMode - <_DefaultLinkMode Condition="'$(_PlatformName)' == 'macOS'">None - <_DefaultLinkMode Condition="'$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly - <_DefaultLinkMode Condition="'$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None - <_DefaultLinkMode Condition="'$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None - <_DefaultLinkMode Condition="'$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true'">Full + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'macOS'">None + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None + <_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly @@ -1488,7 +1662,7 @@ '%(ResolvedFileToPublish.Filename)%(ResolvedFileToPublish.Extension)' == '$(_GlobalizationDataFile)' And '%(ResolvedFileToPublish.NuGetPackageId)' == '$(_MonoNugetPackageId)' " - PublishFolderType="Assembly" + PublishFolderType="$(_GlobalizationDataFileLocation)" /> @@ -1528,7 +1702,7 @@ <_CreateDumpExecutable Include="@(ResolvedFileToPublish)" - Condition=" '$(UseMonoRuntime)' == 'false' And + Condition=" '$(_XamarinRuntime)' == 'CoreCLR' And '%(ResolvedFileToPublish.Filename)' == 'createdump' And '%(ResolvedFileToPublish.Extension)' == '' And '%(ResolvedFileToPublish.AssetType)' == 'native' And diff --git a/external/MonoTouch.Dialog b/external/MonoTouch.Dialog index 94359c74ef48..f500f9a48dbf 160000 --- a/external/MonoTouch.Dialog +++ b/external/MonoTouch.Dialog @@ -1 +1 @@ -Subproject commit 94359c74ef481ce7b5daa28b890f35a6e77d94c8 +Subproject commit f500f9a48dbf856c693b255078e1507cf1e8edde diff --git a/external/Touch.Unit b/external/Touch.Unit index 8d80e1f10414..5739adefc261 160000 --- a/external/Touch.Unit +++ b/external/Touch.Unit @@ -1 +1 @@ -Subproject commit 8d80e1f10414ec85afa14c8c45a05334eb37c6dd +Subproject commit 5739adefc261b7bfeb70ff718c7b2d97bdfa42ee diff --git a/mk/rules.mk b/mk/rules.mk index 2d309e3389fa..6910cdda651e 100644 --- a/mk/rules.mk +++ b/mk/rules.mk @@ -297,6 +297,8 @@ $(eval $(call NativeCompilationTemplate,-dotnet,-O2 -DDOTNET)) $(eval $(call NativeCompilationTemplate,-dotnet-debug,-DDEBUG -DDOTNET)) $(eval $(call NativeCompilationTemplate,-dotnet-coreclr,-O2 -DCORECLR_RUNTIME -DDOTNET)) $(eval $(call NativeCompilationTemplate,-dotnet-coreclr-debug,-DDEBUG -DCORECLR_RUNTIME -DDOTNET)) +$(eval $(call NativeCompilationTemplate,-dotnet-nativeaot,-O2 -DCORECLR_RUNTIME -DDOTNET -DNATIVEAOT)) +$(eval $(call NativeCompilationTemplate,-dotnet-nativeaot-debug,-DDEBUG -DCORECLR_RUNTIME -DDOTNET -DNATIVEAOT)) .libs/iphoneos .libs/iphonesimulator .libs/watchos .libs/watchsimulator .libs/tvos .libs/tvsimulator .libs/maccatalyst .libs/mac: $(Q) mkdir -p $@ diff --git a/runtime/Makefile b/runtime/Makefile index 2db40b5d7b0f..ea15e991e25c 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -22,7 +22,7 @@ SHIPPED_HEADERS += \ xamarin/monovm-bridge.h \ xamarin/coreclr-bridge.h \ -SHARED_SOURCES += mono-runtime.m bindings.m bindings-generated.m shared.m runtime.m trampolines.m trampolines-invoke.m xamarin-support.m nsstring-localization.m trampolines-varargs.m monovm-bridge.m coreclr-bridge.m +SHARED_SOURCES += mono-runtime.m bindings.m bindings-generated.m shared.m runtime.m trampolines.m trampolines-invoke.m xamarin-support.m nsstring-localization.m trampolines-varargs.m monovm-bridge.m coreclr-bridge.m nativeaot-bridge.m SHARED_I386_SOURCES += trampolines-i386.m trampolines-i386-asm.s trampolines-i386-objc_msgSend.s trampolines-i386-objc_msgSendSuper.s trampolines-i386-objc_msgSend_stret.s trampolines-i386-objc_msgSendSuper_stret.s SHARED_X86_64_SOURCES += trampolines-x86_64.m trampolines-x86_64-asm.s trampolines-x86_64-objc_msgSend.s trampolines-x86_64-objc_msgSendSuper.s trampolines-x86_64-objc_msgSend_stret.s trampolines-x86_64-objc_msgSendSuper_stret.s SHARED_ARM64_SOURCES += trampolines-arm64.m trampolines-arm64-asm.s trampolines-arm64-objc_msgSend.s trampolines-arm64-objc_msgSendSuper.s @@ -454,6 +454,11 @@ MAC_LIBS = \ # This is used when using the CoreCLR runtime instead of Mono. # CORECLR_RUNTIME is defined for these versions of libxamarin. # +# libxamarin-nativeaot.a: +# This is used when using NativeAOT. +# CORECLR_RUNTIME is defined for these versions of libxamarin (because the nativeaot bridge shares *a lot* of code with the coreclr bridge) +# NATIVEAOT is defined for these versions of libxamarin +# ifdef INCLUDE_XAMARIN_LEGACY all-local:: $(TARGETS) @@ -614,6 +619,15 @@ endef $(foreach platform,$(DOTNET_CORECLR_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(eval $(call DotNetCoreClrLibTemplate,$(platform),$(rid))))) +define DotNetNativeAotLibTemplate +DOTNET_TARGETS += \ + $(DOTNET_DESTDIR)/Microsoft.$(1).Runtime.$(2)/runtimes/$(2)/native/libxamarin-dotnet-nativeaot.a \ + $(DOTNET_DESTDIR)/Microsoft.$(1).Runtime.$(2)/runtimes/$(2)/native/libxamarin-dotnet-nativeaot-debug.a \ + +endef + +$(foreach platform,$(DOTNET_NATIVEAOT_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(eval $(call DotNetNativeAotLibTemplate,$(platform),$(rid))))) + # a few lookup tables, because the data we have is not always in the format we need it DOTNET_iphonesimulator_DYLIB_FLAGS=-lmonosgen-2.0 -licudata -licui18n -licuuc -framework UIKit DOTNET_iphoneos_DYLIB_FLAGS=-lmonosgen-2.0 -licudata -licui18n -licuuc -framework UIKit @@ -704,6 +718,8 @@ $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIM $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_DEBUG,-dotnet-debug,,.mono))))) $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR,-dotnet-coreclr,_CORECLR))))) $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR_DEBUG,-dotnet-coreclr-debug,_CORECLR))))) +$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATIVEAOT,-dotnet-nativeaot,_NATIVEAOT,.mono))))) +$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATIVEAOT_DEBUG,-dotnet-nativeaot-debug,_NATIVEAOT,.mono))))) # # DotNetLibExtensionTemplate builds lib[tv]extension.a @@ -731,6 +747,7 @@ endef $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),,-dotnet,,))))) $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR,-dotnet-coreclr,_CORECLR))))) +$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATOVEAOT,-dotnet-nativeaot,_NATOVEAOT))))) dotnet: $(DOTNET_TARGETS) diff --git a/runtime/coreclr-bridge.m b/runtime/coreclr-bridge.m index 287c3f963534..ba7ec923e6fc 100644 --- a/runtime/coreclr-bridge.m +++ b/runtime/coreclr-bridge.m @@ -11,6 +11,7 @@ #include #include #include +#include #include "product.h" #include "runtime-internal.h" @@ -477,6 +478,7 @@ munmap ((void *) buf, fd_len); } +#if !defined (NATIVEAOT) bool xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues) { @@ -510,6 +512,7 @@ return rv == 0; } +#endif // !defined (NATIVEAOT) void xamarin_install_nsautoreleasepool_hooks () @@ -537,18 +540,20 @@ xamarin_assertion_message ("%s threw an exception: %p = %s", method, gchandle, [xamarin_print_all_exceptions (gchandle) UTF8String]); } -typedef void (*xamarin_runtime_initialize_decl)(struct InitializationOptions* options); +#if !defined (NATIVEAOT) +typedef void (*xamarin_runtime_initialize_decl)(struct InitializationOptions* options, GCHandle* exception_gchandle); void xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle) { void *del = NULL; - int rv = coreclr_create_delegate (coreclr_handle, coreclr_domainId, PRODUCT ", Version=0.0.0.0", "ObjCRuntime.Runtime", "Initialize", &del); + int rv = coreclr_create_delegate (coreclr_handle, coreclr_domainId, PRODUCT ", Version=0.0.0.0", "ObjCRuntime.Runtime", "SafeInitialize", &del); if (rv != 0) xamarin_assertion_message ("xamarin_bridge_call_runtime_initialize: failed to create delegate: %i\n", rv); xamarin_runtime_initialize_decl runtime_initialize = (xamarin_runtime_initialize_decl) del; - runtime_initialize (options); + runtime_initialize (options, exception_gchandle); } +#endif // !defined (NATIVEAOT) void xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle) @@ -737,6 +742,7 @@ return rv; } +#if !defined (NATIVEAOT) int mono_jit_exec (MonoDomain * domain, MonoAssembly * assembly, int argc, const char** argv) { @@ -766,6 +772,7 @@ return (int) exitCode; } +#endif // !defined (NATIVEAOT) MonoGHashTable * mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type) diff --git a/runtime/monotouch-main.m b/runtime/monotouch-main.m index 4f9646b6bd47..c2f8cc0ed30f 100644 --- a/runtime/monotouch-main.m +++ b/runtime/monotouch-main.m @@ -454,12 +454,14 @@ - (void) memoryWarning: (NSNotification *) sender xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while opening an assembly"); } +#if SUPPORTS_DYNAMIC_REGISTRATION if (xamarin_supports_dynamic_registration) { MonoReflectionAssembly *rassembly = mono_assembly_get_object (mono_domain_get (), assembly); xamarin_register_entry_assembly (rassembly, &exception_gchandle); xamarin_mono_object_release (&rassembly); xamarin_process_fatal_exception_gchandle (exception_gchandle, "An exception occurred while opening the entry assembly"); } +#endif // SUPPORTS_DYNAMIC_REGISTRATION DEBUG_LAUNCH_TIME_PRINT ("\tAssembly register time"); diff --git a/runtime/nativeaot-bridge.m b/runtime/nativeaot-bridge.m new file mode 100644 index 000000000000..74587bb31399 --- /dev/null +++ b/runtime/nativeaot-bridge.m @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* +* Authors: Rolf Bjarne Kvinge +* +* Copyright (C) 2023 Microsoft Corp. +* +*/ + +#if defined (NATIVEAOT) + +#include +#include +#include +#include +#include + +#include "product.h" +#include "runtime-internal.h" +#include "slinked-list.h" +#include "xamarin/xamarin.h" +#include "xamarin/coreclr-bridge.h" +#include "xamarin/nativeaot-bridge.h" + +void +xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle) +{ + xamarin_objcruntime_runtime_nativeaotinitialize (options, exception_gchandle); +} + +bool +xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues) +{ + return true; +} + +int +mono_jit_exec (MonoDomain * domain, MonoAssembly * assembly, int argc, const char** argv) +{ + return __managed__Main (argc, argv); +} + +#endif // NATIVEAOT diff --git a/runtime/runtime.m b/runtime/runtime.m index b38ff6661f8a..dfb9123876d3 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -82,7 +82,9 @@ enum MarshalManagedExceptionMode xamarin_marshal_managed_exception_mode = MarshalManagedExceptionModeDefault; enum XamarinTriState xamarin_log_exceptions = XamarinTriStateNone; enum XamarinLaunchMode xamarin_launch_mode = XamarinLaunchModeApp; +#if SUPPORTS_DYNAMIC_REGISTRATION bool xamarin_supports_dynamic_registration = true; +#endif const char *xamarin_runtime_configuration_name = NULL; #if DOTNET @@ -141,6 +143,7 @@ /* unused = 0x08,*/ InitializationFlagsIsSimulator = 0x10, InitializationFlagsIsCoreCLR = 0x20, + InitializationFlagsIsNativeAOT = 0x40, }; struct InitializationOptions { @@ -966,7 +969,9 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; xamarin_register_monoassembly (MonoAssembly *assembly, GCHandle *exception_gchandle) { // COOP: this is a function executed only at startup, I believe the mode here doesn't matter. +#if SUPPORTS_DYNAMIC_REGISTRATION if (!xamarin_supports_dynamic_registration) { +#endif #if defined (CORECLR_RUNTIME) if (xamarin_log_level > 0) { MonoReflectionAssembly *rassembly = mono_assembly_get_object (mono_domain_get (), assembly); @@ -983,11 +988,16 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; LOG (PRODUCT ": Skipping assembly registration for %s since it's not needed (dynamic registration is not supported)", mono_assembly_name_get_name (mono_assembly_get_name (assembly))); #endif return true; +#if SUPPORTS_DYNAMIC_REGISTRATION } +#endif + +#if SUPPORTS_DYNAMIC_REGISTRATION MonoReflectionAssembly *rassembly = mono_assembly_get_object (mono_domain_get (), assembly); xamarin_register_assembly (rassembly, exception_gchandle); xamarin_mono_object_release (&rassembly); return *exception_gchandle == INVALID_GCHANDLE; +#endif // SUPPORTS_DYNAMIC_REGISTRATION } // Returns a retained MonoObject. Caller must release. @@ -1293,6 +1303,9 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; #if defined (CORECLR_RUNTIME) options.flags = (enum InitializationFlags) (options.flags | InitializationFlagsIsCoreCLR); #endif +#if defined (NATIVEAOT) + options.flags = (enum InitializationFlags) (options.flags | InitializationFlagsIsNativeAOT); +#endif options.Delegates = &delegates; options.Trampolines = &trampolines; @@ -1304,12 +1317,14 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; #endif #if defined (CORECLR_RUNTIME) +#if !defined(__arm__) // the dynamic trampolines haven't been implemented in 32-bit ARM assembly. options.xamarin_objc_msgsend = (void *) xamarin_dyn_objc_msgSend; options.xamarin_objc_msgsend_super = (void *) xamarin_dyn_objc_msgSendSuper; #if !defined(__aarch64__) options.xamarin_objc_msgsend_stret = (void *) xamarin_dyn_objc_msgSend_stret; options.xamarin_objc_msgsend_super_stret = (void *) xamarin_dyn_objc_msgSendSuper_stret; #endif // !defined(__aarch64__) +#endif // !defined(__arm__) options.unhandled_exception_handler = (void *) &xamarin_coreclr_unhandled_exception_handler; options.reference_tracking_begin_end_callback = (void *) &xamarin_coreclr_reference_tracking_begin_end_callback; options.reference_tracking_is_referenced_callback = (void *) &xamarin_coreclr_reference_tracking_is_referenced_callback; @@ -2574,12 +2589,14 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; int subtractPropertyCount = 0; if (xamarin_icu_dat_file_name != NULL && *xamarin_icu_dat_file_name != 0) { +#if !defined (NATIVEAOT) char path [1024]; if (!xamarin_locate_app_resource (xamarin_icu_dat_file_name, path, sizeof (path))) { LOG (PRODUCT ": Could not locate the ICU data file '%s' in the app bundle.\n", xamarin_icu_dat_file_name); } else { icu_dat_file_path = strdup (path); } +#endif // !defined (NATIVEAOT) } else { subtractPropertyCount++; } diff --git a/runtime/xamarin/main.h b/runtime/xamarin/main.h index 201a09a24d82..a3b51d7745e5 100644 --- a/runtime/xamarin/main.h +++ b/runtime/xamarin/main.h @@ -99,6 +99,12 @@ enum XamarinTriState : int { extern bool mono_use_llvm; // this is defined inside mono +#if defined (NATIVEAOT) +#define SUPPORTS_DYNAMIC_REGISTRATION 0 +#else +#define SUPPORTS_DYNAMIC_REGISTRATION 1 +#endif + #if DEBUG extern bool xamarin_gc_pump; #endif @@ -121,7 +127,9 @@ extern bool xamarin_is_gc_coop; extern enum MarshalObjectiveCExceptionMode xamarin_marshal_objectivec_exception_mode; extern enum MarshalManagedExceptionMode xamarin_marshal_managed_exception_mode; extern enum XamarinLaunchMode xamarin_launch_mode; +#if SUPPORTS_DYNAMIC_REGISTRATION extern bool xamarin_supports_dynamic_registration; +#endif extern const char *xamarin_runtime_configuration_name; extern enum XamarinNativeLinkMode xamarin_libmono_native_link_mode; extern const char** xamarin_runtime_libraries; diff --git a/runtime/xamarin/nativeaot-bridge.h b/runtime/xamarin/nativeaot-bridge.h new file mode 100644 index 000000000000..6de5ad88117b --- /dev/null +++ b/runtime/xamarin/nativeaot-bridge.h @@ -0,0 +1,26 @@ + +/* Support for using NativeAOT */ + +#if defined (NATIVEAOT) + +#ifndef __NATIVEAOT_BRIDGE__ +#define __NATIVEAOT_BRIDGE__ + +#include + +#include "runtime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void xamarin_objcruntime_runtime_nativeaotinitialize (struct InitializationOptions* options, GCHandle* exception_gchandle); +int __managed__Main (int argc, const char** argv); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __NATIVEAOT_BRIDGE__ */ + +#endif // NATIVEAOT diff --git a/src/Foundation/NSObject2.cs b/src/Foundation/NSObject2.cs index f88f1a0492c2..1f645d3044ba 100644 --- a/src/Foundation/NSObject2.cs +++ b/src/Foundation/NSObject2.cs @@ -305,6 +305,12 @@ static void RegisterToggleReference (NSObject obj, IntPtr handle, bool isCustomT { #if NET && __MACOS__ Runtime.RegisterToggleReferenceCoreCLR (obj, handle, isCustomType); +#elif NET + if (Runtime.IsCoreCLR) { + Runtime.RegisterToggleReferenceCoreCLR (obj, handle, isCustomType); + } else { + RegisterToggleRef (obj, handle, isCustomType); + } #else RegisterToggleRef (obj, handle, isCustomType); #endif diff --git a/src/ILLink.Substitutions.MacCatalyst.xml b/src/ILLink.Substitutions.MacCatalyst.xml index 82dfcf97ae5c..21704812349f 100644 --- a/src/ILLink.Substitutions.MacCatalyst.xml +++ b/src/ILLink.Substitutions.MacCatalyst.xml @@ -4,7 +4,10 @@ - + + + + diff --git a/src/ILLink.Substitutions.ios.xml b/src/ILLink.Substitutions.ios.xml index 00e9e50e50e6..c4d2a0a4228e 100644 --- a/src/ILLink.Substitutions.ios.xml +++ b/src/ILLink.Substitutions.ios.xml @@ -4,7 +4,10 @@ - + + + + diff --git a/src/ILLink.Substitutions.macOS.xml b/src/ILLink.Substitutions.macOS.xml index a0fd78280ac9..e993b4cc124c 100644 --- a/src/ILLink.Substitutions.macOS.xml +++ b/src/ILLink.Substitutions.macOS.xml @@ -5,6 +5,8 @@ + + diff --git a/src/ILLink.Substitutions.tvos.xml b/src/ILLink.Substitutions.tvos.xml index e03cc08a2fba..d057a9395ad0 100644 --- a/src/ILLink.Substitutions.tvos.xml +++ b/src/ILLink.Substitutions.tvos.xml @@ -4,7 +4,10 @@ - + + + + diff --git a/src/ObjCRuntime/Runtime.CoreCLR.cs b/src/ObjCRuntime/Runtime.CoreCLR.cs index b9f3622fda0e..5dfe7e77734e 100644 --- a/src/ObjCRuntime/Runtime.CoreCLR.cs +++ b/src/ObjCRuntime/Runtime.CoreCLR.cs @@ -506,7 +506,16 @@ static IntPtr GetAssemblyName (IntPtr gchandle) static IntPtr GetAssemblyLocation (IntPtr gchandle) { var asm = (Assembly?) GetGCHandleTarget (gchandle); - return Marshal.StringToHGlobalAuto (asm?.Location); + if (asm is null) + return IntPtr.Zero; + + string location; + if (IsNativeAOT) { + location = Path.Combine (System.AppContext.BaseDirectory, asm.GetName ().Name + ".dll"); + } else { + location = asm.Location; + } + return Marshal.StringToHGlobalAuto (location); } static void SetFlagsForNSObject (IntPtr gchandle, byte flags) diff --git a/src/ObjCRuntime/Runtime.cs b/src/ObjCRuntime/Runtime.cs index f411a851b93e..f86fc65711d0 100644 --- a/src/ObjCRuntime/Runtime.cs +++ b/src/ObjCRuntime/Runtime.cs @@ -159,6 +159,7 @@ internal enum InitializationFlags : int { IsSimulator = 0x10, #if NET IsCoreCLR = 0x20, + IsNativeAOT = 0x40, #endif } @@ -222,6 +223,14 @@ internal unsafe static bool IsCoreCLR { return (options->Flags.HasFlag (InitializationFlags.IsCoreCLR)); } } + + [BindingImpl (BindingImplOptions.Optimizable)] + internal unsafe static bool IsNativeAOT { + get { + // The linker may turn calls to this property into a constant + return (options->Flags.HasFlag (InitializationFlags.IsNativeAOT)); + } + } #endif [BindingImpl (BindingImplOptions.Optimizable)] @@ -249,6 +258,20 @@ internal static bool Initialized { static extern int _NSGetExecutablePath (byte[] buf, ref int bufsize); #endif +#if NET + [Preserve] // called from native - nativeaot-bridge.m and coreclr-bridge.m. + [UnmanagedCallersOnly (EntryPoint = "xamarin_objcruntime_runtime_nativeaotinitialize")] + unsafe static void SafeInitialize (InitializationOptions* options, IntPtr* exception_gchandle) + { + *exception_gchandle = IntPtr.Zero; + try { + Initialize (options); + } catch (Exception e) { + *exception_gchandle = AllocGCHandle (e); + } + } +#endif + [Preserve] // called from native - runtime.m. [BindingImpl (BindingImplOptions.Optimizable)] // To inline the Runtime.DynamicRegistrationSupported code if possible. unsafe static void Initialize (InitializationOptions* options) diff --git a/tests/ComputeRegistrarConstant.targets b/tests/ComputeRegistrarConstant.targets index 6e6c743e890e..9d5d2e9dcaf5 100644 --- a/tests/ComputeRegistrarConstant.targets +++ b/tests/ComputeRegistrarConstant.targets @@ -1,12 +1,12 @@ - + true true - + true true diff --git a/tests/bindings-test/ProtocolTest.cs b/tests/bindings-test/ProtocolTest.cs index ba1d57be1f92..d1fa363842a0 100644 --- a/tests/bindings-test/ProtocolTest.cs +++ b/tests/bindings-test/ProtocolTest.cs @@ -164,50 +164,50 @@ public void ProtocolMembers () methods = protocol_copyMethodDescriptionList (protocol, true, true); CleanupSignatures (methods); Assert.AreEqual (4, methods.Length, "Required Instance Methods: Count"); - Assert.That (methods, Contains.Item (new objc_method_description ("requiredInstanceMethod", "v@:")), "Required Instance Methods: requiredInstanceMethod"); - Assert.That (methods, Contains.Item (new objc_method_description ("requiredInstanceProperty", "@@:")), "Required Instance Methods: requiredInstanceProperty"); - Assert.That (methods, Contains.Item (new objc_method_description ("setRequiredInstanceProperty:", "v@:@")), "Required Instance Methods: setRequiredInstanceProperty"); - Assert.That (methods, Contains.Item (new objc_method_description ("requiredReadonlyProperty", "@@:")), "Required Instance Methods: requiredReadonlyProperty:"); + AssertContains (methods, new objc_method_description ("requiredInstanceMethod", "v@:"), "Required Instance Methods: requiredInstanceMethod"); + AssertContains (methods, new objc_method_description ("requiredInstanceProperty", "@@:"), "Required Instance Methods: requiredInstanceProperty"); + AssertContains (methods, new objc_method_description ("setRequiredInstanceProperty:", "v@:@"), "Required Instance Methods: setRequiredInstanceProperty"); + AssertContains (methods, new objc_method_description ("requiredReadonlyProperty", "@@:"), "Required Instance Methods: requiredReadonlyProperty:"); // Required static methods methods = protocol_copyMethodDescriptionList (protocol, true, false); CleanupSignatures (methods); Assert.AreEqual (3, methods.Length, "Required Static Methods: Count"); - Assert.That (methods, Contains.Item (new objc_method_description ("requiredStaticMethod", "v@:")), "Required Static Methods: requiredStaticMethod"); - Assert.That (methods, Contains.Item (new objc_method_description ("setRequiredStaticProperty:", "v@:@")), "Required Static Methods: setRequiredStaticProperty:"); - Assert.That (methods, Contains.Item (new objc_method_description ("requiredStaticProperty", "@@:")), "Required Static Methods: requiredStaticProperty"); + AssertContains (methods, new objc_method_description ("requiredStaticMethod", "v@:"), "Required Static Methods: requiredStaticMethod"); + AssertContains (methods, new objc_method_description ("setRequiredStaticProperty:", "v@:@"), "Required Static Methods: setRequiredStaticProperty:"); + AssertContains (methods, new objc_method_description ("requiredStaticProperty", "@@:"), "Required Static Methods: requiredStaticProperty"); // Optional instance methods methods = protocol_copyMethodDescriptionList (protocol, false, true); CleanupSignatures (methods); Assert.AreEqual (19, methods.Length, "Optional Instance Methods: Count"); - Assert.That (methods, Contains.Item (new objc_method_description ("variadicMethod:", "v@:^v")), "Optional Instance Methods: variadicMethod:"); - Assert.That (methods, Contains.Item (new objc_method_description ("methodWithReturnType", "@@:")), "Optional Instance Methods: methodWithReturnType"); - Assert.That (methods, Contains.Item (new objc_method_description ("methodWithParameter:", "v@:i")), "Optional Instance Methods: methodWithParameter:"); - Assert.That (methods, Contains.Item (new objc_method_description ("methodWithParameters:second:third:fourth:", "v@:iiii")), "Optional Instance Methods: methodWithParameters:second:third:fourth:"); - Assert.That (methods, Contains.Item (new objc_method_description ("optionalInstanceMethod", "v@:")), "Optional Instance Methods: optionalInstanceMethod"); - Assert.That (methods, Contains.Item (new objc_method_description ("methodWithRefParameters:second:third:fourth:", "v@:i^i^ii")), "Optional Instance Methods: methodWithRefParameters:second:third:fourth:"); - Assert.That (methods, Contains.Item (new objc_method_description ("optionalInstanceProperty", "@@:")), "Optional Instance Methods: optionalInstanceProperty"); - Assert.That (methods, Contains.Item (new objc_method_description ("setOptionalInstanceProperty:", "v@:@")), "Optional Instance Methods: setOptionalInstanceProperty:"); - Assert.That (methods, Contains.Item (new objc_method_description ("get_propertyWithCustomAccessors", "@@:")), "Optional Instance Methods: get_propertyWithCustomAccessors"); - Assert.That (methods, Contains.Item (new objc_method_description ("set_propertyWithCustomAccessors:", "v@:@")), "Optional Instance Methods: set_propertyWithCustomAccessors:"); - Assert.That (methods, Contains.Item (new objc_method_description ("propertyWithArgumentSemanticNone", "@@:")), "Optional Instance Methods: propertyWithArgumentSemanticNone"); - Assert.That (methods, Contains.Item (new objc_method_description ("setPropertyWithArgumentSemanticNone:", "v@:@")), "Optional Instance Methods: setPropertyWithArgumentSemanticNone:"); - Assert.That (methods, Contains.Item (new objc_method_description ("propertyWithArgumentSemanticCopy", "@@:")), "Optional Instance Methods: propertyWithArgumentSemanticCopy"); - Assert.That (methods, Contains.Item (new objc_method_description ("setPropertyWithArgumentSemanticCopy:", "v@:@")), "Optional Instance Methods: setPropertyWithArgumentSemanticCopy:"); - Assert.That (methods, Contains.Item (new objc_method_description ("propertyWithArgumentSemanticAssign", "@@:")), "Optional Instance Methods: propertyWithArgumentSemanticAssign"); - Assert.That (methods, Contains.Item (new objc_method_description ("setPropertyWithArgumentSemanticAssign:", "v@:@")), "Optional Instance Methods: setPropertyWithArgumentSemanticAssign:"); - Assert.That (methods, Contains.Item (new objc_method_description ("readonlyProperty", "@@:")), "Optional Instance Methods: readonlyProperty:"); - Assert.That (methods, Contains.Item (new objc_method_description ("propertyWithArgumentSemanticRetain", "@@:")), "Optional Instance Methods: propertyWithArgumentSemanticRetain"); - Assert.That (methods, Contains.Item (new objc_method_description ("setPropertyWithArgumentSemanticRetain:", "v@:@")), "Optional Instance Methods: setPropertyWithArgumentSemanticRetain:"); + AssertContains (methods, new objc_method_description ("variadicMethod:", "v@:^v"), "Optional Instance Methods: variadicMethod:"); + AssertContains (methods, new objc_method_description ("methodWithReturnType", "@@:"), "Optional Instance Methods: methodWithReturnType"); + AssertContains (methods, new objc_method_description ("methodWithParameter:", "v@:i"), "Optional Instance Methods: methodWithParameter:"); + AssertContains (methods, new objc_method_description ("methodWithParameters:second:third:fourth:", "v@:iiii"), "Optional Instance Methods: methodWithParameters:second:third:fourth:"); + AssertContains (methods, new objc_method_description ("optionalInstanceMethod", "v@:"), "Optional Instance Methods: optionalInstanceMethod"); + AssertContains (methods, new objc_method_description ("methodWithRefParameters:second:third:fourth:", "v@:i^i^ii"), "Optional Instance Methods: methodWithRefParameters:second:third:fourth:"); + AssertContains (methods, new objc_method_description ("optionalInstanceProperty", "@@:"), "Optional Instance Methods: optionalInstanceProperty"); + AssertContains (methods, new objc_method_description ("setOptionalInstanceProperty:", "v@:@"), "Optional Instance Methods: setOptionalInstanceProperty:"); + AssertContains (methods, new objc_method_description ("get_propertyWithCustomAccessors", "@@:"), "Optional Instance Methods: get_propertyWithCustomAccessors"); + AssertContains (methods, new objc_method_description ("set_propertyWithCustomAccessors:", "v@:@"), "Optional Instance Methods: set_propertyWithCustomAccessors:"); + AssertContains (methods, new objc_method_description ("propertyWithArgumentSemanticNone", "@@:"), "Optional Instance Methods: propertyWithArgumentSemanticNone"); + AssertContains (methods, new objc_method_description ("setPropertyWithArgumentSemanticNone:", "v@:@"), "Optional Instance Methods: setPropertyWithArgumentSemanticNone:"); + AssertContains (methods, new objc_method_description ("propertyWithArgumentSemanticCopy", "@@:"), "Optional Instance Methods: propertyWithArgumentSemanticCopy"); + AssertContains (methods, new objc_method_description ("setPropertyWithArgumentSemanticCopy:", "v@:@"), "Optional Instance Methods: setPropertyWithArgumentSemanticCopy:"); + AssertContains (methods, new objc_method_description ("propertyWithArgumentSemanticAssign", "@@:"), "Optional Instance Methods: propertyWithArgumentSemanticAssign"); + AssertContains (methods, new objc_method_description ("setPropertyWithArgumentSemanticAssign:", "v@:@"), "Optional Instance Methods: setPropertyWithArgumentSemanticAssign:"); + AssertContains (methods, new objc_method_description ("readonlyProperty", "@@:"), "Optional Instance Methods: readonlyProperty:"); + AssertContains (methods, new objc_method_description ("propertyWithArgumentSemanticRetain", "@@:"), "Optional Instance Methods: propertyWithArgumentSemanticRetain"); + AssertContains (methods, new objc_method_description ("setPropertyWithArgumentSemanticRetain:", "v@:@"), "Optional Instance Methods: setPropertyWithArgumentSemanticRetain:"); // Optional static methods methods = protocol_copyMethodDescriptionList (protocol, false, false); CleanupSignatures (methods); Assert.AreEqual (3, methods.Length, "Optional Static Methods: Count"); - Assert.That (methods, Contains.Item (new objc_method_description ("optionalStaticMethod", "v@:")), "Optional Static Methods: optionalStaticMethod"); - Assert.That (methods, Contains.Item (new objc_method_description ("optionalStaticProperty", "@@:")), "Optional Static Methods: optionalStaticProperty"); - Assert.That (methods, Contains.Item (new objc_method_description ("setOptionalStaticProperty:", "v@:@")), "Optional Static Methods: setOptionalStaticProperty:"); + AssertContains (methods, new objc_method_description ("optionalStaticMethod", "v@:"), "Optional Static Methods: optionalStaticMethod"); + AssertContains (methods, new objc_method_description ("optionalStaticProperty", "@@:"), "Optional Static Methods: optionalStaticProperty"); + AssertContains (methods, new objc_method_description ("setOptionalStaticProperty:", "v@:@"), "Optional Static Methods: setOptionalStaticProperty:"); objc_property [] properties; properties = protocol_copyPropertyList (protocol); @@ -221,60 +221,75 @@ public void ProtocolMembers () Assert.AreEqual (2, properties.Length, "Properties: Count"); } - Assert.That (properties, Contains.Item (new objc_property ("requiredInstanceProperty", "T@\"NSString\",N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("requiredInstanceProperty", "T@\"NSString\",N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", "") - })), "Properties: requiredInstanceProperty"); + }), "Properties: requiredInstanceProperty"); - Assert.That (properties, Contains.Item (new objc_property ("requiredReadonlyProperty", "T@\"NSString\",R,N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("requiredReadonlyProperty", "T@\"NSString\",R,N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("R", ""), new objc_property_attribute ("N", "") - })), "Properties: requiredReadonlyProperty"); + }), "Properties: requiredReadonlyProperty"); if (XamarinTests.ObjCRuntime.Registrar.IsStaticRegistrar) { - Assert.That (properties, Contains.Item (new objc_property ("optionalInstanceProperty", "T@\"NSString\",N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("optionalInstanceProperty", "T@\"NSString\",N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", "") - })), "Properties: optionalInstanceProperty"); + }), "Properties: optionalInstanceProperty"); - Assert.That (properties, Contains.Item (new objc_property ("propertyWithCustomAccessors", "T@\"NSString\",N,Gget_propertyWithCustomAccessors,Sset_propertyWithCustomAccessors:", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("propertyWithCustomAccessors", "T@\"NSString\",N,Gget_propertyWithCustomAccessors,Sset_propertyWithCustomAccessors:", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", ""), new objc_property_attribute ("G", "get_propertyWithCustomAccessors"), new objc_property_attribute ("S", "set_propertyWithCustomAccessors:") - })), "Properties: propertyWithCustomAccessors"); + }), "Properties: propertyWithCustomAccessors"); - Assert.That (properties, Contains.Item (new objc_property ("propertyWithArgumentSemanticNone", "T@\"NSString\",N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("propertyWithArgumentSemanticNone", "T@\"NSString\",N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", "") - })), "Properties: propertyWithArgumentSemanticNone"); + }), "Properties: propertyWithArgumentSemanticNone"); - Assert.That (properties, Contains.Item (new objc_property ("propertyWithArgumentSemanticCopy", "T@\"NSString\",C,N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("propertyWithArgumentSemanticCopy", "T@\"NSString\",C,N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", ""), new objc_property_attribute ("C", "") - })), "Properties: propertyWithArgumentSemanticCopy"); + }), "Properties: propertyWithArgumentSemanticCopy"); - Assert.That (properties, Contains.Item (new objc_property ("propertyWithArgumentSemanticAssign", "T@\"NSString\",N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("propertyWithArgumentSemanticAssign", "T@\"NSString\",N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("N", "") - })), "Properties: propertyWithArgumentSemanticAssign"); + }), "Properties: propertyWithArgumentSemanticAssign"); - Assert.That (properties, Contains.Item (new objc_property ("propertyWithArgumentSemanticRetain", "T@\"NSString\",&,N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("propertyWithArgumentSemanticRetain", "T@\"NSString\",&,N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("&", ""), new objc_property_attribute ("N", "") - })), "Properties: propertyWithArgumentSemanticRetain"); + }), "Properties: propertyWithArgumentSemanticRetain"); - Assert.That (properties, Contains.Item (new objc_property ("readonlyProperty", "T@\"NSString\",R,N", new objc_property_attribute [] { + AssertContains (properties, new objc_property ("readonlyProperty", "T@\"NSString\",R,N", new objc_property_attribute [] { new objc_property_attribute ("T", "@\"NSString\""), new objc_property_attribute ("R", ""), new objc_property_attribute ("N", "") - })), "Properties: readonlyProperty"); + }), "Properties: readonlyProperty"); } } + static void AssertContains (T [] array, T item, string message) where T : IEquatable + { + for (var i = 0; i < array.Length; i++) { + var element = array [i]; + if (element is null && item is null) + return; + if (element is null || item is null) + continue; + if (element.Equals (item)) + return; + } + + throw new Exception ($"Collection {array} does not contain item {item}: {message}"); + } + [DllImport ("/usr/lib/libobjc.dylib")] internal extern static IntPtr objc_getProtocol (string name); diff --git a/tests/dotnet/Net7_0SimpleApp/shared.csproj b/tests/dotnet/Net7_0SimpleApp/shared.csproj index cda1f92953a6..ccb12ab98835 100644 --- a/tests/dotnet/Net7_0SimpleApp/shared.csproj +++ b/tests/dotnet/Net7_0SimpleApp/shared.csproj @@ -6,6 +6,9 @@ MySimpleApp com.xamarin.mysimpleapp 7.0 + + true + true diff --git a/tests/monotouch-test/ObjCRuntime/RegistrarTest.cs b/tests/monotouch-test/ObjCRuntime/RegistrarTest.cs index c9e7eb495195..dd17244c45c2 100644 --- a/tests/monotouch-test/ObjCRuntime/RegistrarTest.cs +++ b/tests/monotouch-test/ObjCRuntime/RegistrarTest.cs @@ -111,7 +111,7 @@ public void RegistrarRemoval () // It's not safe to remove the dynamic registrar in monotouch-test (by design; some of the tested API makes it unsafe, and the linker correctly detects this), // so the dynamic registrar will only be removed if manually requested. // Also removal of the dynamic registrar is not supported in XM -#if OPTIMIZEALL && !__MACOS__ +#if (OPTIMIZEALL && !__MACOS__) || NATIVEAOT var shouldBeRemoved = true; #else var shouldBeRemoved = false; diff --git a/tests/monotouch-test/mono/ConfigTest.cs b/tests/monotouch-test/mono/ConfigTest.cs index 36a554f1151d..32e7fd682ee8 100644 --- a/tests/monotouch-test/mono/ConfigTest.cs +++ b/tests/monotouch-test/mono/ConfigTest.cs @@ -13,8 +13,17 @@ public partial class ConfigTest { [Test] public void Existence () { +#if NATIVEAOT +#if __MACCATALYST__ || __MACOS__ + var config_dir = Path.Combine (Path.GetDirectoryName (AppContext.BaseDirectory.TrimEnd ('/')), "MonoBundle"); +#else + var config_dir = AppContext.BaseDirectory; +#endif + var config_file = Path.Combine (config_dir, Assembly.GetExecutingAssembly ().GetName ().Name + ".dll.config"); +#else var config_file = Assembly.GetExecutingAssembly ().Location + ".config"; - Assert.True (File.Exists (config_file), "existence"); +#endif + Assert.That (config_file, Does.Exist, "existence"); Assert.That (File.ReadAllText (config_file), Contains.Substring ("Xamarin rocks"), "content"); } } diff --git a/tests/monotouch-test/mono/Symbols.cs b/tests/monotouch-test/mono/Symbols.cs index cb24398bbd5f..61aea05ea396 100644 --- a/tests/monotouch-test/mono/Symbols.cs +++ b/tests/monotouch-test/mono/Symbols.cs @@ -20,6 +20,7 @@ public void FunctionNames () Collect (); bool aot = symbols [1].Contains ("MonoTouchFixtures_Symbols_Collect"); + bool nativeaot = symbols [1].Contains ("MonoTouchFixtures_Symbols__Collect"); bool llvmonly = symbols [1].Contains ("mono_llvmonly_runtime_invoke"); // LLVM inlines the Collect function, so 'Collect' doesn't show up in the stack trace :/ bool interp = false; @@ -32,7 +33,7 @@ public void FunctionNames () } } - Assert.IsTrue (aot || interp || llvmonly, $"#1\n\t{string.Join ("\n\t", symbols)}"); + Assert.IsTrue (aot || interp || llvmonly || nativeaot, $"#1\n\t{string.Join ("\n\t", symbols)}"); } void Collect () diff --git a/tests/xharness/Jenkins/TestData.cs b/tests/xharness/Jenkins/TestData.cs index 0fcfe71e46da..62e33f6f21de 100644 --- a/tests/xharness/Jenkins/TestData.cs +++ b/tests/xharness/Jenkins/TestData.cs @@ -23,5 +23,6 @@ class TestData { public string XamMacArch; public string RuntimeIdentifier; public string Registrar; + public bool PublishAot; // NativeAOT } } diff --git a/tests/xharness/Jenkins/TestVariationsFactory.cs b/tests/xharness/Jenkins/TestVariationsFactory.cs index 3af7db146ba6..3ef390bdf80f 100644 --- a/tests/xharness/Jenkins/TestVariationsFactory.cs +++ b/tests/xharness/Jenkins/TestVariationsFactory.cs @@ -101,6 +101,8 @@ IEnumerable GetTestData (RunTestTask test) yield return new TestData { Variation = "Debug (managed static registrar)", Registrar = "managed-static", Debug = true, Profiling = false, Ignored = ignore }; yield return new TestData { Variation = "Release (managed static registrar, all optimizations)", BundlerArguments = "--optimize:all", Registrar = "managed-static", Debug = false, Profiling = false, LinkMode = "Full", Defines = "OPTIMIZEALL", Ignored = ignore }; } + if (test.TestProject.IsDotNetProject) + yield return new TestData { Variation = "Release (NativeAOT)", Debug = false, PublishAot = true, Ignored = ignore, Defines = "NATIVEAOT", LinkMode = "Full" }; break; case string name when name.StartsWith ("mscorlib", StringComparison.Ordinal): if (supports_debug) @@ -127,11 +129,14 @@ IEnumerable GetTestData (RunTestTask test) yield return new TestData { Variation = "Release (all optimizations)", BundlerArguments = "--optimize:all", Registrar = "static", Debug = false, Profiling = false, LinkMode = "Full", Defines = "OPTIMIZEALL", Ignored = ignore }; yield return new TestData { Variation = "Debug (all optimizations)", BundlerArguments = "--optimize:all,-remove-uithread-checks", Registrar = "static", Debug = true, Profiling = false, LinkMode = "Full", Defines = "OPTIMIZEALL", Ignored = ignore ?? !jenkins.TestSelection.IsEnabled (TestLabel.All) }; - if (test.TestProject.IsDotNetProject && mac_supports_arm64) + if (test.TestProject.IsDotNetProject && mac_supports_arm64) { yield return new TestData { Variation = "Debug (ARM64)", Debug = true, Profiling = false, Ignored = !mac_supports_arm64 ? true : ignore, RuntimeIdentifier = arm64_sim_runtime_identifier, }; + yield return new TestData { Variation = "Release (NativeAOT, ARM64)", Debug = false, PublishAot = true, Ignored = ignore, Defines = "NATIVEAOT", RuntimeIdentifier = arm64_sim_runtime_identifier, LinkMode = "Full" }; + } if (test.TestProject.IsDotNetProject) { yield return new TestData { Variation = "Debug (managed static registrar)", Registrar = "managed-static", Debug = true, Profiling = false, Ignored = ignore }; yield return new TestData { Variation = "Release (managed static registrar, all optimizations)", BundlerArguments = "--optimize:all", Registrar = "managed-static", Debug = false, Profiling = false, LinkMode = "Full", Defines = "OPTIMIZEALL", Ignored = ignore }; + yield return new TestData { Variation = "Release (NativeAOT)", Debug = false, PublishAot = true, Ignored = ignore, Defines = "NATIVEAOT", LinkMode = "Full" }; } break; case "introspection": @@ -157,10 +162,21 @@ IEnumerable GetTestData (RunTestTask test) if (test.Platform != TestPlatform.MacCatalyst) { yield return new TestData { Variation = "Debug (static registrar)", Registrar = "static", Debug = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), }; yield return new TestData { Variation = "Debug (static registrar, ARM64)", Registrar = "static", Debug = true, Profiling = false, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) || !mac_supports_arm64, RuntimeIdentifier = arm64_runtime_identifier, }; + // Pending: We need the NativeAOT's runtime bits to ship using runtime packs for macOS (https://github.com/dotnet/runtime/issues/87060) before we can enable this + // yield return new TestData { Variation = "Release (NativeAOT)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), Defines = "NATIVEAOT", LinkMode = "Full" }; + // yield return new TestData { Variation = "Release (NativeAOT, ARM64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) || !mac_supports_arm64, Defines = "NATIVEAOT", RuntimeIdentifier = arm64_runtime_identifier, LinkMode = "Full" }; } if (test.Platform == TestPlatform.MacCatalyst) { yield return new TestData { Variation = "Release (ARM64, LLVM)", Debug = false, UseLlvm = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst) || !mac_supports_arm64, RuntimeIdentifier = arm64_runtime_identifier }; yield return new TestData { Variation = "Release", Debug = false, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst) }; + // Pending: We need to skip this consistency check to support universal apps: + // https://github.com/dotnet/sdk/blob/f90e558092ac61038ffa1017fe3a5aca1af5ae7e/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L224-L226 + // because the outer build has PublishAot=true and no RuntimeIdentifier set. + // Filed as https://github.com/dotnet/sdk/issues/33414. + // yield return new TestData { Variation = "Release (NativeAOT)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst), Defines = "NATIVEAOT", LinkMode = "Full" }; + + yield return new TestData { Variation = "Release (NativeAOT, ARM64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst) || !mac_supports_arm64, Defines = "NATIVEAOT", RuntimeIdentifier = arm64_runtime_identifier, LinkMode = "Full" }; + yield return new TestData { Variation = "Release (NativeAOT, x64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst), Defines = "NATIVEAOT", LinkMode = "Full", RuntimeIdentifier = "maccatalyst-x64" }; } if (test.Platform == TestPlatform.Mac) { yield return new TestData { Variation = "Release", Debug = false, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) }; @@ -220,6 +236,7 @@ public IEnumerable CreateTestVariations (IEnumerable tests, Func CreateTestVariations (IEnumerable tests, Func messages) if (!values [i].HasValue) continue; + // The remove-dynamic-registrar optimization is required when using NativeAOT + if (app.XamarinRuntime == XamarinRuntime.NativeAOT && (Opt) i == Opt.RemoveDynamicRegistrar && values [i] == false) { + messages.Add (ErrorHelper.CreateWarning (2016, Errors.MX2016 /* Keeping the dynamic registrar (by passing '--optimize=-remove-dynamic-registrar') is not possible, because the dynamic registrar is not supported when using NativeAOT. Support for dynamic registration will still be removed. */)); + values [i] = true; + continue; + } + // The remove-dynamic-registrar optimization is a bit if a special case on macOS: // it only works in very specific circumstances, so we don't add it to valid_platforms. // This means it won't be listed in --help, and it won't be enabled if all optimizations @@ -275,7 +282,9 @@ public void Initialize (Application app, out List messages) StaticBlockToDelegateLookup = true; if (!RemoveDynamicRegistrar.HasValue) { - if (InlineDynamicRegistrationSupported != true) { + if (app.XamarinRuntime == XamarinRuntime.NativeAOT) { + RemoveDynamicRegistrar = true; + } else if (InlineDynamicRegistrationSupported != true) { // Can't remove the dynamic registrar unless also inlining Runtime.DynamicRegistrationSupported RemoveDynamicRegistrar = false; } else if (StaticBlockToDelegateLookup != true) { diff --git a/tools/common/Target.cs b/tools/common/Target.cs index c952d93fed1f..5cc2a4e90ad0 100644 --- a/tools/common/Target.cs +++ b/tools/common/Target.cs @@ -687,20 +687,22 @@ void GenerateIOSMain (StringWriter sw, Abi abi) var assembly_location_count = 0; var enable_llvm = (abi & Abi.LLVM) != 0; - register_assemblies.AppendLine ("\tGCHandle exception_gchandle = INVALID_GCHANDLE;"); - foreach (var s in assemblies) { - if (!s.IsAOTCompiled) - continue; + if (app.XamarinRuntime != XamarinRuntime.NativeAOT) { + register_assemblies.AppendLine ("\tGCHandle exception_gchandle = INVALID_GCHANDLE;"); + foreach (var s in assemblies) { + if (!s.IsAOTCompiled) + continue; - var info = s.AssemblyDefinition.Name.Name; - info = EncodeAotSymbol (info); - assembly_externs.Append ("extern void *mono_aot_module_").Append (info).AppendLine ("_info;"); - assembly_aot_modules.Append ("\tmono_aot_register_module (mono_aot_module_").Append (info).AppendLine ("_info);"); + var info = s.AssemblyDefinition.Name.Name; + info = EncodeAotSymbol (info); + assembly_externs.Append ("extern void *mono_aot_module_").Append (info).AppendLine ("_info;"); + assembly_aot_modules.Append ("\tmono_aot_register_module (mono_aot_module_").Append (info).AppendLine ("_info);"); - string sname = s.FileName; - if (assembly_name != sname && IsBoundAssembly (s)) { - register_assemblies.Append ("\txamarin_open_and_register (\"").Append (sname).Append ("\", &exception_gchandle);").AppendLine (); - register_assemblies.AppendLine ("\txamarin_process_managed_exception_gchandle (exception_gchandle);"); + string sname = s.FileName; + if (assembly_name != sname && IsBoundAssembly (s)) { + register_assemblies.Append ("\txamarin_open_and_register (\"").Append (sname).Append ("\", &exception_gchandle);").AppendLine (); + register_assemblies.AppendLine ("\txamarin_process_managed_exception_gchandle (exception_gchandle);"); + } } } @@ -797,6 +799,8 @@ void GenerateIOSMain (StringWriter sw, Abi abi) } else { sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_INTERP);"); } + } else if (app.XamarinRuntime == XamarinRuntime.NativeAOT) { + // don't call mono_jit_set_aot_mode } else if (app.IsDeviceBuild) { sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_FULL);"); } else if (app.Platform == ApplePlatform.MacCatalyst && ((abi & Abi.ARM64) == Abi.ARM64)) { @@ -852,7 +856,8 @@ void GenerateIOSMain (StringWriter sw, Abi abi) // Do this last, so that the app developer can override any other environment variable we set. foreach (var kvp in app.EnvironmentVariables) sw.WriteLine ("\tsetenv (\"{0}\", \"{1}\", 1);", kvp.Key.Replace ("\"", "\\\""), kvp.Value.Replace ("\"", "\\\"")); - sw.WriteLine ("\txamarin_supports_dynamic_registration = {0};", app.DynamicRegistrationSupported ? "TRUE" : "FALSE"); + if (app.XamarinRuntime != XamarinRuntime.NativeAOT) + sw.WriteLine ("\txamarin_supports_dynamic_registration = {0};", app.DynamicRegistrationSupported ? "TRUE" : "FALSE"); #if NET sw.WriteLine ("\txamarin_runtime_configuration_name = {0};", string.IsNullOrEmpty (app.RuntimeConfigurationFile) ? "NULL" : $"\"{app.RuntimeConfigurationFile}\""); #endif diff --git a/tools/common/XamarinRuntime.cs b/tools/common/XamarinRuntime.cs index af78ec9c2e78..ecab1567fe08 100644 --- a/tools/common/XamarinRuntime.cs +++ b/tools/common/XamarinRuntime.cs @@ -2,5 +2,6 @@ namespace Xamarin.Bundler { public enum XamarinRuntime { MonoVM, CoreCLR, + NativeAOT, } } diff --git a/tools/mtouch/Errors.designer.cs b/tools/mtouch/Errors.designer.cs index d770fa6bddc0..9c382bd3f3b8 100644 --- a/tools/mtouch/Errors.designer.cs +++ b/tools/mtouch/Errors.designer.cs @@ -3901,6 +3901,15 @@ public static string MX2005 { } } + /// + /// Looks up a localized string similar to Keeping the dynamic registrar (by passing '--optimize=-remove-dynamic-registrar') is not possible, because the dynamic registrar is not supported when using NativeAOT. Support for dynamic registration will still be removed.. + /// + public static string MX2016 { + get { + return ResourceManager.GetString("MX2016", resourceCulture); + } + } + /// /// Looks up a localized string similar to Could not process XML description: {0} /// . diff --git a/tools/mtouch/Errors.resx b/tools/mtouch/Errors.resx index 8ebe9f75b579..76e6fc7c5b1b 100644 --- a/tools/mtouch/Errors.resx +++ b/tools/mtouch/Errors.resx @@ -1190,6 +1190,10 @@ + + Keeping the dynamic registrar (by passing '--optimize=-remove-dynamic-registrar') is not possible, because the dynamic registrar is not supported when using NativeAOT. Support for dynamic registration will still be removed. + + Could not process XML description: {0}