From c0c0e63a3be2a5727b156398ab91dd24649b8234 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 21 Feb 2018 09:27:26 +0100 Subject: [PATCH] [mtouch] Find the link context for code shared app extensions in the static registrar. Fixes #3514. (#3545) When code sharing is enabled, only the container app/target will have a LinkContext. So make sure the static registrar finds that link context when it needs information from the linker. https://github.com/xamarin/xamarin-macios/issues/3514 --- tests/mtouch/MTouch.cs | 38 +++++++++++++++++++++++++++++++++ tools/common/StaticRegistrar.cs | 2 +- tools/common/Target.cs | 12 +++++++++++ tools/mtouch/Application.cs | 1 + tools/mtouch/Target.cs | 8 +++++++ tools/mtouch/mtouch.cs | 4 +++- 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/mtouch/MTouch.cs b/tests/mtouch/MTouch.cs index bc6b871573..493134b8cd 100644 --- a/tests/mtouch/MTouch.cs +++ b/tests/mtouch/MTouch.cs @@ -3692,6 +3692,44 @@ public class HandlerTest Assert.That (missingSimlauncherSymbols, Is.Empty, "no missing simlauncher symbols"); } + [Test] + public void LinkedAwayTypesInContainerAppLinker () + { + var codeApp = "[Foundation.Preserve] public class TestApp1 { static void X () { System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ()); } }"; + var codeExt = @" +public partial class KeyboardViewController : UIKit.UIInputViewController +{ + public KeyboardViewController (System.IntPtr handle) : base (handle) { } + public override void TextWillChange (UIKit.IUITextInput textInput) { } + public override void TextDidChange (UIKit.IUITextInput textInput) { } +} + +[Foundation.Preserve] public class TestApp2 { static void X () { System.Console.WriteLine (typeof (ObjCRuntime.Runtime).ToString ()); } }"; + + using (var extension = new MTouchTool ()) { + extension.CreateTemporaryServiceExtension (extraCode: codeExt); + extension.CreateTemporaryCacheDirectory (); + extension.Abi = "arm64"; + extension.DSym = false; // faster test + extension.MSym = false; // faster test + extension.NoStrip = true; // faster test + extension.AssertExecute (MTouchAction.BuildDev, "extension build"); + + using (var mtouch = new MTouchTool ()) { + mtouch.AppExtensions.Add (extension); + mtouch.CreateTemporaryApp (extraCode: codeApp); + mtouch.CreateTemporaryCacheDirectory (); + mtouch.Abi = "arm64"; + mtouch.DSym = false; // faster test + mtouch.MSym = false; // faster test + mtouch.NoStrip = true; // faster test + + mtouch.AssertExecute (MTouchAction.BuildDev, "build"); + mtouch.AssertNoWarnings (); + } + } + } + public void XamarinSdkAdjustLibs () { using (var exttool = new MTouchTool ()) { diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs index 80bdad790e..2d2589808a 100644 --- a/tools/common/StaticRegistrar.cs +++ b/tools/common/StaticRegistrar.cs @@ -531,7 +531,7 @@ namespace Registrar { public Xamarin.Tuner.DerivedLinkContext LinkContext { get { - return Target?.LinkContext; + return Target?.GetLinkContext (); } } diff --git a/tools/common/Target.cs b/tools/common/Target.cs index a19367c7b9..67384007fa 100644 --- a/tools/common/Target.cs +++ b/tools/common/Target.cs @@ -62,6 +62,18 @@ namespace Xamarin.Bundler { this.StaticRegistrar = new StaticRegistrar (this); } + // This will find the link context, possibly looking in container targets. + public PlatformLinkContext GetLinkContext () + { + if (LinkContext != null) + return LinkContext; +#if MTOUCH + if (App.IsExtension && App.IsCodeShared) + return ContainerTarget.GetLinkContext (); +#endif + return null; + } + public bool CachedLink { get { return cached_link; diff --git a/tools/mtouch/Application.cs b/tools/mtouch/Application.cs index ffa03ce24b..01bfcfcb60 100644 --- a/tools/mtouch/Application.cs +++ b/tools/mtouch/Application.cs @@ -105,6 +105,7 @@ namespace Xamarin.Bundler { public bool IsExtension; public List Extensions = new List (); // A list of the extensions this app contains. public List AppExtensions = new List (); + public Application ContainerApp; // For extensions, this is the containing app public bool? EnablePie; public bool NativeStrip = true; diff --git a/tools/mtouch/Target.cs b/tools/mtouch/Target.cs index d3f71ce7f9..d0248a39f7 100644 --- a/tools/mtouch/Target.cs +++ b/tools/mtouch/Target.cs @@ -68,6 +68,14 @@ namespace Xamarin.Bundler } } + // If this is an app extension, this returns the equivalent (32/64bit) target for the container app. + // This may be null (it's possible to build an extension for 32+64bit, and the main app only for 64-bit, for instance. + public Target ContainerTarget { + get { + return App.ContainerApp.Targets.FirstOrDefault ((v) => v.Is32Build == Is32Build); + } + } + // This is a list of all the architectures we need to build, which may include any architectures // in any extensions (but not the main app). List all_architectures; diff --git a/tools/mtouch/mtouch.cs b/tools/mtouch/mtouch.cs index f81124892f..f87fe528ce 100644 --- a/tools/mtouch/mtouch.cs +++ b/tools/mtouch/mtouch.cs @@ -1380,7 +1380,9 @@ namespace Xamarin.Bundler if (!File.Exists (f_path)) continue; Action app_action; - app.AppExtensions.Add (ParseArguments (File.ReadAllLines (f_path), out app_action)); + var ext = ParseArguments (File.ReadAllLines (f_path), out app_action); + ext.ContainerApp = app; + app.AppExtensions.Add (ext); if (app_action != Action.Build) throw ErrorHelper.CreateError (99, "Internal error: Extension build action is '{0}' when it should be 'Build'. Please file a bug report with a test case (http://bugzilla.xamarin.com).", app_action); }