diff --git a/external/Java.Interop b/external/Java.Interop index a1d3ecc8ba6..084e9f7f5c7 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit a1d3ecc8ba6e67b96ae1c633194b0e78c2ac5c23 +Subproject commit 084e9f7f5c7de86a75a372dbff58f72042df2477 diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs index 653e519819a..1e1fd67e3ae 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs @@ -444,30 +444,31 @@ void AddRuntimeLibraries (ZipArchive apk, string supportedAbis) void AddNativeLibrariesFromAssemblies (ZipArchive apk, string supportedAbis) { var abis = supportedAbis.Split (new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); - var res = new DirectoryAssemblyResolver (Console.WriteLine, loadDebugSymbols: false); + using (var res = new DirectoryAssemblyResolver (Console.WriteLine, loadDebugSymbols: false)) { foreach (var assembly in EmbeddedNativeLibraryAssemblies) res.Load (assembly.ItemSpec); - foreach (var assemblyPath in EmbeddedNativeLibraryAssemblies) { - var assembly = res.GetAssembly (assemblyPath.ItemSpec); - foreach (var mod in assembly.Modules) { - var ressozip = mod.Resources.FirstOrDefault (r => r.Name == "__AndroidNativeLibraries__.zip") as EmbeddedResource; - if (ressozip == null) - continue; - var data = ressozip.GetResourceData (); - using (var ms = new MemoryStream (data)) { - using (var zip = ZipArchive.Open (ms)) { - foreach (var e in zip.Where (x => abis.Any (a => x.FullName.Contains (a)))) { - if (e.IsDirectory) - continue; - var key = e.FullName.Replace ("native_library_imports", "lib"); - if (apk.Any(k => k.FullName == key)) { - Log.LogCodedWarning ("4301", "Apk already contains the item {0}; ignoring.", key); - continue; - } - using (var s = new MemoryStream ()) { - e.Extract (s); - s.Position = 0; - apk.AddEntry (s.ToArray (),key); + foreach (var assemblyPath in EmbeddedNativeLibraryAssemblies) { + var assembly = res.GetAssembly (assemblyPath.ItemSpec); + foreach (var mod in assembly.Modules) { + var ressozip = mod.Resources.FirstOrDefault (r => r.Name == "__AndroidNativeLibraries__.zip") as EmbeddedResource; + if (ressozip == null) + continue; + var data = ressozip.GetResourceData (); + using (var ms = new MemoryStream (data)) { + using (var zip = ZipArchive.Open (ms)) { + foreach (var e in zip.Where (x => abis.Any (a => x.FullName.Contains (a)))) { + if (e.IsDirectory) + continue; + var key = e.FullName.Replace ("native_library_imports", "lib"); + if (apk.Any (k => k.FullName == key)) { + Log.LogCodedWarning ("4301", "Apk already contains the item {0}; ignoring.", key); + continue; + } + using (var s = new MemoryStream ()) { + e.Extract (s); + s.Position = 0; + apk.AddEntry (s.ToArray (), key); + } } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CheckTargetFrameworks.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CheckTargetFrameworks.cs index cddc6ff69b1..974c4f22c7f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CheckTargetFrameworks.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CheckTargetFrameworks.cs @@ -23,9 +23,8 @@ public class CheckTargetFrameworks : Task public string ProjectFile { get; set; } Dictionary apiLevels = new Dictionary (); - DirectoryAssemblyResolver res; - int ExtractApiLevel(ITaskItem ass) + int ExtractApiLevel(DirectoryAssemblyResolver res, ITaskItem ass) { Log.LogDebugMessage (ass.ItemSpec); foreach (var ca in res.GetAssembly (ass.ItemSpec).CustomAttributes) { @@ -51,13 +50,14 @@ public override bool Execute () Log.LogDebugMessage (" ProjectFile: {0}", ProjectFile); Log.LogDebugTaskItems (" ResolvedUserAssemblies: {0}", ResolvedAssemblies); - res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); - foreach (var assembly in ResolvedAssemblies) { - res.Load (Path.GetFullPath (assembly.ItemSpec)); - var apiLevel = ExtractApiLevel (assembly); - if (apiLevel > 0) { - Log.LogDebugMessage ("{0}={1}", Path.GetFileNameWithoutExtension (assembly.ItemSpec), apiLevel); - apiLevels.Add (assembly, apiLevel); + using (var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false)) { + foreach (var assembly in ResolvedAssemblies) { + res.Load (Path.GetFullPath (assembly.ItemSpec)); + var apiLevel = ExtractApiLevel (res, assembly); + if (apiLevel > 0) { + Log.LogDebugMessage ("{0}={1}", Path.GetFileNameWithoutExtension (assembly.ItemSpec), apiLevel); + apiLevels.Add (assembly, apiLevel); + } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs index 4302432f731..8d99775bf99 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs @@ -79,7 +79,11 @@ public override bool Execute () Log.LogDebugMessage (" ApplicationJavaClass: {0}", ApplicationJavaClass); try { - Run (); + // We're going to do 3 steps here instead of separate tasks so + // we can share the list of JLO TypeDefinitions between them + using (var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: true)) { + Run (res); + } } catch (XamarinAndroidException e) { Log.LogCodedError (string.Format ("XA{0:0000}", e.Code), e.MessageWithoutCode); @@ -90,17 +94,13 @@ public override bool Execute () return !Log.HasLoggedErrors; } - void Run () + void Run (DirectoryAssemblyResolver res) { PackageNamingPolicy pnp; JniType.PackageNamingPolicy = Enum.TryParse (PackageNamingPolicy, out pnp) ? pnp : PackageNamingPolicyEnum.LowercaseHash; var temp = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ()); Directory.CreateDirectory (temp); - // We're going to do 3 steps here instead of separate tasks so - // we can share the list of JLO TypeDefinitions between them - var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols:true); - var selectedWhitelistAssemblies = new List (); // Put every assembly we'll need in the resolver diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs index ec1c1640e75..e1c8956b25f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateResourceDesigner.cs @@ -106,23 +106,24 @@ public override bool Execute () var assemblyNames = new List (); if (IsApplication && References != null && References.Any ()) { // FIXME: should this be unified to some better code with ResolveLibraryProjectImports? - var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); - foreach (var assemblyName in References) { - var suffix = assemblyName.ItemSpec.EndsWith (".dll") ? String.Empty : ".dll"; - string hintPath = assemblyName.GetMetadata ("HintPath").Replace (Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); - string fileName = assemblyName.ItemSpec + suffix; - resolver.Load (Path.GetFullPath (assemblyName.ItemSpec)); - if (!String.IsNullOrEmpty (hintPath) && !File.Exists (hintPath)) // ignore invalid HintPath - hintPath = null; - string assemblyPath = String.IsNullOrEmpty (hintPath) ? fileName : hintPath; - if (MonoAndroidHelper.IsFrameworkAssembly (fileName) && !MonoAndroidHelper.FrameworkEmbeddedJarLookupTargets.Contains (Path.GetFileName (fileName))) - continue; - Log.LogDebugMessage ("Scan assembly {0} for resource generator", fileName); - assemblyNames.Add (assemblyPath); + using (var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false)) { + foreach (var assemblyName in References) { + var suffix = assemblyName.ItemSpec.EndsWith (".dll") ? String.Empty : ".dll"; + string hintPath = assemblyName.GetMetadata ("HintPath").Replace (Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + string fileName = assemblyName.ItemSpec + suffix; + resolver.Load (Path.GetFullPath (assemblyName.ItemSpec)); + if (!String.IsNullOrEmpty (hintPath) && !File.Exists (hintPath)) // ignore invalid HintPath + hintPath = null; + string assemblyPath = String.IsNullOrEmpty (hintPath) ? fileName : hintPath; + if (MonoAndroidHelper.IsFrameworkAssembly (fileName) && !MonoAndroidHelper.FrameworkEmbeddedJarLookupTargets.Contains (Path.GetFileName (fileName))) + continue; + Log.LogDebugMessage ("Scan assembly {0} for resource generator", fileName); + assemblyNames.Add (assemblyPath); + } + var assemblies = assemblyNames.Select (assembly => resolver.GetAssembly (assembly)); + new ResourceDesignerImportGenerator (Namespace, resources) + .CreateImportMethods (assemblies); } - var assemblies = assemblyNames.Select (assembly => resolver.GetAssembly (assembly)); - new ResourceDesignerImportGenerator (Namespace, resources) - .CreateImportMethods (assemblies); } AdjustConstructor (isFSharp, resources); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs index acb68e5f400..656beb25c14 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAdditionalResourcesFromAssemblies.cs @@ -363,28 +363,29 @@ public override bool Execute () ? CachePath : Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), CacheBaseDir); - var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); - foreach (var assemblyItem in Assemblies) { - string fullPath = Path.GetFullPath (assemblyItem.ItemSpec); - if (assemblies.Contains (fullPath)) { - LogDebugMessage (" Skip assembly: {0}, it was already processed", fullPath); - continue; - } - assemblies.Add (fullPath); - resolver.Load (fullPath); - // Append source file name (without the Xamarin. prefix or extension) to the base folder - // This would help avoid potential collisions. - foreach (var ca in resolver.GetAssembly (assemblyItem.ItemSpec).CustomAttributes) { - switch (ca.AttributeType.FullName) { - case "Android.IncludeAndroidResourcesFromAttribute": - AddAttributeValue (androidResources, ca, "XA5206", "{0}. Android resource directory {1} doesn't exist.", true, fullPath); - break; - case "Java.Interop.JavaLibraryReferenceAttribute": - AddAttributeValue (javaLibraries, ca, "XA5207", "{0}. Java library file {1} doesn't exist.", false, fullPath); - break; - case "Android.NativeLibraryReferenceAttribute": - AddAttributeValue (nativeLibraries, ca, "XA5210", "{0}. Native library file {1} doesn't exist.", false, fullPath); - break; + using (var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false)) { + foreach (var assemblyItem in Assemblies) { + string fullPath = Path.GetFullPath (assemblyItem.ItemSpec); + if (assemblies.Contains (fullPath)) { + LogDebugMessage (" Skip assembly: {0}, it was already processed", fullPath); + continue; + } + assemblies.Add (fullPath); + resolver.Load (fullPath); + // Append source file name (without the Xamarin. prefix or extension) to the base folder + // This would help avoid potential collisions. + foreach (var ca in resolver.GetAssembly (assemblyItem.ItemSpec).CustomAttributes) { + switch (ca.AttributeType.FullName) { + case "Android.IncludeAndroidResourcesFromAttribute": + AddAttributeValue (androidResources, ca, "XA5206", "{0}. Android resource directory {1} doesn't exist.", true, fullPath); + break; + case "Java.Interop.JavaLibraryReferenceAttribute": + AddAttributeValue (javaLibraries, ca, "XA5207", "{0}. Java library file {1} doesn't exist.", false, fullPath); + break; + case "Android.NativeLibraryReferenceAttribute": + AddAttributeValue (nativeLibraries, ca, "XA5210", "{0}. Native library file {1} doesn't exist.", false, fullPath); + break; + } } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs index 12723dc3764..73b8e614fe9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs @@ -75,8 +75,16 @@ public override bool Execute () Log.LogDebugMessage (" DumpDependencies: {0}", DumpDependencies); Log.LogDebugMessage (" LinkOnlyNewerThan: {0}", LinkOnlyNewerThan); - var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); - + var rp = new ReaderParameters { + InMemory = true, + }; + using (var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false, loadReaderParameters: rp)) { + return Execute (res); + } + } + + bool Execute (DirectoryAssemblyResolver res) + { // Put every assembly we'll need in the resolver foreach (var assembly in ResolvedAssemblies) { res.Load (Path.GetFullPath (assembly.ItemSpec)); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs index 090e409f83e..85bc81ce91e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveAssemblies.cs @@ -42,9 +42,14 @@ public class ResolveAssemblies : Task [Output] public string[] ResolvedDoNotPackageAttributes { get; set; } - DirectoryAssemblyResolver resolver; - public override bool Execute () + { + using (var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false)) { + return Execute (resolver); + } + } + + bool Execute (DirectoryAssemblyResolver resolver) { Log.LogDebugMessage ("ResolveAssemblies Task"); Log.LogDebugMessage (" ReferenceAssembliesDirectory: {0}", ReferenceAssembliesDirectory); @@ -52,7 +57,6 @@ public override bool Execute () Log.LogDebugMessage (" LinkMode: {0}", LinkMode); Log.LogDebugTaskItems (" Assemblies:", Assemblies); - resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); foreach (var dir in ReferenceAssembliesDirectory.Split (new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) resolver.SearchDirectories.Add (dir); @@ -80,14 +84,14 @@ public override bool Execute () } try { foreach (var assembly in topAssemblyReferences) - AddAssemblyReferences (assemblies, assembly, true); + AddAssemblyReferences (resolver, assemblies, assembly, true); } catch (Exception ex) { Log.LogError ("Exception while loading assemblies: {0}", ex); return false; } // Add I18N assemblies if needed - AddI18nAssemblies (assemblies); + 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 (); @@ -100,13 +104,13 @@ public override bool Execute () Log.LogDebugTaskItems (" [Output] ResolvedFrameworkAssemblies:", ResolvedFrameworkAssemblies); Log.LogDebugTaskItems (" [Output] ResolvedDoNotPackageAttributes:", ResolvedDoNotPackageAttributes); - return true; + return !Log.HasLoggedErrors; } readonly List do_not_package_atts = new List (); int indent = 2; - private void AddAssemblyReferences (ICollection assemblies, AssemblyDefinition assembly, bool topLevel) + void AddAssemblyReferences (DirectoryAssemblyResolver resolver, ICollection assemblies, AssemblyDefinition assembly, bool topLevel) { var fqname = assembly.MainModule.FullyQualifiedName; @@ -130,7 +134,7 @@ private void AddAssemblyReferences (ICollection assemblies, AssemblyDefi // Recurse into each referenced assembly foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) { var reference_assembly = resolver.Resolve (reference); - AddAssemblyReferences (assemblies, reference_assembly, false); + AddAssemblyReferences (resolver, assemblies, reference_assembly, false); } indent -= 2; } @@ -147,7 +151,7 @@ static LinkModes ParseLinkMode (string linkmode) return mode; } - private void AddI18nAssemblies (ICollection assemblies) + void AddI18nAssemblies (DirectoryAssemblyResolver resolver, ICollection assemblies) { var i18n = Linker.ParseI18nAssemblies (I18nAssemblies); var link = ParseLinkMode (LinkMode); @@ -156,25 +160,25 @@ private void AddI18nAssemblies (ICollection assemblies) if (i18n == Mono.Linker.I18nAssemblies.None) return; - assemblies.Add (ResolveI18nAssembly ("I18N")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N")); if (i18n.HasFlag (Mono.Linker.I18nAssemblies.CJK)) - assemblies.Add (ResolveI18nAssembly ("I18N.CJK")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N.CJK")); if (i18n.HasFlag (Mono.Linker.I18nAssemblies.MidEast)) - assemblies.Add (ResolveI18nAssembly ("I18N.MidEast")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N.MidEast")); if (i18n.HasFlag (Mono.Linker.I18nAssemblies.Other)) - assemblies.Add (ResolveI18nAssembly ("I18N.Other")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N.Other")); if (i18n.HasFlag (Mono.Linker.I18nAssemblies.Rare)) - assemblies.Add (ResolveI18nAssembly ("I18N.Rare")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N.Rare")); if (i18n.HasFlag (Mono.Linker.I18nAssemblies.West)) - assemblies.Add (ResolveI18nAssembly ("I18N.West")); + assemblies.Add (ResolveI18nAssembly (resolver, "I18N.West")); } - private string ResolveI18nAssembly (string name) + string ResolveI18nAssembly (DirectoryAssemblyResolver resolver, string name) { var assembly = resolver.Resolve (AssemblyNameReference.Parse (name)); return assembly.MainModule.FullyQualifiedName; diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs index cb30333484f..eb542d9ea2c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveLibraryProjectImports.cs @@ -71,7 +71,10 @@ public override bool Execute () var resolvedResourceDirectories = new List (); var resolvedAssetDirectories = new List (); var resolvedEnvironmentFiles = new List (); - Extract (jars, resolvedResourceDirectories, resolvedAssetDirectories, resolvedEnvironmentFiles); + + using (var resolver = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false)) { + Extract (resolver, jars, resolvedResourceDirectories, resolvedAssetDirectories, resolvedEnvironmentFiles); + } Jars = jars.ToArray (); ResolvedResourceDirectories = resolvedResourceDirectories @@ -133,6 +136,7 @@ static string GetTargetAssembly (ITaskItem assemblyName) // Extracts library project contents under e.g. obj/Debug/[__library_projects__/*.jar | res/*/*] void Extract ( + DirectoryAssemblyResolver res, ICollection jars, ICollection resolvedResourceDirectories, ICollection resolvedAssetDirectories, @@ -142,7 +146,6 @@ void Extract ( if (!outdir.Exists) outdir.Create (); - var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols: false); foreach (var assembly in Assemblies) res.Load (assembly.ItemSpec); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs b/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs index a79f8328af7..85f29b807ca 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs @@ -28,7 +28,13 @@ public override bool Execute () Log.LogDebugMessage ("StripEmbeddedLibraries Task"); Log.LogDebugTaskItems (" Assemblies: ", Assemblies); - var res = new DirectoryAssemblyResolver (Log.LogWarning, true); + using (var res = new DirectoryAssemblyResolver (Log.LogWarning, true)) { + return Execute (res); + } + } + + bool Execute (DirectoryAssemblyResolver res) + { foreach (var assembly in Assemblies) res.Load (Path.GetFullPath (assembly.ItemSpec));