diff --git a/src/Microsoft.Android.Build.BaseTasks/AndroidRidAbiHelper.cs b/src/Microsoft.Android.Build.BaseTasks/AndroidRidAbiHelper.cs index 229d069..8e6cce4 100644 --- a/src/Microsoft.Android.Build.BaseTasks/AndroidRidAbiHelper.cs +++ b/src/Microsoft.Android.Build.BaseTasks/AndroidRidAbiHelper.cs @@ -19,13 +19,27 @@ public static class AndroidRidAbiHelper public static string GetNativeLibraryAbi (string lib) { // The topmost directory the .so file is contained within - var dir = Path.GetFileName (Path.GetDirectoryName (lib)).ToLowerInvariant (); - if (dir.StartsWith ("interpreter-", StringComparison.Ordinal)) { - dir = dir.Substring (12); + var dir = Directory.GetParent (lib); + var dirName = dir.Name.ToLowerInvariant (); + if (dirName.StartsWith ("interpreter-", StringComparison.Ordinal)) { + dirName = dirName.Substring ("interpreter-".Length); } - if (ValidAbis.Contains (dir)) { - return dir; + if (ValidAbis.Contains (dirName)) { + return dirName; } + + // Look for a directory with a RID as a name, such as: + // android-arm64/libfoo.so + var abi = RuntimeIdentifierToAbi (dirName); + if (!string.IsNullOrEmpty (abi)) + return abi; + + // Try one directory higher, such as: + // packages/sqlitepclraw.lib.e_sqlite3.android/1.1.11/runtimes/android-arm64/native/libe_sqlite3.so + abi = RuntimeIdentifierToAbi (dir.Parent.Name.ToLowerInvariant ()); + if (!string.IsNullOrEmpty (abi)) + return abi; + return null; } @@ -41,8 +55,7 @@ public static string GetNativeLibraryAbi (ITaskItem lib) // First, try nominal "Link" path. var link = lib.GetMetadata ("Link"); if (!string.IsNullOrWhiteSpace (link)) { - var linkdirs = link.ToLowerInvariant ().Split ('/', '\\'); - lib_abi = ValidAbis.Where (p => linkdirs.Contains (p)).FirstOrDefault (); + lib_abi = GetNativeLibraryAbi (link); } // Check for a RuntimeIdentifier diff --git a/tests/Microsoft.Android.Build.BaseTasks-Tests/AndroidRidAbiHelperTests.cs b/tests/Microsoft.Android.Build.BaseTasks-Tests/AndroidRidAbiHelperTests.cs new file mode 100644 index 0000000..bb241cb --- /dev/null +++ b/tests/Microsoft.Android.Build.BaseTasks-Tests/AndroidRidAbiHelperTests.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using Microsoft.Android.Build.Tasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using NUnit.Framework; + +namespace Microsoft.Android.Build.BaseTasks.Tests +{ + [TestFixture] + public class AndroidRidAbiHelperTests + { + static object [] StringValueSource = new object [] { + new[] { + /* input */ "armeabi-v7a/libfoo.so", + /* expected */ "armeabi-v7a" + }, + new[] { + /* input */ "arm64-v8a/libfoo.so", + /* expected */ "arm64-v8a" + }, + new[] { + /* input */ "x86/libfoo.so", + /* expected */ "x86" + }, + new[] { + /* input */ "x86_64/libfoo.so", + /* expected */ "x86_64" + }, + new[] { + /* input */ "android-arm/libfoo.so", + /* expected */ "armeabi-v7a" + }, + new[] { + /* input */ "android-arm64/libfoo.so", + /* expected */ "arm64-v8a" + }, + new[] { + /* input */ "android-x86/libfoo.so", + /* expected */ "x86" + }, + new[] { + /* input */ "android-x64/libfoo.so", + /* expected */ "x86_64" + }, + new[] { + /* input */ "android-arm/native/libfoo.so", + /* expected */ "armeabi-v7a" + }, + new[] { + /* input */ "android-arm64/native/libfoo.so", + /* expected */ "arm64-v8a" + }, + new[] { + /* input */ "android-x86/native/libfoo.so", + /* expected */ "x86" + }, + new[] { + /* input */ "android-x64/native/libfoo.so", + /* expected */ "x86_64" + }, + new[] { + /* input */ "android.21-x64/native/libfoo.so", + /* expected */ "x86_64" + }, + new[] { + /* input */ "packages/sqlitepclraw.lib.e_sqlite3.android/1.1.11/runtimes/android-arm64/native/libe_sqlite3.so", + /* expected */ "arm64-v8a" + } + }; + + [Test] + [TestCaseSource (nameof (StringValueSource))] + public void StringValue (string input, string expected) + { + Assert.AreEqual (expected, AndroidRidAbiHelper.GetNativeLibraryAbi (input)); + } + + static object [] ITaskItemValueSource = new object [] { + new object [] { + /* input */ + new TaskItem("armeabi-v7a/libfoo.so"), + /* expected */ + "armeabi-v7a" + }, + new object [] { + /* input */ + new TaskItem("libabi.so", new Dictionary { + { "Abi", "armeabi-v7a" } + }), + /* expected */ + "armeabi-v7a" + }, + new object [] { + /* input */ + new TaskItem("librid.so", new Dictionary { + { "RuntimeIdentifier", "android-arm" } + }), + /* expected */ + "armeabi-v7a" + }, + new object [] { + /* input */ + new TaskItem("liblink.so", new Dictionary { + { "Link", "armeabi-v7a/libfoo.so" } + }), + /* expected */ + "armeabi-v7a" + }, + new object [] { + /* input */ + new TaskItem("liblink.so", new Dictionary { + { "Link", "x86/libfoo.so" } + }), + /* expected */ + "x86" + }, + new object [] { + /* input */ + new TaskItem("liblink.so", new Dictionary { + { "Link", "x86_64/libfoo.so" } + }), + /* expected */ + "x86_64" + }, + new object [] { + /* input */ + new TaskItem("libridlink.so", new Dictionary { + { "Link", "android-arm/libfoo.so" } + }), + /* expected */ + "armeabi-v7a" + }, + }; + + [Test] + [TestCaseSource (nameof (ITaskItemValueSource))] + public void ITaskItemValue (ITaskItem input, string expected) + { + Assert.AreEqual (expected, AndroidRidAbiHelper.GetNativeLibraryAbi (input)); + } + } +}