Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NativeAOT on macOS #18524

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ObjCRuntime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,12 @@ static IntPtr PrintAllExceptions (IntPtr exception_gchandle)
// For XM it will also register all assemblies loaded in the current appdomain.
internal static void RegisterAssemblies ()
{
#if NET
if (IsNativeAOT) {
return;
}
#endif

#if PROFILE
var watch = new Stopwatch ();
#endif
Expand Down
1 change: 0 additions & 1 deletion tests/bindings-test/ProtocolTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class ProtocolTest {
return false;
}


return true;
}
}
Expand Down
4 changes: 3 additions & 1 deletion tests/monotouch-test/AppKit/DerivedEventTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ void TestDelegates (NSComboBox b)
[Test]
public void DerivedEvents_OverwriteThrows ()
{
#if RELEASE
#if NATIVEAOT
var checkTrimmedAway = true;
#elif RELEASE
var checkTrimmedAway = TestRuntime.IsLinkAll;
#else
var checkTrimmedAway = false;
Expand Down
5 changes: 5 additions & 0 deletions tests/monotouch-test/AppKit/NSView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ public void AllItemsWithNSMenuShouldAllowNull ()
foreach (var ctor in types) {
var o = ctor ();
var prop = o.GetType ().GetProperty ("Menu", BindingFlags.Public | BindingFlags.Instance);
#if NATIVEAOT
if (prop is null)
continue; // the property was linked away.
#else
if (prop is null && TestRuntime.IsLinkAll)
continue; // the property was linked away.
#endif
prop.SetValue (o, null, null);
}

Expand Down
2 changes: 2 additions & 0 deletions tests/monotouch-test/ObjCRuntime/EveryFrameworkSmokeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ LoadStatus CheckLoadFailure (string libraryName, string path)
return LoadStatus.FailTest;
}

#if !NATIVEAOT
[Test]
public void ExpectedLibrariesAreLoaded ()
{
Expand All @@ -106,6 +107,7 @@ public void ExpectedLibrariesAreLoaded ()
if (failures.Count > 0)
Assert.Fail (string.Join ("\n", failures));
}
#endif
}
}
#endif // __MACOS__
4 changes: 2 additions & 2 deletions tests/monotouch-test/ObjCRuntime/RegistrarTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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__) || NATIVEAOT
#if (OPTIMIZEALL || NATIVEAOT) && !__MACOS__
var shouldBeRemoved = true;
#else
var shouldBeRemoved = false;
Expand Down Expand Up @@ -2246,7 +2246,7 @@ public void TestCtors ()
}
}

#if __MACOS__
#if __MACOS__ && !NATIVEAOT
[Test]
public void CustomUserTypeWithDynamicallyLoadedAssembly ()
{
Expand Down
4 changes: 4 additions & 0 deletions tests/mtouch/Cache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ public static class Cache // Not really a cache (since the root directory is cle

static Cache ()
{
#if NATIVEAOT
root = Path.Combine (Path.GetDirectoryName (Environment.ProcessPath)!, "tmp-test-dir");
#else
root = Path.Combine (Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().Location)!, "tmp-test-dir");
#endif
if (Directory.Exists (root)) {
var movedRoot = root + DateTime.UtcNow.Ticks.ToString () + "-deletion-in-progress";
// The temporary directory can be big, and it can take a while to clean it out.
Expand Down
5 changes: 2 additions & 3 deletions tests/xharness/Jenkins/TestVariationsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,8 @@ IEnumerable<TestData> 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" };
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 = "SdkOnly" };
yield return new TestData { Variation = "Release (NativeAOT, x64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), Defines = "NATIVEAOT", RuntimeIdentifier = "osx-x64", LinkMode = "SdkOnly" };
}
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 };
Expand Down
2 changes: 1 addition & 1 deletion tools/common/Optimizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public void Initialize (Application app, out List<ProductException> messages)

// We will register protocols if the static registrar is enabled and loading assemblies is not possible
if (!RegisterProtocols.HasValue) {
if (app.Platform != ApplePlatform.MacOSX) {
if (app.Platform != ApplePlatform.MacOSX || app.XamarinRuntime == XamarinRuntime.NativeAOT) {
RegisterProtocols = (app.Registrar == RegistrarMode.Static || app.Registrar == RegistrarMode.ManagedStatic) && !app.UseInterpreter;
} else {
RegisterProtocols = false;
Expand Down
20 changes: 20 additions & 0 deletions tools/common/StaticRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3426,6 +3426,12 @@ bool SpecializeTrampoline (AutoIndentStringBuilder sb, ObjCMethod method, List<E
sb.AppendLine ("}");
return true;
case Trampoline.CopyWithZone2:
#if NET
// Managed Static Registrar handles CopyWithZone2 in GenerateCallToUnmanagedCallersOnlyMethod
if (LinkContext.App.Registrar == RegistrarMode.ManagedStatic) {
return false;
}
#endif
sb.AppendLine ("-(id) copyWithZone: (NSZone *) zone");
sb.AppendLine ("{");
sb.AppendLine ("return xamarin_copyWithZone_trampoline2 (self, _cmd, zone);");
Expand Down Expand Up @@ -3474,6 +3480,7 @@ bool TryGetReturnType (ObjCMethod method, string descriptiveMethodName, List<Exc
case Trampoline.X86_DoubleABI_StretTrampoline:
case Trampoline.StaticStret:
case Trampoline.Stret:
case Trampoline.CopyWithZone2:
switch (method.NativeReturnType.FullName) {
case "System.Int64":
rettype = "long long";
Expand Down Expand Up @@ -4353,6 +4360,14 @@ void GenerateCallToUnmanagedCallersOnlyMethod (AutoIndentStringBuilder sb, ObjCM
sb.WriteLine ($"bool call_super = false;");
if (hasReturnType)
sb.WriteLine ($"{callbackReturnType} rv = {{ 0 }};");
if (method.CurrentTrampoline == Trampoline.CopyWithZone2) {
sb.WriteLine ("id p0 = (id)zone;");
sb.WriteLine ("GCHandle gchandle;");
sb.WriteLine ("enum XamarinGCHandleFlags flags = XamarinGCHandleFlags_None;");
sb.WriteLine ("gchandle = xamarin_get_gchandle_with_flags (self, &flags);");
sb.WriteLine ("if (gchandle != INVALID_GCHANDLE)");
sb.Indent ().WriteLine ("xamarin_set_gchandle_with_flags (self, INVALID_GCHANDLE, XamarinGCHandleFlags_None);").Unindent ();
}

if (!staticCall) {
sb.WriteLine ($"static {ucoEntryPoint}_function {ucoEntryPoint};");
Expand All @@ -4376,6 +4391,11 @@ void GenerateCallToUnmanagedCallersOnlyMethod (AutoIndentStringBuilder sb, ObjCM
GenerateCallToSuperForConstructor (sb, method, exceptions);
}

if (method.CurrentTrampoline == Trampoline.CopyWithZone2) {
sb.WriteLine ("if (gchandle != INVALID_GCHANDLE)");
sb.Indent ().WriteLine ("xamarin_set_gchandle_with_flags (self, gchandle, flags);").Unindent ();
}

if (hasReturnType)
sb.WriteLine ("return rv;");

Expand Down
2 changes: 1 addition & 1 deletion tools/linker/CoreOptimizeGeneratedCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public override bool IsActiveFor (AssemblyDefinition assembly)

// process only assemblies where the linker is enabled (e.g. --linksdk, --linkskip)
AssemblyAction action = Annotations.GetAction (assembly);
if (action != AssemblyAction.Link) {
if (action != AssemblyAction.Link && action != AssemblyAction.Save) {
#if DEBUG
Console.WriteLine ("Assembly {0} : skipped ({1})", assembly, action);
#endif
Expand Down
3 changes: 2 additions & 1 deletion tools/linker/RegistrarRemovalTrackingStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ bool RequiresDynamicRegistrar (AssemblyDefinition assembly, bool warnIfRequired)
//
// and these overloads don't need the dynamic registrar, which means we only have
// to look in assemblies that aren't linked.
if (Annotations.GetAction (assembly) == AssemblyAction.Link && Optimizations.OptimizeBlockLiteralSetupBlock == true)
var action = Annotations.GetAction (assembly);
if ((action == AssemblyAction.Link || action == AssemblyAction.Save) && Optimizations.OptimizeBlockLiteralSetupBlock == true)
break;

switch (mr.Name) {
Expand Down
Loading