From cb51193f694ada51367cbe74ac375bbe25c8a89d Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Tue, 13 Oct 2020 16:21:41 -0400 Subject: [PATCH] Remove MetadataLoadContext dependency from AndroidAppBuilder (#43339) This will allow AndroidAppBuilder to be packaged without having unnecessary dependencies. --- eng/testing/tests.mobile.targets | 8 +-- src/mono/mono.proj | 2 +- .../sample/Android/AndroidSampleApp.csproj | 37 ++++------ src/mono/netcore/sample/Android/Makefile | 5 +- .../AndroidAppBuilder/AndroidAppBuilder.cs | 32 ++++++--- .../AndroidAppBuilder.csproj | 2 - .../AndroidAppBuilder/ApkBuilder.cs | 37 ---------- .../AndroidAppBuilder/AssemblyResolver.cs | 71 ------------------- 8 files changed, 42 insertions(+), 152 deletions(-) delete mode 100644 tools-local/tasks/mobile.tasks/AndroidAppBuilder/AssemblyResolver.cs diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 07ec891cb20cb1..2f0d799395de92 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -28,6 +28,9 @@ AssemblyFile="$(AndroidAppBuilderTasksAssemblyPath)" /> + + + arm64-v8a armeabi-v7a @@ -35,9 +38,6 @@ x86 - - - @@ -49,7 +49,7 @@ - true + true $(ROOTFS_DIR) false .cmd diff --git a/src/mono/netcore/sample/Android/AndroidSampleApp.csproj b/src/mono/netcore/sample/Android/AndroidSampleApp.csproj index c5949f7644f831..3eddf9f315473d 100644 --- a/src/mono/netcore/sample/Android/AndroidSampleApp.csproj +++ b/src/mono/netcore/sample/Android/AndroidSampleApp.csproj @@ -4,53 +4,44 @@ false $(NetCoreAppCurrent) x64 - Android - $(ArtifactsBinDir)microsoft.netcore.app.runtime.android-$(TargetArchitecture)\$(Configuration)\runtimes\android-$(TargetArchitecture)\ + false + android-$(TargetArchitecture) + true + <_TrimmerDefaultAction Condition="'$(Configuration)' == 'Release'">link + True + $(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration)\runtimes\android-$(TargetArchitecture)\ $(NoWarn),CA1050 - + + - + + $(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration) + - - + - + - arm64-v8a - armeabi-v7a - x86_64 - $(Platform) False True $(ANDROID_SDK_ROOT)\platform-tools\adb $(OutputPath)apk\ - - - - - - diff --git a/src/mono/netcore/sample/Android/Makefile b/src/mono/netcore/sample/Android/Makefile index 48aeb1fdbc656c..0ee5290de9b482 100644 --- a/src/mono/netcore/sample/Android/Makefile +++ b/src/mono/netcore/sample/Android/Makefile @@ -8,11 +8,10 @@ runtimepack: ../../../../.././build.sh Mono+Libs -os Android -arch $(MONO_ARCH) -c $(MONO_CONFIG) run: - $(DOTNET) build \ + $(DOTNET) publish \ /p:TargetArchitecture=$(MONO_ARCH) \ - /p:TargetOS=Android \ /p:Configuration=$(MONO_CONFIG) \ /p:DeployAndRun=true clean: - rm -rf bin + rm -rf ../../../../../artifacts/bin/AndroidSampleApp diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs index 1da046fe937e39..c837d89d6910b4 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -12,10 +12,6 @@ public class AndroidAppBuilderTask : Task [Required] public string SourceDir { get; set; } = ""!; - public ITaskItem[]? AssemblySearchPaths { get; set; } - - public ITaskItem[]? ExtraAssemblies { get; set; } - [Required] public string MonoRuntimeHeaders { get; set; } = ""!; @@ -24,11 +20,8 @@ public class AndroidAppBuilderTask : Task /// public string MainLibraryFileName { get; set; } = ""!; - /// - /// Target arch, can be 'x86', 'x86_64', 'armeabi-v7a' or 'arm64-v8a' - /// [Required] - public string Abi { get; set; } = ""!; + public string RuntimeIdentifier { get; set; } = ""!; public string? ProjectName { get; set; } @@ -56,6 +49,8 @@ public override bool Execute() { Utils.Logger = Log; + string abi = DetermineAbi(); + var apkBuilder = new ApkBuilder(); apkBuilder.ProjectName = ProjectName; apkBuilder.OutputDir = OutputDir; @@ -65,10 +60,25 @@ public override bool Execute() apkBuilder.BuildApiLevel = BuildApiLevel; apkBuilder.BuildToolsVersion = BuildToolsVersion; apkBuilder.StripDebugSymbols = StripDebugSymbols; - apkBuilder.AssemblySearchPaths = AssemblySearchPaths?.Select(a => a.ItemSpec)?.ToArray(); - apkBuilder.ExtraAssemblies = ExtraAssemblies?.Select(a => a.ItemSpec)?.ToArray(); - (ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(SourceDir, Abi, MainLibraryFileName, MonoRuntimeHeaders); + (ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(SourceDir, abi, MainLibraryFileName, MonoRuntimeHeaders); return true; } + + private string DetermineAbi() + { + switch (RuntimeIdentifier) + { + case "android-x86": + return "x86"; + case "android-x64": + return "x86_64"; + case "android-arm": + return "armeabi-v7a"; + case "android-arm64": + return "arm64-v8a"; + default: + throw new ArgumentException(RuntimeIdentifier + " is not supported for Android"); + } + } } diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj index da39656e8c4a32..05a73a0f88f1bd 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj @@ -15,12 +15,10 @@ - - diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs index 5ae2e5a494d7bb..919cf0aa3f105d 100644 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs @@ -18,8 +18,6 @@ public class ApkBuilder public string? BuildToolsVersion { get; set; } public string? OutputDir { get; set; } public bool StripDebugSymbols { get; set; } - public string[]? AssemblySearchPaths { get; set; } - public string[]? ExtraAssemblies { get; set; } public (string apk, string packageId) BuildApk( string sourceDir, string abi, string entryPointLib, string monoRuntimeHeaders) @@ -102,41 +100,6 @@ public class ApkBuilder extensionsToIgnore.Add(".dbg"); } - var assembliesToResolve = new List(); - - if (!string.IsNullOrEmpty(entryPointLibPath)) - assembliesToResolve.Add(entryPointLibPath); - - if (ExtraAssemblies != null) - assembliesToResolve.AddRange(ExtraAssemblies); - - // try to resolve dependencies of entryPointLib + ExtraAssemblies from AssemblySearchPaths - // and copy them to sourceDir - if (AssemblySearchPaths?.Length > 0) - { - string[] resolvedDependencies = AssemblyResolver.ResolveDependencies(assembliesToResolve.ToArray(), AssemblySearchPaths, true); - foreach (string resolvedDependency in resolvedDependencies) - { - string destination = Path.Combine(sourceDir, Path.GetFileName(resolvedDependency)); - if (!File.Exists(destination)) - File.Copy(resolvedDependency, destination); - } - } - else - { - AssemblySearchPaths = new[] {OutputDir}; - } - - // copy all native libs from AssemblySearchPaths to sourceDir - // TODO: skip some if not used by the app - string[] allFiles = AssemblySearchPaths.SelectMany(p => Directory.GetFiles(p, "*", SearchOption.AllDirectories)).ToArray(); - foreach (string nativeLib in allFiles.Where(f => f.EndsWith(".a") || f.EndsWith(".so"))) - { - string destination = Path.Combine(sourceDir, Path.GetFileName(nativeLib)); - if (!File.Exists(destination)) - File.Copy(nativeLib, destination); - } - // Copy sourceDir to OutputDir/assets-tozip (ignore native files) // these files then will be zipped and copied to apk/assets/assets.zip Utils.DirectoryCopy(sourceDir, Path.Combine(OutputDir, "assets-tozip"), file => diff --git a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AssemblyResolver.cs b/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AssemblyResolver.cs deleted file mode 100644 index ef01c0fd5f6edd..00000000000000 --- a/tools-local/tasks/mobile.tasks/AndroidAppBuilder/AssemblyResolver.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -internal class AssemblyResolver : MetadataAssemblyResolver -{ - private string[] _searchPaths; - - public AssemblyResolver(string[] searchPaths) => _searchPaths = searchPaths; - - public static string[] ResolveDependencies( - string[] assembliesToResolve, string[] searchPaths, bool ignoreErrors = true) - { - var assemblies = new Dictionary(); - var mlc = new MetadataLoadContext(new AssemblyResolver(searchPaths), "System.Private.CoreLib"); - foreach (string assemblyPath in assembliesToResolve) - { - try - { - AddAssembly(mlc, mlc.LoadFromAssemblyPath(assemblyPath), assemblies, ignoreErrors); - } - catch (Exception) - { - if (!ignoreErrors) - { - throw; - } - } - } - return assemblies.Values.Select(i => i.Location).Distinct().ToArray(); - } - - private static void AddAssembly(MetadataLoadContext mlc, Assembly assembly, Dictionary assemblies, bool ignoreErrors) - { - if (assemblies.ContainsKey(assembly.GetName().Name!)) - return; - assemblies[assembly.GetName().Name!] = assembly; - foreach (AssemblyName name in assembly.GetReferencedAssemblies()) - { - try - { - Assembly refAssembly = mlc.LoadFromAssemblyName(name); - AddAssembly(mlc, refAssembly, assemblies, ignoreErrors); - } - catch (Exception) - { - if (!ignoreErrors) - { - throw; - } - } - } - } - - public override Assembly? Resolve(MetadataLoadContext context, AssemblyName assemblyName) - { - string name = assemblyName.Name!; - foreach (string dir in _searchPaths) - { - string path = Path.Combine(dir, name + ".dll"); - if (File.Exists(path)) - return context.LoadFromAssemblyPath(path); - } - return null; - } -}