From c0e6736d461f981b1a9333535768a7f02b29d577 Mon Sep 17 00:00:00 2001 From: VS MobileTools Engineering Service 2 Date: Wed, 28 Jul 2021 01:59:44 -0700 Subject: [PATCH] [release/6.0.1xx-preview7] [dotnet] Add support for the interpreter + AOT when needed. Fixes #11421 and #11724. (#12237) * [dotnet] Refactor and extend the logic to determine whether we should run the AOT compiler or not. We also can't link dynamically with libmonosgen-2.0.dylib if we AOT compile anything, so make sure we don't do that. * [runtime] AOT is no longer limited to device builds. * [runtime/tools] Implement finding native mono lib for Mac Catalyst. This also meant propagating how libmono is linked from the MSBuild code to the Application class so that our existing logic is able to correctly determine which native mono lib to use. * [tools] Implement interpreter + AOT compilation for simulator + Mac Catalyst. The interpreter requires running the AOT compiler for System.Private.CoreLib.dll, so the first step in implementing the interpreter is to implement support for the AOT compiler as well. For .NET the logic is now as follows: * If the interpreter is enabled, AOT compile System.Private.CoreLib.dll. * If the interpreter is disabled, AOT everything on device + Mac Catalyst on ARM64. * [tests] Add a MyInterpretedApp test solution * [dotnet] Parse --dlsym and pass it to the dotnet-linker tasks. * [dotnet] Only list linker flags for assemblies after we've computed them. This means not listing per-assembly linker flags for only binding projects, but delay it until we've computed the linker flags for all assemblies (and reflect this in variable names as well). * [dotnet-linker] Add native references to libSystem.Security.Cryptography.Native.Apple for Mac Catalyst. Fixes these test failures: Ctor_Trust: System.DllNotFoundException : libSystem.Security.Cryptography.Native.Apple MailX1: System.DllNotFoundException : libSystem.Security.Cryptography.Native.Apple Encrypt_Empty: System.DllNotFoundException : libSystem.Security.Cryptography.Native.Apple KeyRecordTest: System.DllNotFoundException : libSystem.Security.Cryptography.Native.Apple Basic_Leaf_Only: System.DllNotFoundException : libSystem.Security.Cryptography.Native.Apple which are all because of Xamarin.MacCatalyst: Unable to resolve P/Invoke 'AppleCryptoNative_X509GetContentType' in the library 'libSystem.Security.Cryptography.Native.Apple' which happens because without this change we're not linking with the static version of libSystem.Security.Cryptography.Native.Apple. * [monotouch-test] Fix some formatting and add assert messages * [tools] Disable direct-pinvoke for AOT-compiled code on Mac Catalyst. Using 'direct-pinvoke' will tell the AOT compiler to emit a direct call to the native function declared in the DllImport, which doesn't work when we want to redirect to a different native funcion (in our xamarin_pinvoke_override/PINVOKE_OVERRIDE implementation). This fixes our exception marshalling tests in monotouch-test. * [monotouch-test] Improve the MTLDeviceTest to work on Mac Catalyst. * [tools] Always use '__Internal' as the native library for .NET. This is not the final fix, but this code will be reworked extensively, and this fix works for now to make the interpreter work. * [monotouch-test] Ignore the MTLDeviceTest.ReturnReleaseTest on Mac Catalyst. It requires a backport of other test fixes (which we're not really interested in), so just ignore it. Co-authored-by: Rolf Bjarne Kvinge --- dotnet/targets/Xamarin.Shared.Sdk.targets | 26 ++++++-- .../Tasks/ParseBundlerArgumentsTaskBase.cs | 12 ++++ msbuild/Xamarin.Shared/Xamarin.Shared.targets | 1 + runtime/monotouch-main.m | 10 +--- runtime/monovm-bridge.m | 5 +- runtime/runtime.m | 18 ++++++ runtime/xamarin/main.h | 1 + runtime/xamarin/runtime.h | 2 - tests/dotnet/MyInterpretedApp/AppDelegate.cs | 4 +- .../MyInterpretedApp/Entitlements.plist | 6 -- tests/dotnet/MyInterpretedApp/Info.plist | 20 ------- .../MyInterpretedApp/MacCatalyst/Makefile | 1 + .../MacCatalyst/MyInterpretedApp.csproj | 8 +++ tests/dotnet/MyInterpretedApp/Main.cs | 13 +++- tests/dotnet/MyInterpretedApp/Makefile | 12 ++-- tests/dotnet/MyInterpretedApp/iOS/Makefile | 4 ++ .../{ => iOS}/MyInterpretedApp.csproj | 4 +- tests/dotnet/MyInterpretedApp/shared.csproj | 19 ++++++ tests/dotnet/MyInterpretedApp/shared.mk | 23 ++++++++ tests/dotnet/MyInterpretedApp/tvOS/Makefile | 1 + .../tvOS/MyInterpretedApp.csproj | 7 +++ tests/monotouch-test/Metal/MTLDeviceTests.cs | 27 +++++---- .../System.Net.Http/MessageHandlers.cs | 10 ++-- tools/common/Application.cs | 39 ++++++++++-- tools/common/Target.cs | 59 ++++++++++--------- tools/dotnet-linker/LinkerConfiguration.cs | 25 ++++++++ .../Steps/ComputeNativeBuildFlagsStep.cs | 17 ++++++ .../Steps/ExtractBindingLibrariesStep.cs | 17 ------ .../MonoTouch.Tuner/ListExportedSymbols.cs | 2 +- 29 files changed, 273 insertions(+), 120 deletions(-) delete mode 100644 tests/dotnet/MyInterpretedApp/Entitlements.plist create mode 100644 tests/dotnet/MyInterpretedApp/MacCatalyst/Makefile create mode 100644 tests/dotnet/MyInterpretedApp/MacCatalyst/MyInterpretedApp.csproj create mode 100644 tests/dotnet/MyInterpretedApp/iOS/Makefile rename tests/dotnet/MyInterpretedApp/{ => iOS}/MyInterpretedApp.csproj (54%) create mode 100644 tests/dotnet/MyInterpretedApp/shared.csproj create mode 100644 tests/dotnet/MyInterpretedApp/shared.mk create mode 100644 tests/dotnet/MyInterpretedApp/tvOS/Makefile create mode 100644 tests/dotnet/MyInterpretedApp/tvOS/MyInterpretedApp.csproj diff --git a/dotnet/targets/Xamarin.Shared.Sdk.targets b/dotnet/targets/Xamarin.Shared.Sdk.targets index 1d380c933585..93d4eb128d80 100644 --- a/dotnet/targets/Xamarin.Shared.Sdk.targets +++ b/dotnet/targets/Xamarin.Shared.Sdk.targets @@ -360,6 +360,7 @@ AOTCompiler=$(_AOTCompiler) AOTOutputDirectory=$(_AOTOutputDirectory) CacheDirectory=$(_LinkerCacheDirectory) + @(_BundlerDlsym -> 'Dlsym=%(Identity)') Debug=$(_BundlerDebug) DeploymentTarget=$(_MinimumOSVersion) @(_BundlerEnvironmentVariables -> 'EnvironmentVariable=%(Identity)=%(Value)') @@ -370,6 +371,8 @@ InvariantGlobalization=$(InvariantGlobalization) ItemsDirectory=$(_LinkerItemsDirectory) IsSimulatorBuild=$(_SdkIsSimulator) + LibMonoLinkMode=$(_LibMonoLinkMode) + LibXamarinLinkMode=$(_LibXamarinLinkMode) LinkMode=$(_LinkMode) MarshalManagedExceptionMode=$(_MarshalManagedExceptionMode) MarshalObjectiveCExceptionMode=$(_MarshalObjectiveCExceptionMode) @@ -557,9 +560,9 @@ - - - + + + @@ -630,6 +633,17 @@ + + + <_RunAotCompiler>false + + <_RunAotCompiler Condition="'$(_SdkIsSimulator)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst'">true + + <_RunAotCompiler Condition="'$(MtouchInterpreter)' != ''">true + + <_RunAotCompiler Condition="'$(RuntimeIdentifier)' == 'maccatalyst-arm64'">true + + <_IntermediateNativeLibraryDir>$(IntermediateOutputPath)nativelibraries/ <_NativeExecutableName>$(_AppBundleName) @@ -642,11 +656,13 @@ <_AOTInputDirectory>$(_IntermediateNativeLibraryDir)aot-input/ <_AOTOutputDirectory>$(_IntermediateNativeLibraryDir)aot-output/ + <_LibMonoLinkMode Condition="'$(_LibMonoLinkMode)' == '' And '$(_RunAotCompiler)' == 'true'">static <_LibMonoLinkMode Condition="'$(_LibMonoLinkMode)' == '' And ('$(ComputedPlatform)' != 'iPhone' Or '$(_PlatformName)' == 'macOS')">dylib <_LibMonoLinkMode Condition="'$(_LibMonoLinkMode)' == ''">static <_LibMonoExtension Condition="'$(_LibMonoLinkMode)' == 'dylib'">dylib <_LibMonoExtension Condition="'$(_LibMonoLinkMode)' == 'static'">a + <_LibXamarinLinkMode Condition="'$(_LibXamarinLinkMode)' == '' And '$(_RunAotCompiler)' == 'true'">static <_LibXamarinLinkMode Condition="'$(_LibXamarinLinkMode)' == '' And '$(ComputedPlatform)' != 'iPhone' And '$(_PlatformName)' != 'macOS'">dylib <_LibXamarinLinkMode Condition="'$(_LibXamarinLinkMode)' == ''">static <_LibXamarinExtension Condition="'$(_LibXamarinLinkMode)' == 'dylib'">dylib @@ -702,7 +718,7 @@ @@ -836,7 +852,7 @@ EntitlementsInExecutable="$(_CompiledEntitlements)" FrameworkRPath="$(_EmbeddedFrameworksRPath)" Frameworks="@(_NativeExecutableFrameworks);@(_BindingLibraryFrameworks)" - LinkerFlags="@(_BindingLibraryLinkerFlags);@(_ReferencesLinkerFlags);@(_MainLinkerFlags)" + LinkerFlags="@(_AssemblyLinkerFlags);@(_ReferencesLinkerFlags);@(_MainLinkerFlags)" LinkWithLibraries="@(_XamarinMainLibraries);@(_BindingLibraryLinkWith);@(_MainLinkWith)" MinimumOSVersion="$(_MinimumOSVersion)" NativeReferences="@(_FileNativeReference);@(_FrameworkNativeReference)" diff --git a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ParseBundlerArgumentsTaskBase.cs b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ParseBundlerArgumentsTaskBase.cs index bbd6bd9cb2d7..74b666cd6505 100644 --- a/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ParseBundlerArgumentsTaskBase.cs +++ b/msbuild/Xamarin.MacDev.Tasks.Core/Tasks/ParseBundlerArgumentsTaskBase.cs @@ -7,6 +7,9 @@ namespace Xamarin.MacDev.Tasks { public abstract class ParseBundlerArgumentsTaskBase : XamarinTask { public string ExtraArgs { get; set; } + [Output] + public ITaskItem [] DlSym { get; set; } + [Output] public ITaskItem[] EnvironmentVariables { get; set; } @@ -49,6 +52,7 @@ public override bool Execute () var args = CommandLineArgumentBuilder.Parse (ExtraArgs); List xml = null; var envVariables = new List (); + var dlsyms = new List (); for (int i = 0; i < args.Length; i++) { var arg = args [i]; @@ -84,6 +88,9 @@ public override bool Execute () // do not set the MtouchNoSymbolStrip property to 'true' in that case. NoSymbolStrip = string.IsNullOrEmpty (value) ? "true" : "false"; break; + case "dlsym": + dlsyms.Add (new TaskItem (string.IsNullOrEmpty (value) ? "true" : value)); + break; case "dsym": NoDSymUtil = ParseBool (value) ? "false" : "true"; break; @@ -143,6 +150,11 @@ public override bool Execute () EnvironmentVariables = envVariables.ToArray (); } + if (dlsyms.Count > 0) { + if (DlSym != null) + dlsyms.AddRange (DlSym); + DlSym = dlsyms.ToArray (); + } } return !Log.HasLoggedErrors; diff --git a/msbuild/Xamarin.Shared/Xamarin.Shared.targets b/msbuild/Xamarin.Shared/Xamarin.Shared.targets index 2c3b8dea923b..70993a846784 100644 --- a/msbuild/Xamarin.Shared/Xamarin.Shared.targets +++ b/msbuild/Xamarin.Shared/Xamarin.Shared.targets @@ -1016,6 +1016,7 @@ Copyright (C) 2018 Microsoft. All rights reserved. NoDSymUtil="$(_NoDSymUtil)" > + diff --git a/runtime/monotouch-main.m b/runtime/monotouch-main.m index e10bb7d0f842..0475b4a005e2 100644 --- a/runtime/monotouch-main.m +++ b/runtime/monotouch-main.m @@ -426,12 +426,9 @@ - (void) memoryWarning: (NSNotification *) sender xamarin_initialize (); DEBUG_LAUNCH_TIME_PRINT ("\tmonotouch init time"); -#if defined (__arm__) || defined(__aarch64__) - xamarin_register_assemblies (); - assembly = xamarin_open_and_register (xamarin_executable_name, &exception_gchandle); - if (exception_gchandle != NULL) - xamarin_process_managed_exception_gchandle (exception_gchandle); -#else + if (xamarin_register_assemblies != NULL) + xamarin_register_assemblies (); + if (xamarin_executable_name) { assembly = xamarin_open_and_register (xamarin_executable_name, &exception_gchandle); if (exception_gchandle != NULL) @@ -455,7 +452,6 @@ - (void) memoryWarning: (NSNotification *) sender if (exception_gchandle != NULL) xamarin_process_managed_exception_gchandle (exception_gchandle); } -#endif DEBUG_LAUNCH_TIME_PRINT ("\tAssembly register time"); diff --git a/runtime/monovm-bridge.m b/runtime/monovm-bridge.m index 40e8adaf4b68..7fdce3cae2d6 100644 --- a/runtime/monovm-bridge.m +++ b/runtime/monovm-bridge.m @@ -57,9 +57,8 @@ void xamarin_bridge_initialize () { -#if defined (__arm__) || defined(__aarch64__) - xamarin_register_modules (); -#endif + if (xamarin_register_modules != NULL) + xamarin_register_modules (); DEBUG_LAUNCH_TIME_PRINT ("\tAOT register time"); #ifdef DEBUG diff --git a/runtime/runtime.m b/runtime/runtime.m index ccbd684b8fa7..c81141413e8d 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -83,6 +83,7 @@ enum XamarinLaunchMode xamarin_launch_mode = XamarinLaunchModeApp; bool xamarin_supports_dynamic_registration = true; const char *xamarin_runtime_configuration_name = NULL; +const char *xamarin_mono_native_lib_name = "__Internal"; /* Callbacks */ @@ -2441,8 +2442,25 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; void* symbol = NULL; +#if TARGET_OS_MACCATALYST + static void *monoNativeLibrary = NULL; +#endif + if (!strcmp (libraryName, "__Internal")) { symbol = dlsym (RTLD_DEFAULT, entrypointName); +#if TARGET_OS_MACCATALYST + } else if (!strcmp (libraryName, "libSystem.Native") || + !strcmp (libraryName, "libSystem.Security.Cryptography.Native.Apple") || + !strcmp (libraryName, "libSystem.Net.Security.Native")) { + if (monoNativeLibrary == NULL) { + if (xamarin_mono_native_lib_name == NULL || !strcmp (xamarin_mono_native_lib_name, "__Internal")) { + monoNativeLibrary = RTLD_DEFAULT; + } else { + monoNativeLibrary = dlopen (xamarin_mono_native_lib_name, RTLD_LAZY); + } + } + symbol = dlsym (monoNativeLibrary, entrypointName); +#endif // TARGET_OS_MACCATALYST #if !defined (CORECLR_RUNTIME) // we're intercepting objc_msgSend calls using the managed System.Runtime.InteropServices.ObjectiveC.Bridge.SetMessageSendCallback instead. #if defined (__i386__) || defined (__x86_64__) || defined (__arm64__) } else if (!strcmp (libraryName, "/usr/lib/libobjc.dylib")) { diff --git a/runtime/xamarin/main.h b/runtime/xamarin/main.h index bf175a54b887..bf07699f6596 100644 --- a/runtime/xamarin/main.h +++ b/runtime/xamarin/main.h @@ -109,6 +109,7 @@ extern enum MarshalManagedExceptionMode xamarin_marshal_managed_exception_mode; extern enum XamarinLaunchMode xamarin_launch_mode; extern bool xamarin_supports_dynamic_registration; extern const char *xamarin_runtime_configuration_name; +extern const char *xamarin_mono_native_lib_name; typedef void (*xamarin_setup_callback) (); typedef int (*xamarin_extension_main_callback) (int argc, char** argv); diff --git a/runtime/xamarin/runtime.h b/runtime/xamarin/runtime.h index 86c702f5bcf0..24daad097a6e 100644 --- a/runtime/xamarin/runtime.h +++ b/runtime/xamarin/runtime.h @@ -328,9 +328,7 @@ void xamarin_mono_object_release_at_process_exit (MonoObject *mobj); */ MonoAssembly * xamarin_open_assembly (const char *name); -#if defined(__arm__) || defined(__aarch64__) void mono_aot_register_module (void *aot_info); -#endif typedef void (*xamarin_register_module_callback) (); typedef void (*xamarin_register_assemblies_callback) (); diff --git a/tests/dotnet/MyInterpretedApp/AppDelegate.cs b/tests/dotnet/MyInterpretedApp/AppDelegate.cs index d7121c6f6036..c4477acb4ea5 100644 --- a/tests/dotnet/MyInterpretedApp/AppDelegate.cs +++ b/tests/dotnet/MyInterpretedApp/AppDelegate.cs @@ -3,7 +3,7 @@ using Foundation; using UIKit; -namespace MySingleView +namespace MyInterpretedApp { public partial class AppDelegate : UIApplicationDelegate { @@ -15,7 +15,7 @@ public override bool FinishedLaunching (UIApplication app, NSDictionary options) var dvc = new UIViewController (); var button = new UIButton (window.Bounds); - button.SetTitle ("net6!", UIControlState.Normal); + button.SetTitle ($"Execution mode: {Application.GetExecutionMode ()}", UIControlState.Normal); dvc.Add (button); window.RootViewController = dvc; diff --git a/tests/dotnet/MyInterpretedApp/Entitlements.plist b/tests/dotnet/MyInterpretedApp/Entitlements.plist deleted file mode 100644 index 5ea1ec76e117..000000000000 --- a/tests/dotnet/MyInterpretedApp/Entitlements.plist +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tests/dotnet/MyInterpretedApp/Info.plist b/tests/dotnet/MyInterpretedApp/Info.plist index 68032597c947..6631ffa6f242 100644 --- a/tests/dotnet/MyInterpretedApp/Info.plist +++ b/tests/dotnet/MyInterpretedApp/Info.plist @@ -2,25 +2,5 @@ - UIDeviceFamily - - 1 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - MinimumOSVersion - 10.0 - CFBundleDisplayName - ApplicationName - CFBundleIdentifier - com.xamarin.mysingleview - XSAppIconAssets - Resources/Images.xcassets/AppIcons.appiconset - XSLaunchImageAssets - Resources/Images.xcassets/LaunchImage.launchimage diff --git a/tests/dotnet/MyInterpretedApp/MacCatalyst/Makefile b/tests/dotnet/MyInterpretedApp/MacCatalyst/Makefile new file mode 100644 index 000000000000..110d078f4577 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/MacCatalyst/Makefile @@ -0,0 +1 @@ +include ../shared.mk diff --git a/tests/dotnet/MyInterpretedApp/MacCatalyst/MyInterpretedApp.csproj b/tests/dotnet/MyInterpretedApp/MacCatalyst/MyInterpretedApp.csproj new file mode 100644 index 000000000000..8e66a9f43850 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/MacCatalyst/MyInterpretedApp.csproj @@ -0,0 +1,8 @@ + + + + net6.0-maccatalyst + maccatalyst-arm64 + + + diff --git a/tests/dotnet/MyInterpretedApp/Main.cs b/tests/dotnet/MyInterpretedApp/Main.cs index 198707897413..326f775d06db 100644 --- a/tests/dotnet/MyInterpretedApp/Main.cs +++ b/tests/dotnet/MyInterpretedApp/Main.cs @@ -1,15 +1,26 @@ using System; +using System.Runtime.CompilerServices; using Foundation; using UIKit; -namespace MySingleView +namespace MyInterpretedApp { public class Application { static void Main (string[] args) { + Console.WriteLine ($"Execution mode: {GetExecutionMode ()}"); UIApplication.Main (args, null, typeof (AppDelegate)); } + + public static string GetExecutionMode() + { + if (!RuntimeFeature.IsDynamicCodeSupported) + return "AOT"; + if (RuntimeFeature.IsDynamicCodeCompiled) + return "JIT"; + return "Interpreter"; + } } } diff --git a/tests/dotnet/MyInterpretedApp/Makefile b/tests/dotnet/MyInterpretedApp/Makefile index e385064ec09e..84377bb70450 100644 --- a/tests/dotnet/MyInterpretedApp/Makefile +++ b/tests/dotnet/MyInterpretedApp/Makefile @@ -2,8 +2,12 @@ TOP=../../.. include $(TOP)/Make.config -build: - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) +%-ios: + $(MAKE) -C iOS $@ + +%-tvos: + $(MAKE) -C tvOS $@ + +%-maccatalyst %-maccat: + $(MAKE) -C MacCatalyst $@ -run: - $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) -t:Run diff --git a/tests/dotnet/MyInterpretedApp/iOS/Makefile b/tests/dotnet/MyInterpretedApp/iOS/Makefile new file mode 100644 index 000000000000..f1a4290889e9 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/iOS/Makefile @@ -0,0 +1,4 @@ +include ../shared.mk + +dev: + $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) /p:RuntimeIdentifier=ios-arm64 diff --git a/tests/dotnet/MyInterpretedApp/MyInterpretedApp.csproj b/tests/dotnet/MyInterpretedApp/iOS/MyInterpretedApp.csproj similarity index 54% rename from tests/dotnet/MyInterpretedApp/MyInterpretedApp.csproj rename to tests/dotnet/MyInterpretedApp/iOS/MyInterpretedApp.csproj index b1e5256cc14d..79efbc425b52 100644 --- a/tests/dotnet/MyInterpretedApp/MyInterpretedApp.csproj +++ b/tests/dotnet/MyInterpretedApp/iOS/MyInterpretedApp.csproj @@ -2,8 +2,6 @@ net6.0-ios - iossimulator-x64 - Exe - all + diff --git a/tests/dotnet/MyInterpretedApp/shared.csproj b/tests/dotnet/MyInterpretedApp/shared.csproj new file mode 100644 index 000000000000..9048b403f527 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/shared.csproj @@ -0,0 +1,19 @@ + + + + Exe + true + true + + MyInterpretedApp + com.xamarin.myinterpretedapp + 1.0 + + + + + + Info.plist + + + diff --git a/tests/dotnet/MyInterpretedApp/shared.mk b/tests/dotnet/MyInterpretedApp/shared.mk new file mode 100644 index 000000000000..b1be5cd7a8ad --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/shared.mk @@ -0,0 +1,23 @@ +TOP=../../../.. +include $(TOP)/Make.config + +reload: + rm -Rf $(TOP)/tests/dotnet/packages + $(MAKE) -C $(TOP) -j8 all + $(MAKE) -C $(TOP) -j8 install + git clean -xfdq + +reload-and-build: reload + $(MAKE) build + +reload-and-run: reload + $(MAKE) run + +build: + $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) + +run: + $(DOTNET6) build /bl *.csproj $(MSBUILD_VERBOSITY) -t:Run + +diag: + $(DOTNET6) build /v:diag msbuild.binlog diff --git a/tests/dotnet/MyInterpretedApp/tvOS/Makefile b/tests/dotnet/MyInterpretedApp/tvOS/Makefile new file mode 100644 index 000000000000..110d078f4577 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/tvOS/Makefile @@ -0,0 +1 @@ +include ../shared.mk diff --git a/tests/dotnet/MyInterpretedApp/tvOS/MyInterpretedApp.csproj b/tests/dotnet/MyInterpretedApp/tvOS/MyInterpretedApp.csproj new file mode 100644 index 000000000000..efe9e8970530 --- /dev/null +++ b/tests/dotnet/MyInterpretedApp/tvOS/MyInterpretedApp.csproj @@ -0,0 +1,7 @@ + + + + net6.0-tvos + + + diff --git a/tests/monotouch-test/Metal/MTLDeviceTests.cs b/tests/monotouch-test/Metal/MTLDeviceTests.cs index 0edb6b541d65..cea5c95a7591 100644 --- a/tests/monotouch-test/Metal/MTLDeviceTests.cs +++ b/tests/monotouch-test/Metal/MTLDeviceTests.cs @@ -63,6 +63,9 @@ static void FreePageAligned (IntPtr ptr, int length) } [Test] +#if __MACCATALYST__ + [Ignore ("This test requires a few test fixes that hasn't been backported to the release/6.0.1xx-preview7 branch - and won't be, since they're not necessary.")] +#endif public void ReturnReleaseTest () { // This test tries to exercise all the Metal API that has a @@ -97,7 +100,7 @@ public void ReturnReleaseTest () string metallib_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "default.metallib"); string fragmentshader_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "fragmentShader.metallib"); -#if !__MACOS__ +#if !__MACOS__ && !__MACCATALYST__ if (Runtime.Arch == Arch.SIMULATOR) Assert.Ignore ("Metal isn't available in the simulator"); #endif @@ -339,14 +342,16 @@ public void ReturnReleaseTest () } } - using (var library = device.CreateLibrary (fragmentshader_path, out var error)) - using (var func = library.CreateFunction ("fragmentShader2")) { - using (var enc = func.CreateArgumentEncoder (0)) { - Assert.IsNotNull (enc, "MTLFunction.CreateArgumentEncoder (nuint): NonNull"); - } - using (var enc = func.CreateArgumentEncoder (0, out var reflection)) { - Assert.IsNotNull (enc, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull"); - Assert.IsNotNull (reflection, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull reflection"); + using (var library = device.CreateLibrary (fragmentshader_path, out var error)) { + Assert.IsNull (error, "MTLFunction.CreateArgumentEncoder: library creation failure"); + using (var func = library.CreateFunction ("fragmentShader2")) { + using (var enc = func.CreateArgumentEncoder (0)) { + Assert.IsNotNull (enc, "MTLFunction.CreateArgumentEncoder (nuint): NonNull"); + } + using (var enc = func.CreateArgumentEncoder (0, out var reflection)) { + Assert.IsNotNull (enc, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull"); + Assert.IsNotNull (reflection, "MTLFunction.CreateArgumentEncoder (nuint, MTLArgument): NonNull reflection"); + } } } @@ -378,7 +383,7 @@ public void ReturnReleaseTest () using (var hd = new MTLHeapDescriptor ()) { hd.CpuCacheMode = MTLCpuCacheMode.DefaultCache; -#if __MACOS__ +#if __MACOS__ || __MACCATALYST__ hd.StorageMode = MTLStorageMode.Private; #else hd.StorageMode = MTLStorageMode.Shared; @@ -388,7 +393,7 @@ public void ReturnReleaseTest () hd.Size = sa.Size; using (var heap = device.CreateHeap (hd)) { -#if __MACOS__ +#if __MACOS__ || __MACCATALYST__ txt.StorageMode = MTLStorageMode.Private; #endif using (var texture = heap.CreateTexture (txt)) { diff --git a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs index c3f0f891990e..3bc836cd1f5d 100644 --- a/tests/monotouch-test/System.Net.Http/MessageHandlers.cs +++ b/tests/monotouch-test/System.Net.Http/MessageHandlers.cs @@ -426,13 +426,13 @@ public void RejectSslCertificatesServicePointManager (Type handlerType) Assert.Inconclusive ("Request timedout."); } else { // the ServicePointManager.ServerCertificateValidationCallback will never be executed. - Assert.False(invalidServicePointManagerCbWasExcuted); - Assert.True(validationCbWasExecuted); + Assert.False (invalidServicePointManagerCbWasExcuted, "Invalid SPM executed"); + Assert.True (validationCbWasExecuted, "Validation Callback called"); // assert the exception type Assert.IsNotNull (ex, (result == null)? "Expected exception is missing and got no result" : $"Expected exception but got {result.Content.ReadAsStringAsync ().Result}"); - Assert.IsInstanceOf (typeof (HttpRequestException), ex); - Assert.IsNotNull (ex.InnerException); - Assert.IsInstanceOf (expectedExceptionType, ex.InnerException); + Assert.IsInstanceOf (typeof (HttpRequestException), ex, "Exception type"); + Assert.IsNotNull (ex.InnerException, "InnerException"); + Assert.IsInstanceOf (expectedExceptionType, ex.InnerException, "InnerException type"); } } diff --git a/tools/common/Application.cs b/tools/common/Application.cs index dd83b7993c27..d7e6e967e7ec 100644 --- a/tools/common/Application.cs +++ b/tools/common/Application.cs @@ -182,8 +182,12 @@ public string FrameworksDirectory { } // How Mono should be embedded into the app. + AssemblyBuildTarget? libmono_link_mode; public AssemblyBuildTarget LibMonoLinkMode { get { + if (libmono_link_mode.HasValue) + return libmono_link_mode.Value; + if (Platform == ApplePlatform.MacOSX) { // This property was implemented for iOS, but might be re-used for macOS if desired after testing to verify it works as expected. throw ErrorHelper.CreateError (99, Errors.MX0099, "LibMonoLinkMode isn't a valid operation for macOS apps."); @@ -199,11 +203,18 @@ public AssemblyBuildTarget LibMonoLinkMode { return AssemblyBuildTarget.StaticObject; } } + set { + libmono_link_mode = value; + } } // How libxamarin should be embedded into the app. + AssemblyBuildTarget? libxamarin_link_mode; public AssemblyBuildTarget LibXamarinLinkMode { get { + if (libxamarin_link_mode.HasValue) + return libxamarin_link_mode.Value; + if (Platform == ApplePlatform.MacOSX) { // This property was implemented for iOS, but might be re-used for macOS if desired after testing to verify it works as expected. throw ErrorHelper.CreateError (99, Errors.MX0099, "LibXamarinLinkMode isn't a valid operation for macOS apps."); @@ -219,14 +230,25 @@ public AssemblyBuildTarget LibXamarinLinkMode { return AssemblyBuildTarget.StaticObject; } } + set { + libxamarin_link_mode = value; + } } // How the generated libpinvoke library should be linked into the app. public AssemblyBuildTarget LibPInvokesLinkMode => LibXamarinLinkMode; // How the profiler library should be linked into the app. public AssemblyBuildTarget LibProfilerLinkMode => OnlyStaticLibraries ? AssemblyBuildTarget.StaticObject : AssemblyBuildTarget.DynamicLibrary; + // How the libmononative library should be linked into the app. - public AssemblyBuildTarget LibMonoNativeLinkMode => HasDynamicLibraries ? AssemblyBuildTarget.DynamicLibrary : AssemblyBuildTarget.StaticObject; + public AssemblyBuildTarget LibMonoNativeLinkMode { + get { + // if there's a specific way libmono is being linked, use the same way. + if (libmono_link_mode.HasValue) + return libmono_link_mode.Value; + return HasDynamicLibraries ? AssemblyBuildTarget.DynamicLibrary: AssemblyBuildTarget.StaticObject; + } + } // If all assemblies are compiled into static libraries. public bool OnlyStaticLibraries { @@ -1350,8 +1372,10 @@ public bool IsInterpreted (string assembly) if (Platform == ApplePlatform.MacOSX) throw ErrorHelper.CreateError (99, Errors.MX0099, "IsInterpreted isn't a valid operation for macOS apps."); +#if !NET if (IsSimulatorBuild) return false; +#endif // IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both. if (!UseInterpreter) @@ -1381,15 +1405,18 @@ public bool IsInterpreted (string assembly) public bool IsAOTCompiled (string assembly) { #if NET - if (Platform == ApplePlatform.MacOSX || Platform == ApplePlatform.MacCatalyst) + if (Platform == ApplePlatform.MacOSX) return false; // AOT on .NET for macOS hasn't been implemented yet. #else if (Platform == ApplePlatform.MacOSX) throw ErrorHelper.CreateError (99, Errors.MX0099, "IsAOTCompiled isn't a valid operation for macOS apps."); #endif + if (!UseInterpreter) { + if (Platform == ApplePlatform.MacCatalyst) + return IsArchEnabled (Abi.ARM64); - if (!UseInterpreter) - return true; + return IsDeviceBuild; + } // IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both: // - mscorlib will always be processed by the AOT compiler to generate required wrapper functions for the interpreter to work @@ -1593,8 +1620,10 @@ public bool UseDlsym (string assembly) return !Profile.IsSdkAssembly (Path.GetFileNameWithoutExtension (assembly)); case ApplePlatform.TVOS: case ApplePlatform.WatchOS: - case ApplePlatform.MacCatalyst: return false; + case ApplePlatform.MacCatalyst: + // We can't emit a direct call to the P/Invoke with the AOT compiler: https://github.com/dotnet/runtime/issues/55733 + return IsAOTCompiled (assembly); default: throw ErrorHelper.CreateError (71, Errors.MX0071, Platform, ProductName); } diff --git a/tools/common/Target.cs b/tools/common/Target.cs index e41680b46fb0..abc38ab55fcb 100644 --- a/tools/common/Target.cs +++ b/tools/common/Target.cs @@ -668,12 +668,12 @@ void GenerateIOSMain (StringWriter sw, Abi abi) foreach (var s in assemblies) { if (!s.IsAOTCompiled) continue; - if ((abi & Abi.SimulatorArchMask) == 0) { - 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 (); @@ -681,22 +681,20 @@ void GenerateIOSMain (StringWriter sw, Abi abi) } } - if ((abi & Abi.SimulatorArchMask) == 0 || app.Embeddinator) { - var frameworks = assemblies.Where ((a) => a.BuildTarget == AssemblyBuildTarget.Framework) - .OrderBy ((a) => a.Identity, StringComparer.Ordinal); - foreach (var asm_fw in frameworks) { - var asm_name = asm_fw.Identity; - if (asm_fw.BuildTargetName == asm_name) - continue; // this is deduceable - var prefix = string.Empty; - if (!app.HasFrameworksDirectory && asm_fw.IsCodeShared) - prefix = "../../"; - var suffix = string.Empty; - if (app.IsSimulatorBuild) - suffix = "/simulator"; - assembly_location.AppendFormat ("\t{{ \"{0}\", \"{2}Frameworks/{1}.framework/MonoBundle{3}\" }},\n", asm_name, asm_fw.BuildTargetName, prefix, suffix); - assembly_location_count++; - } + var frameworks = assemblies.Where ((a) => a.BuildTarget == AssemblyBuildTarget.Framework) + .OrderBy ((a) => a.Identity, StringComparer.Ordinal); + foreach (var asm_fw in frameworks) { + var asm_name = asm_fw.Identity; + if (asm_fw.BuildTargetName == asm_name) + continue; // this is deduceable + var prefix = string.Empty; + if (!app.HasFrameworksDirectory && asm_fw.IsCodeShared) + prefix = "../../"; + var suffix = string.Empty; + if (app.IsSimulatorBuild) + suffix = "/simulator"; + assembly_location.AppendFormat ("\t{{ \"{0}\", \"{2}Frameworks/{1}.framework/MonoBundle{3}\" }},\n", asm_name, asm_fw.BuildTargetName, prefix, suffix); + assembly_location_count++; } sw.WriteLine ("#include \"xamarin/xamarin.h\""); @@ -762,8 +760,11 @@ void GenerateIOSMain (StringWriter sw, Abi abi) sw.WriteLine ("\tmono_ee_interp_init (NULL);"); #endif sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_INTERP);"); - } else if (app.IsDeviceBuild) + } 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)) { + sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_FULL);"); + } if (assembly_location.Length > 0) sw.WriteLine ("\txamarin_set_assembly_directories (&assembly_locations);"); @@ -779,12 +780,12 @@ void GenerateIOSMain (StringWriter sw, Abi abi) #else var addDllMap = true; #endif + string mono_native_lib; + if (app.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject || Driver.IsDotNet) + mono_native_lib = "__Internal"; + else + mono_native_lib = app.GetLibNativeName () + ".dylib"; if (addDllMap) { - string mono_native_lib; - if (app.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject) - mono_native_lib = "__Internal"; - else - mono_native_lib = app.GetLibNativeName () + ".dylib"; sw.WriteLine (); #if NET sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"libSystem.Native\", NULL, \"{mono_native_lib}\", NULL);"); @@ -796,6 +797,8 @@ void GenerateIOSMain (StringWriter sw, Abi abi) sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Net.Security.Native\", NULL, \"{mono_native_lib}\", NULL);"); #endif sw.WriteLine (); + } else { + sw.WriteLine ($"\txamarin_mono_native_lib_name = \"{mono_native_lib}\";"); } } diff --git a/tools/dotnet-linker/LinkerConfiguration.cs b/tools/dotnet-linker/LinkerConfiguration.cs index 10088548622b..f12e19d6e837 100644 --- a/tools/dotnet-linker/LinkerConfiguration.cs +++ b/tools/dotnet-linker/LinkerConfiguration.cs @@ -16,6 +16,8 @@ namespace Xamarin.Linker { public class LinkerConfiguration { + string LinkerFile; + public List Abis; public string AOTCompiler; public string AOTOutputDirectory; @@ -74,6 +76,8 @@ public static LinkerConfiguration GetInstance (LinkContext context, bool createI if (!File.Exists (linker_file)) throw new FileNotFoundException ($"The custom linker file {linker_file} does not exist."); + LinkerFile = linker_file; + Profile = new BaseProfile (this); DerivedLinkContext = new DerivedLinkContext { LinkerConfiguration = this, }; Application = new Application (this); @@ -122,6 +126,9 @@ public static LinkerConfiguration GetInstance (LinkContext context, bool createI throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}"); DeploymentTarget = deployment_target; break; + case "Dlsym": + Application.ParseDlsymOptions (value); + break; case "EnvironmentVariable": var separators = new char [] { ':', '=' }; var equals = value.IndexOfAny (separators); @@ -145,6 +152,12 @@ public static LinkerConfiguration GetInstance (LinkContext context, bool createI case "IsSimulatorBuild": IsSimulatorBuild = string.Equals ("true", value, StringComparison.OrdinalIgnoreCase); break; + case "LibMonoLinkMode": + Application.LibMonoLinkMode = ParseLinkMode (value, key); + break; + case "LibXamarinLinkMode": + Application.LibXamarinLinkMode = ParseLinkMode (value, key); + break; case "LinkMode": if (!Enum.TryParse (value, true, out var lm)) throw new InvalidOperationException ($"Unable to parse the {key} value: {value} in {linker_file}"); @@ -298,6 +311,17 @@ public static LinkerConfiguration GetInstance (LinkContext context, bool createI Application.Initialize (); } + AssemblyBuildTarget ParseLinkMode (string value, string variableName) + { + if (string.Equals (value, "dylib", StringComparison.OrdinalIgnoreCase)) { + return AssemblyBuildTarget.DynamicLibrary; + } else if (string.Equals (value, "static", StringComparison.OrdinalIgnoreCase)) { + return AssemblyBuildTarget.StaticObject; + } + + throw new InvalidOperationException ($"Invalid {variableName} '{value}' in {LinkerFile}"); + } + public void Write () { if (Verbosity > 0) { @@ -307,6 +331,7 @@ public void Write () Console.WriteLine ($" AssemblyName: {Application.AssemblyName}"); Console.WriteLine ($" CacheDirectory: {CacheDirectory}"); Console.WriteLine ($" Debug: {Application.EnableDebug}"); + Console.WriteLine ($" Dlsym: {Application.DlsymOptions} {(Application.DlsymAssemblies != null ? string.Join (" ", Application.DlsymAssemblies.Select (v => (v.Item2 ? "+" : "-") + v.Item1)) : string.Empty)}"); Console.WriteLine ($" DeploymentTarget: {DeploymentTarget}"); Console.WriteLine ($" IntermediateLinkDir: {IntermediateLinkDir}"); Console.WriteLine ($" InterpretedAssemblies: {string.Join (", ", Application.InterpretedAssemblies)}"); diff --git a/tools/dotnet-linker/Steps/ComputeNativeBuildFlagsStep.cs b/tools/dotnet-linker/Steps/ComputeNativeBuildFlagsStep.cs index bec18ab4af30..9aa1e1920472 100644 --- a/tools/dotnet-linker/Steps/ComputeNativeBuildFlagsStep.cs +++ b/tools/dotnet-linker/Steps/ComputeNativeBuildFlagsStep.cs @@ -27,6 +27,23 @@ protected override void TryEndProcess () } Configuration.WriteOutputForMSBuild ("_LinkerFrameworks", linkerFrameworks); + + // Tell MSBuild about any additional linker flags we found + var linkerFlags = new List (); + foreach (var asm in Configuration.Target.Assemblies) { + if (asm.LinkerFlags == null) + continue; + foreach (var arg in asm.LinkerFlags) { + var item = new MSBuildItem { + Include = arg, + Metadata = new Dictionary { + { "Assembly", asm.Identity }, + }, + }; + linkerFlags.Add (item); + } + } + Configuration.WriteOutputForMSBuild ("_AssemblyLinkerFlags", linkerFlags); } } } diff --git a/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs b/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs index 709efaeab633..044226f61b57 100644 --- a/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs +++ b/tools/dotnet-linker/Steps/ExtractBindingLibrariesStep.cs @@ -55,23 +55,6 @@ protected override void TryEndProcess () } } Configuration.WriteOutputForMSBuild ("_BindingLibraryFrameworks", frameworks); - - // Tell MSBuild about any additional linker flags we found - var linkerFlags = new List (); - foreach (var asm in Configuration.Target.Assemblies) { - if (asm.LinkerFlags == null) - continue; - foreach (var arg in asm.LinkerFlags) { - var item = new MSBuildItem { - Include = arg, - Metadata = new Dictionary { - { "Assembly", asm.Identity }, - }, - }; - linkerFlags.Add (item); - } - } - Configuration.WriteOutputForMSBuild ("_BindingLibraryLinkerFlags", linkerFlags); } } } diff --git a/tools/linker/MonoTouch.Tuner/ListExportedSymbols.cs b/tools/linker/MonoTouch.Tuner/ListExportedSymbols.cs index 105afae92bd6..d01071a85c49 100644 --- a/tools/linker/MonoTouch.Tuner/ListExportedSymbols.cs +++ b/tools/linker/MonoTouch.Tuner/ListExportedSymbols.cs @@ -146,7 +146,7 @@ void ProcessMethod (MethodDefinition method) case "System.Security.Cryptography.Native.Apple": #if NET // https://github.com/dotnet/runtime/issues/47533 - if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX) { + if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX && DerivedLinkContext.App.Platform != ApplePlatform.MacCatalyst) { Driver.Log (4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name); break; }