diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs index 6c66bdd696d..261f9b506a5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aot.cs @@ -44,6 +44,9 @@ public class Aot : AsyncTask [Required] public string SdkBinDirectory { get; set; } + [Required] + public ITaskItem ManifestFile { get; set; } + [Required] public ITaskItem[] ResolvedAssemblies { get; set; } @@ -168,9 +171,22 @@ static bool ValidateAotConfiguration (TaskLoggingHelper log, AndroidTargetArch a return true; } - static int GetNdkApiLevel(string androidNdkPath, string androidApiLevel, AndroidTargetArch arch) + int GetNdkApiLevel(string androidNdkPath, string androidApiLevel, AndroidTargetArch arch) { - int level = int.Parse(androidApiLevel); + var manifest = AndroidAppManifest.Load (ManifestFile.ItemSpec); + + int level; + if (manifest.MinSdkVersion.HasValue) { + level = manifest.MinSdkVersion.Value; + } + else if (int.TryParse (androidApiLevel, out level)) { + // level already set + } + else { + // Probably not ideal! + level = AndroidVersion.MaxApiLevel; + } + // Some Android API levels do not exist on the NDK level. Workaround this my mapping them to the // most appropriate API level that does exist. if (level == 6 || level == 7) level = 5; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 79eeb7eac32..5fbc8f2f8c3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Xml.Linq; using Microsoft.Build.Framework; using NUnit.Framework; @@ -209,12 +210,29 @@ public void BuildAotApplication (string supportedAbis, bool enableLLVM, bool exp proj.SetProperty (KnownProperties.TargetFrameworkVersion, "v5.1"); proj.SetProperty (KnownProperties.AndroidSupportedAbis, supportedAbis); proj.SetProperty ("EnableLLVM", enableLLVM.ToString ()); + if (enableLLVM) { + // Set //uses-sdk/@android:minSdkVersion so that LLVM uses the right libc.so + proj.AndroidManifest = $@" + + + + +"; + } using (var b = CreateApkBuilder (path)) { b.ThrowOnBuildFailure = false; b.Verbosity = LoggerVerbosity.Diagnostic; Assert.AreEqual (expectedResult, b.Build (proj), "Build should have {0}.", expectedResult ? "succeeded" : "failed"); if (!expectedResult) return; + if (enableLLVM) { + // LLVM passes a direct path to libc.so, and we need to use the libc.so + // which corresponds to the *minimum* SDK version specified in AndroidManifest.xml + // Since we overrode minSdkVersion=10, that means we should use libc.so from android-9. + var rightLibc = new Regex (@"^\s*\[AOT\].*cross-.*--llvm.*,ld-flags=.*android-9.arch-.*.usr.lib.libc\.so", RegexOptions.Multiline); + var m = rightLibc.Match (b.LastBuildOutput); + Assert.IsTrue (m.Success, "AOT+LLVM should use libc.so from minSdkVersion!"); + } foreach (var abi in supportedAbis.Split (new char [] { ';' })) { var libapp = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "bundles", abi, "libmonodroid_bundle_app.so"); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index b2eeafd4e0e..36eabbf3d07 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -2145,6 +2145,7 @@ because xbuild doesn't support framework reference assemblies. AndroidNdkDirectory="$(_AndroidNdkDirectory)" AndroidApiLevel="$(_AndroidApiLevel)" SdkBinDirectory="$(MonoAndroidBinDirectory)" + ManifestFile="$(IntermediateOutputPath)android\AndroidManifest.xml" SupportedAbis="$(_BuildTargetAbis)" AndroidSequencePointsMode="$(_SequencePointsMode)" AotAdditionalArguments="$(AndroidAotAdditionalArguments)"