diff --git a/tools/dotnet-linker/Compat.cs b/tools/dotnet-linker/Compat.cs index 4961c0a23bf1..b12dccb08d2f 100644 --- a/tools/dotnet-linker/Compat.cs +++ b/tools/dotnet-linker/Compat.cs @@ -119,6 +119,22 @@ public class Pipeline { } } +namespace Xamarin.Linker { + public class Profile { + public LinkerConfiguration Configuration { get; private set; } + + public Profile (LinkerConfiguration config) + { + Configuration = config; + } + + public bool IsProductAssembly (AssemblyDefinition assembly) + { + return assembly.Name.Name == Configuration.PlatformAssembly; + } + } +} + namespace Mono.Linker { public static class LinkContextExtensions { public static void LogMessage (this LinkContext context, string messsage) diff --git a/tools/dotnet-linker/LinkerConfiguration.cs b/tools/dotnet-linker/LinkerConfiguration.cs index e3b80f2d592c..412a4af200fc 100644 --- a/tools/dotnet-linker/LinkerConfiguration.cs +++ b/tools/dotnet-linker/LinkerConfiguration.cs @@ -10,6 +10,7 @@ using Xamarin.Bundler; using Xamarin.Utils; +using Xamarin.Tuner; using ObjCRuntime; @@ -38,6 +39,7 @@ public class LinkerConfiguration { public CompilerFlags CompilerFlags; public LinkContext Context { get; private set; } + public Profile Profile { get; private set; } // The list of assemblies is populated in CollectAssembliesStep. public List Assemblies = new List (); @@ -62,6 +64,7 @@ public static LinkerConfiguration GetInstance (LinkContext context) if (!File.Exists (linker_file)) throw new FileNotFoundException ($"The custom linker file {linker_file} does not exist."); + Profile = new Profile (this); Application = new Application (this); Target = new Target (Application); CompilerFlags = new CompilerFlags (Target); diff --git a/tools/dotnet-linker/SetupStep.cs b/tools/dotnet-linker/SetupStep.cs index e722f7b3345e..2d6e5525f8a5 100644 --- a/tools/dotnet-linker/SetupStep.cs +++ b/tools/dotnet-linker/SetupStep.cs @@ -55,6 +55,7 @@ protected override void Process () // [assembly: LinkSafe] attributes, which means we treat them as sdk assemblies and those may have // Preserve attributes. prelink_substeps.Add (new ApplyPreserveAttribute ()); + prelink_substeps.Add (new PreserveSmartEnumConversionsSubStep ()); } Steps.Add (new LoadNonSkippedAssembliesStep ()); diff --git a/tools/dotnet-linker/dotnet-linker.csproj b/tools/dotnet-linker/dotnet-linker.csproj index a826bc95db06..180401cff87f 100644 --- a/tools/dotnet-linker/dotnet-linker.csproj +++ b/tools/dotnet-linker/dotnet-linker.csproj @@ -137,9 +137,15 @@ external\tools\linker\ApplyPreserveAttribute.cs + + external\tools\linker\ExceptionalSubStep.cs + external\tools\linker\MonoTouch.Tuner\Extensions.cs + + external\tools\linker\MonoTouch.Tuner\PreserveSmartEnumConversionsSubStep.cs + external\tools\linker\MobileExtensions.cs diff --git a/tools/linker/ExceptionalSubStep.cs b/tools/linker/ExceptionalSubStep.cs index 6bcc8346d09c..3fe8ab3c0c90 100644 --- a/tools/linker/ExceptionalSubStep.cs +++ b/tools/linker/ExceptionalSubStep.cs @@ -7,15 +7,40 @@ using Xamarin.Tuner; +#if NET +using Mono.Linker; +using Mono.Linker.Steps; +#endif + namespace Xamarin.Linker { public abstract class ExceptionalSubStep : BaseSubStep { protected DerivedLinkContext LinkContext { get { +#if NET + throw new NotImplementedException (); +#else return (DerivedLinkContext) base.context; +#endif + } + } + +#if NET + protected LinkContext context { + get { return Context; } + } + + protected LinkerConfiguration Configuration { + get { return LinkerConfiguration.GetInstance (Context); } + } + + protected Profile Profile { + get { + return Configuration.Profile; } } +#endif public override sealed void ProcessAssembly (AssemblyDefinition assembly) { diff --git a/tools/linker/MonoTouch.Tuner/PreserveSmartEnumConversionsSubStep.cs b/tools/linker/MonoTouch.Tuner/PreserveSmartEnumConversionsSubStep.cs index b32c56df1761..b1850d520dd2 100644 --- a/tools/linker/MonoTouch.Tuner/PreserveSmartEnumConversionsSubStep.cs +++ b/tools/linker/MonoTouch.Tuner/PreserveSmartEnumConversionsSubStep.cs @@ -7,7 +7,11 @@ using Mono.Cecil.Cil; using Mono.Linker; using Mono.Tuner; +#if NET +using Mono.Linker.Steps; +#else using MonoTouch.Tuner; +#endif using Xamarin.Bundler; @@ -21,7 +25,10 @@ public class PreserveSmartEnumConversionsSubStep : ExceptionalSubStep public override SubStepTargets Targets { get { - return SubStepTargets.Method | SubStepTargets.Property; + return + SubStepTargets.Method + | SubStepTargets.Type // SubStepTargets.Type is only needed to work around a linker bug: https://github.com/mono/linker/issues/1458 + | SubStepTargets.Property; } } @@ -41,6 +48,18 @@ public override bool IsActiveFor (AssemblyDefinition assembly) void Preserve (Tuple pair, MethodDefinition conditionA, MethodDefinition conditionB = null) { +#if NET + // The AddPreservedMethod (MethodDefinition, MethodDefinition) has not been exposed yet, so preserve the entire containing type instead. + // https://github.com/mono/linker/issues/1456 + if (conditionA != null) { + context.Annotations.AddPreservedMethod (conditionA.DeclaringType, pair.Item1); + context.Annotations.AddPreservedMethod (conditionA.DeclaringType, pair.Item2); + } + if (conditionB != null) { + context.Annotations.AddPreservedMethod (conditionB.DeclaringType, pair.Item1); + context.Annotations.AddPreservedMethod (conditionB.DeclaringType, pair.Item2); + } +#else if (conditionA != null) { context.Annotations.AddPreservedMethod (conditionA, pair.Item1); context.Annotations.AddPreservedMethod (conditionA, pair.Item2); @@ -49,6 +68,7 @@ void Preserve (Tuple pair, MethodDefinition context.Annotations.AddPreservedMethod (conditionB, pair.Item1); context.Annotations.AddPreservedMethod (conditionB, pair.Item2); } +#endif } void ProcessAttributeProvider (ICustomAttributeProvider provider, MethodDefinition conditionA, MethodDefinition conditionB = null)