From e19cb85a6261352813089e85e6b926e8b2bb722f Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Thu, 15 Dec 2016 11:07:34 +0000 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Fix an issue where Facade assemblies are deployed A change "somewhere" has recently causes this issue. The problem is in Release mode we now include the Facade assemblies in the package. Which is something we definately should NOT be doing. That said we do need the Facades in order for Linking and Aot to work since Cecil needs to be able to load them. So what this commit does is make sure the ResolveAssemblies task adds metadata for the Facades. We can then use that in the BuildApk Task to filter out the assemblies we do not want to ship. --- .../Tasks/ResolveAssemblies.cs | 29 ++++++++++++------- .../Utilities/ITaskItemEqualityComparer.cs | 23 +++++++++++++++ .../Xamarin.Android.Build.Tasks.csproj | 3 ++ .../Xamarin.Android.Common.targets | 25 +++++++++++++--- 4 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Utilities/ITaskItemEqualityComparer.cs diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs index 420a38a12fb..108c7922d49 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs @@ -23,6 +23,8 @@ public class ResolveAssemblies : Task [Required] public string ReferenceAssembliesDirectory { get; set; } + public ITaskItem[] DesignTimeFacadeDirectories { get; set; } + public string I18nAssemblies { get; set; } public string LinkMode { get; set; } @@ -56,11 +58,12 @@ bool Execute (DirectoryAssemblyResolver resolver) Log.LogDebugMessage (" I18nAssemblies: {0}", I18nAssemblies); Log.LogDebugMessage (" LinkMode: {0}", LinkMode); Log.LogDebugTaskItems (" Assemblies:", Assemblies); + Log.LogDebugTaskItems (" DesignTimeFacadeDirectories:", DesignTimeFacadeDirectories); foreach (var dir in ReferenceAssembliesDirectory.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) resolver.SearchDirectories.Add (dir); - var assemblies = new HashSet (); + var assemblies = new HashSet (new ITaskItemEqualityComparer ()); var topAssemblyReferences = new List (); @@ -76,7 +79,7 @@ bool Execute (DirectoryAssemblyResolver resolver) if (assemblyDef == null) throw new InvalidOperationException ("Failed to load assembly " + assembly.ItemSpec); topAssemblyReferences.Add (assemblyDef); - assemblies.Add (Path.GetFullPath (assemblyDef.MainModule.FullyQualifiedName)); + assemblies.Add (new TaskItem (Path.GetFullPath (assemblyDef.MainModule.FullyQualifiedName))); } } catch (Exception ex) { Log.LogError ("Exception while loading assemblies: {0}", ex); @@ -93,8 +96,8 @@ bool Execute (DirectoryAssemblyResolver resolver) // Add I18N assemblies if needed AddI18nAssemblies (resolver, assemblies); - ResolvedAssemblies = assemblies.Select (a => new TaskItem (a)).ToArray (); - ResolvedSymbols = assemblies.Select (a => a + ".mdb").Where (a => File.Exists (a)).Select (a => new TaskItem (a)).ToArray (); + ResolvedAssemblies = assemblies.ToArray (); + ResolvedSymbols = assemblies.Select (a => new TaskItem (a + ".mdb")).Where (a => File.Exists (a.ItemSpec)).ToArray (); ResolvedFrameworkAssemblies = ResolvedAssemblies.Where (p => MonoAndroidHelper.IsFrameworkAssembly (p.ItemSpec, true)).ToArray (); ResolvedUserAssemblies = ResolvedAssemblies.Where (p => !MonoAndroidHelper.IsFrameworkAssembly (p.ItemSpec, true)).ToArray (); ResolvedDoNotPackageAttributes = do_not_package_atts.ToArray (); @@ -110,13 +113,14 @@ bool Execute (DirectoryAssemblyResolver resolver) readonly List do_not_package_atts = new List (); int indent = 2; - void AddAssemblyReferences (DirectoryAssemblyResolver resolver, ICollection assemblies, AssemblyDefinition assembly, bool topLevel) + void AddAssemblyReferences (DirectoryAssemblyResolver resolver, ICollection assemblies, AssemblyDefinition assembly, bool topLevel) { var fqname = assembly.MainModule.FullyQualifiedName; var fullPath = Path.GetFullPath (fqname); + var item = new TaskItem (fullPath); // Don't repeat assemblies we've already done - if (!topLevel && assemblies.Contains (fullPath)) + if (!topLevel && assemblies.Contains (item)) return; foreach (var att in assembly.CustomAttributes.Where (a => a.AttributeType.FullName == "Java.Interop.DoNotPackageAttribute")) { @@ -129,8 +133,11 @@ void AddAssemblyReferences (DirectoryAssemblyResolver resolver, ICollection new AssemblyNameDefinition (a, null).Name != assembly.Name.Name)) - assemblies.Add (fullPath); + if (!topLevel && assemblies.All (a => new AssemblyNameDefinition (a.ItemSpec, null).Name != assembly.Name.Name)) { + var path = Path.GetDirectoryName (fullPath); + item.SetMetadata ("ResolvedFrom", DesignTimeFacadeDirectories.Any (x => Path.GetDirectoryName (x.ItemSpec).StartsWith (Path.GetDirectoryName (path))) ? "ImplicitlyExpandDesignTimeFacades" : ""); + assemblies.Add (item); + } // Recurse into each referenced assembly foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) { @@ -152,7 +159,7 @@ static LinkModes ParseLinkMode (string linkmode) return mode; } - void AddI18nAssemblies (DirectoryAssemblyResolver resolver, ICollection assemblies) + void AddI18nAssemblies (DirectoryAssemblyResolver resolver, ICollection assemblies) { var i18n = Linker.ParseI18nAssemblies (I18nAssemblies); var link = ParseLinkMode (LinkMode); @@ -179,10 +186,10 @@ void AddI18nAssemblies (DirectoryAssemblyResolver resolver, ICollection assemblies.Add (ResolveI18nAssembly (resolver, "I18N.West")); } - string ResolveI18nAssembly (DirectoryAssemblyResolver resolver, string name) + ITaskItem ResolveI18nAssembly (DirectoryAssemblyResolver resolver, string name) { var assembly = resolver.Resolve (AssemblyNameReference.Parse (name)); - return Path.GetFullPath (assembly.MainModule.FullyQualifiedName); + return new TaskItem (Path.GetFullPath (assembly.MainModule.FullyQualifiedName)); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ITaskItemEqualityComparer.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ITaskItemEqualityComparer.cs new file mode 100644 index 00000000000..2f081362666 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Utilities/ITaskItemEqualityComparer.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using Microsoft.Build.Framework; + +namespace Xamarin.Android.Tasks +{ + public class ITaskItemEqualityComparer : IEqualityComparer + { + public bool Equals (ITaskItem x, ITaskItem y) + { + if (x == null || y == null) + return false; + return x.ItemSpec == y.ItemSpec; + } + + public int GetHashCode (ITaskItem obj) + { + if (obj == null) + return 0; + return obj.ItemSpec.GetHashCode (); + } + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj index 2324bb52335..93b775b0c06 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj @@ -393,6 +393,9 @@ Utilities\Files.cs + + Utilities\ITaskItemEqualityComparer.cs + Linker\Mono.Tuner\ApplyPreserveAttributeBase.cs diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 2dbbb79d769..37c91084b6e 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1234,6 +1234,7 @@ because xbuild doesn't support framework reference assemblies. _GetAdditionalResourcesFromAssemblies; _CreateAdditionalResourceCache; _GenerateAndroidResourceDir; + _ValidateAndroidPackageProperties; @@ -1407,6 +1408,7 @@ because xbuild doesn't support framework reference assemblies. Assemblies="$(OutDir)$(TargetFileName);@(FilteredAssemblies)" I18nAssemblies="$(MandroidI18n)" LinkMode="$(AndroidLinkMode)" + DesignTimeFacadeDirectories="@(DesignTimeFacadeDirectories)" ReferenceAssembliesDirectory="$(TargetFrameworkDirectory)"> @@ -1612,6 +1614,7 @@ because xbuild doesn't support framework reference assemblies. + @@ -1638,36 +1641,42 @@ because xbuild doesn't support framework reference assemblies. @@ -1733,6 +1742,7 @@ because xbuild doesn't support framework reference assemblies. _CheckDuplicateJavaLibraries; _GetAdditionalResourcesFromAssemblies; _CreateAdditionalResourceCache; + _DefineBuildTargetAbis; <_CreateBaseApkInputs> $(MSBuildAllProjects) @@ -2149,6 +2159,12 @@ because xbuild doesn't support framework reference assemblies. + + + <_FilteredShrunkFrameworkAssemblies Include="@(_ShrunkFrameworkAssemblies)" Condition="'%(_ShrunkFrameworkAssemblies.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades'" /> + + + <_PrepareBuildApkDependsOnTargets> _SetLatestTargetFrameworkVersion; @@ -2165,6 +2181,7 @@ because xbuild doesn't support framework reference assemblies. _ResolveSatellitePaths; _CheckApkPerAbiFlag ;_LintChecks + ;FilterDesignTimeFacades @@ -2200,7 +2217,7 @@ because xbuild doesn't support framework reference assemblies. SupportedAbis="$(_BuildTargetAbis)" AndroidSequencePointsMode="$(_SequencePointsMode)" AotAdditionalArguments="$(AndroidAotAdditionalArguments)" - ResolvedAssemblies="@(_ResolvedUserAssemblies);@(_ShrunkFrameworkAssemblies)" + ResolvedAssemblies="@(_ResolvedUserAssemblies);@(_FilteredShrunkFrameworkAssemblies)" AotOutputDirectory="$(_AndroidAotBinDirectory)" IntermediateAssemblyDir="$(MonoAndroidIntermediateAssemblyDir)" LinkMode="$(AndroidLinkMode)" @@ -2214,14 +2231,14 @@ because xbuild doesn't support framework reference assemblies. Condition=" '$(AndroidAotMode)' == 'Hybrid' And '$(AotAssemblies)' == 'True' " AndroidAotMode="$(AndroidAotMode)" ToolPath="$(_MonoAndroidToolsDirectory)" - ResolvedAssemblies="@(_ResolvedAssemblies)"> + ResolvedAssemblies="@(_FilteredShrunkFrameworkAssemblies)">