From fe6c68956d1ed5ae3344108c36bca8fee21d9b2d Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 15 Jul 2021 08:23:23 +0200 Subject: [PATCH] Add support for NDK r23. Context: https://github.com/android/ndk/wiki/Changelog-r23#changelog The most important changes for Xamarin.Android: NDK r23 removes GNU Binutils and so we need to switch to using our bundled copy of them. Upstream changes: * Includes Android 12 APIs. * Updated LLVM to clang-r416183b, based on LLVM 12 development. * [Issue 1047]: Fixes crash when using ASan with the CFI unwinder. * [Issue 1096]: Includes support for [Polly]. Enable by adding `-mllvm -polly` to your cflags. * [Issue 1230]: LLVM's libunwind is now used instead of libgcc for all architectures rather than just 32-bit Arm. * [Issue 1231]: LLVM's libclang_rt.builtins is now used instead of libgcc. * [Issue 1406]: Fixes crash with Neon intrinsic. * Vulkan validation layer source and binaries are no longer shipped in the NDK. The latest are now posted directly to [GitHub](https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases). * Vulkan tools source is also removed, specifically vulkan_wrapper. It should be downloaded upstream from [GitHub](https://github.com/KhronosGroup/Vulkan-Tools). * The toolchain file (android.toolchain.cmake) is refactored to base on CMake's integrated Android support. This new toolchain file will be enabled by default for CMake 3.21 and newer. No user side change is expected. But if anything goes wrong, please file a bug and set `ANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON` to restore the legacy behavior. * When using the new behavior (when using CMake 3.21+ and not explicitly selecting the legacy toolchain), **default build flags may change**. One of the primary goals was to reduce the behavior differences between our toolchain and CMake, and CMake's default flags do not always match the legacy toolchain file. Most notably, if using `CMAKE_BUILD_TYPE=Release`, your optimization type will likely be `-O3` instead of `-O2` or `-Oz`. See [Issue 1536] for more information. * [Issue 929]: `find_library` now prefers shared libraries from the sysroot over static libraries. * [Issue 1390]: ndk-build now warns when building a static executable with the wrong API level. * [Issue 1452]: `NDK_ANALYZE=1` now sets `APP_CLANG_TIDY=true` rather than using scan-build. clang-tidy performs all the same checks by default, and scan-build was no longer working. See the bug for more details, but no user-side changes should be needed. [Issue 929]: https://github.com/android/ndk/issues/929 [Issue 1047]: https://github.com/android/ndk/issues/1047 [Issue 1096]: https://github.com/android/ndk/issues/1096 [Issue 1230]: https://github.com/android/ndk/issues/1230 [Issue 1231]: https://github.com/android/ndk/issues/1231 [Issue 1390]: https://github.com/android/ndk/issues/1390 [Issue 1406]: https://github.com/android/ndk/issues/1406 [Issue 1452]: https://github.com/android/ndk/issues/1452 [Issue 1536]: https://github.com/android/ndk/issues/1536 [Polly]: https://polly.llvm.org/ --- .../guides/building-apps/build-properties.md | 8 +- .../installers/create-installers.targets | 48 +++++----- .../xaprepare/Application/BuildInfo.cs | 5 +- .../xaprepare/Application/MonoJitRuntime.cs | 2 +- .../xaprepare/Application/Utilities.cs | 23 +++++ .../ConfigAndData/BuildAndroidPlatforms.cs | 4 +- .../xaprepare/ConfigAndData/Configurables.cs | 4 +- .../Dependencies/AndroidToolchain.cs | 2 +- .../xaprepare/Steps/Step_Android_SDK_NDK.cs | 24 +---- .../Tasks/GetAotArguments.cs | 18 ++-- .../Tasks/ResolveSdksTask.cs | 15 ++-- .../Utilities/BaseTest.cs | 65 ++++++++++++++ .../BuildReleaseArm64SimpleLegacy.apkdesc | 90 +++++++++---------- .../BuildReleaseArm64XFormsLegacy.apkdesc | 22 ++--- .../Utilities/NdkTools/WithClang.cs | 6 +- .../Utilities/NdkTools/WithClangNoBinutils.cs | 20 ++++- src/monodroid/CMakeLists.txt | 1 - .../MSBuildDeviceIntegration.csproj | 1 + 18 files changed, 226 insertions(+), 132 deletions(-) diff --git a/Documentation/guides/building-apps/build-properties.md b/Documentation/guides/building-apps/build-properties.md index 06e038b28df..a542aa71057 100644 --- a/Documentation/guides/building-apps/build-properties.md +++ b/Documentation/guides/building-apps/build-properties.md @@ -129,14 +129,14 @@ Added in Xamarin.Android 6.1. A path to a directory containing the Android [binutils][binutils] such as `ld`, the native linker, -and `as`, the native assembler. These tools are part of the Android -NDK and are also included in the Xamarin.Android installation. +and `as`, the native assembler. These tools are included in the +Xamarin.Android installation. -The default value is `$(MonoAndroidBinDirectory)\ndk\`. +The default value is `$(MonoAndroidBinDirectory)\binutils\`. Added in Xamarin.Android 10.0. -[binutils]: https://android.googlesource.com/toolchain/binutils/ +[binutils]: https://github.com/xamarin/xamarin-android-binutils/ ## AndroidBoundExceptionType diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index d05347d4e97..a2eb4e4b426 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -310,18 +310,18 @@ <_MSBuildFilesWin Include="$(MSBuildSrcDir)\lib64\libZipSharpNative.pdb" /> <_MSBuildFilesWin Include="$(MSBuildSrcDir)\proguard\bin\proguard.bat" /> <_MSBuildFilesWin Include="$(MSBuildSrcDir)\aapt2.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\aarch64-linux-android-as.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\aarch64-linux-android-ld.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\aarch64-linux-android-strip.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\arm-linux-androideabi-as.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\arm-linux-androideabi-ld.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\arm-linux-androideabi-strip.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\i686-linux-android-as.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\i686-linux-android-ld.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\i686-linux-android-strip.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\x86_64-linux-android-as.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\x86_64-linux-android-ld.exe" /> - <_MSBuildFilesWin Include="$(MSBuildSrcDir)\ndk\x86_64-linux-android-strip.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\aarch64-linux-android-as.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\aarch64-linux-android-ld.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\aarch64-linux-android-strip.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\arm-linux-androideabi-as.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\arm-linux-androideabi-ld.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\arm-linux-androideabi-strip.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\i686-linux-android-as.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\i686-linux-android-ld.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\i686-linux-android-strip.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\x86_64-linux-android-as.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\x86_64-linux-android-ld.exe" /> + <_MSBuildFilesWin Include="$(MSBuildSrcDir)\binutils\x86_64-linux-android-strip.exe" /> <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libmono-android.debug.dll" Condition=" '$(HostOS)' != 'Windows' " /> <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libmono-android.release.dll" Condition=" '$(HostOS)' != 'Windows' " /> <_MSBuildLibHostFilesWin Include="$(MSBuildSrcDir)\lib\host-mxe-Win64\libMonoPosixHelper.dll" /> @@ -341,18 +341,18 @@ - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\aarch64-linux-android-as" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\aarch64-linux-android-ld" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\aarch64-linux-android-strip" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\arm-linux-androideabi-as" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\arm-linux-androideabi-ld" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\arm-linux-androideabi-strip" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\i686-linux-android-as" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\i686-linux-android-ld" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\i686-linux-android-strip" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\x86_64-linux-android-as" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\x86_64-linux-android-ld" /> - <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\ndk\x86_64-linux-android-strip" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\aarch64-linux-android-as" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\aarch64-linux-android-ld" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\aarch64-linux-android-strip" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\arm-linux-androideabi-as" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\arm-linux-androideabi-ld" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\arm-linux-androideabi-strip" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\i686-linux-android-as" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\i686-linux-android-ld" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\i686-linux-android-strip" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\x86_64-linux-android-as" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\x86_64-linux-android-ld" /> + <_MSBuildFilesUnixSignAndHarden Include="$(MSBuildSrcDir)\$(HostOS)\binutils\x86_64-linux-android-strip" /> <_MSBuildFilesUnix Include="$(MSBuildSrcDir)\$(HostOS)\illinkanalyzer" Permission="755" /> <_MSBuildFilesUnix Include="$(MSBuildSrcDir)\$(HostOS)\jit-times" Permission="755" /> <_MSBuildFilesUnix Include="$(MSBuildSrcDir)\$(HostOS)\aprofutil" ExcludeFromAndroidNETSdk="true" /> diff --git a/build-tools/xaprepare/xaprepare/Application/BuildInfo.cs b/build-tools/xaprepare/xaprepare/Application/BuildInfo.cs index 69b8aed2e48..67413577b9b 100644 --- a/build-tools/xaprepare/xaprepare/Application/BuildInfo.cs +++ b/build-tools/xaprepare/xaprepare/Application/BuildInfo.cs @@ -18,6 +18,7 @@ partial class BuildInfo : AppObject public string NDKVersionMajor { get; private set; } = String.Empty; public string NDKVersionMinor { get; private set; } = String.Empty; public string NDKVersionMicro { get; private set; } = String.Empty; + public string NDKVersionTag { get; private set; } = String.Empty; public string NDKMinimumApiAvailable { get; private set; } = String.Empty; public string VersionHash { get; private set; } = String.Empty; @@ -59,8 +60,7 @@ public bool GatherNDKInfo (Context context) string rev = parts [1].Trim (); NDKRevision = rev; - Version ver; - if (!Version.TryParse (rev, out ver)) { + if (!Utilities.ParseAndroidPkgRevision (rev, out Version? ver, out string tag)) { Log.ErrorLine ($"Unable to parse NDK revision '{rev}' as a valid version string"); return false; } @@ -68,6 +68,7 @@ public bool GatherNDKInfo (Context context) NDKVersionMajor = ver.Major.ToString (); NDKVersionMinor = ver.Minor.ToString (); NDKVersionMicro = ver.Build.ToString (); + NDKVersionTag = tag; break; } diff --git a/build-tools/xaprepare/xaprepare/Application/MonoJitRuntime.cs b/build-tools/xaprepare/xaprepare/Application/MonoJitRuntime.cs index 31d435f4bc6..4838e62647e 100644 --- a/build-tools/xaprepare/xaprepare/Application/MonoJitRuntime.cs +++ b/build-tools/xaprepare/xaprepare/Application/MonoJitRuntime.cs @@ -24,7 +24,7 @@ public override void Init (Context context) OutputMonoBtlsFilename = Configurables.Defaults.MonoRuntimeOutputMonoBtlsFilename; OutputMonoPosixHelperFilename = Configurables.Defaults.MonoRuntimeOutputMonoPosixHelperFilename; OutputProfilerFilename = Configurables.Defaults.MonoRuntimeOutputProfilerFilename; - Strip = Path.Combine (Configurables.Paths.AndroidToolchainBinDirectory, $"{Configurables.Defaults.AndroidToolchainPrefixes [Name]}-strip"); + Strip = Path.Combine (Configurables.Paths.AndroidToolchainBinDirectory, "llvm-strip"); } } } diff --git a/build-tools/xaprepare/xaprepare/Application/Utilities.cs b/build-tools/xaprepare/xaprepare/Application/Utilities.cs index d3573903d41..75ee6edec7f 100644 --- a/build-tools/xaprepare/xaprepare/Application/Utilities.cs +++ b/build-tools/xaprepare/xaprepare/Application/Utilities.cs @@ -29,6 +29,29 @@ static partial class Utilities public static readonly Encoding UTF8NoBOM = new UTF8Encoding (false); + public static bool ParseAndroidPkgRevision (string? v, out Version? version, out string? tag) + { + string? ver = v?.Trim (); + version = null; + tag = null; + if (String.IsNullOrEmpty (ver)) + return false; + + if (ver!.IndexOf ('.') < 0) + ver = $"{ver}.0"; + + int tagIdx = ver.IndexOf ('-'); + if (tagIdx >= 0) { + tag = ver.Substring (tagIdx + 1); + ver = ver.Substring (0, tagIdx - 1); + } + + if (Version.TryParse (ver, out version)) + return true; + + return false; + } + public static bool AbiChoiceChanged (Context context) { string cacheFile = Configurables.Paths.MonoRuntimesEnabledAbisCachePath; diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs index 8a0e0b5356c..1e5e2545f1b 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs @@ -5,8 +5,8 @@ namespace Xamarin.Android.Prepare { class BuildAndroidPlatforms { - public const string AndroidNdkVersion = "22b"; - public const string AndroidNdkPkgRevision = "22.1.7171670"; + public const string AndroidNdkVersion = "23"; + public const string AndroidNdkPkgRevision = "23.0.7599858"; public static readonly List AllPlatforms = new List { new AndroidPlatform (apiName: "", apiLevel: 1, platformID: "1"), diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs index 148d4372e04..10081f48e40 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs @@ -398,8 +398,8 @@ public static partial class Paths public static string AndroidToolchainRootDirectory => GetCachedPath (ref androidToolchainRootDirectory, () => Path.Combine (AndroidNdkDirectory, "toolchains", "llvm", "prebuilt", NdkToolchainOSTag)); public static string AndroidToolchainBinDirectory => GetCachedPath (ref androidToolchainBinDirectory, () => Path.Combine (AndroidToolchainRootDirectory, "bin")); public static string AndroidToolchainSysrootLibDirectory => GetCachedPath (ref androidToolchainSysrootLibDirectory, () => Path.Combine (AndroidToolchainRootDirectory, "sysroot", "usr", "lib")); - public static string WindowsBinutilsInstallDir => GetCachedPath (ref windowsBinutilsInstallDir, () => Path.Combine (InstallMSBuildDir, "ndk")); - public static string HostBinutilsInstallDir => GetCachedPath (ref hostBinutilsInstallDir, () => Path.Combine (InstallMSBuildDir, ctx.Properties.GetRequiredValue (KnownProperties.HostOS), "ndk")); + public static string WindowsBinutilsInstallDir => GetCachedPath (ref windowsBinutilsInstallDir, () => Path.Combine (InstallMSBuildDir, "binutils")); + public static string HostBinutilsInstallDir => GetCachedPath (ref hostBinutilsInstallDir, () => Path.Combine (InstallMSBuildDir, ctx.Properties.GetRequiredValue (KnownProperties.HostOS), "binutils")); public static string BinutilsCacheDir => ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory); public static string AndroidBuildToolsCacheDir => ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory); diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs index a65fc65373b..b904ebef583 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs @@ -69,7 +69,7 @@ public AndroidToolchain () new AndroidToolchainComponent ("docs-24_r01", destDir: "docs", pkgRevision: "1", dependencyType: AndroidToolchainComponentType.BuildDependency), new AndroidToolchainComponent ("android_m2repository_r47", destDir: Path.Combine ("extras", "android", "m2repository"), pkgRevision: "47.0.0", dependencyType: AndroidToolchainComponentType.BuildDependency), new AndroidToolchainComponent ($"x86_64-29_r07-{osTag}", destDir: Path.Combine ("system-images", "android-29", "default", "x86_64"), relativeUrl: new Uri ("sys-img/android/", UriKind.Relative), pkgRevision: "7", dependencyType: AndroidToolchainComponentType.EmulatorDependency), - new AndroidToolchainComponent ($"android-ndk-r{AndroidNdkVersion}-{osTag}-x86_64", destDir: AndroidNdkDirectory, pkgRevision: AndroidPkgRevision), + new AndroidToolchainComponent ($"android-ndk-r{AndroidNdkVersion}-{osTag}", destDir: AndroidNdkDirectory, pkgRevision: AndroidPkgRevision), new AndroidToolchainComponent ($"{XABuildToolsPackagePrefix}build-tools_r{XABuildToolsVersion}-{altOsTag}", destDir: Path.Combine ("build-tools", XABuildToolsFolder), isMultiVersion: true), new AndroidToolchainComponent ($"commandlinetools-{cltOsTag}-{CommandLineToolsVersion}", destDir: Path.Combine ("cmdline-tools", CommandLineToolsFolder), isMultiVersion: true), diff --git a/build-tools/xaprepare/xaprepare/Steps/Step_Android_SDK_NDK.cs b/build-tools/xaprepare/xaprepare/Steps/Step_Android_SDK_NDK.cs index 3f54716ab0e..51b54e9e2b3 100644 --- a/build-tools/xaprepare/xaprepare/Steps/Step_Android_SDK_NDK.cs +++ b/build-tools/xaprepare/xaprepare/Steps/Step_Android_SDK_NDK.cs @@ -307,37 +307,21 @@ bool IsInstalled (AndroidToolchainComponent component, string path, out bool mis return false; } - if (!ParseVersion (pkgRevision, out Version? pkgVer) || pkgVer == null) { + if (!Utilities.ParseAndroidPkgRevision (pkgRevision, out Version? pkgVer, out string pkgTag) || pkgVer == null) { Log.DebugLine ($"Failed to parse a valid version from Pkg.Revision ({pkgRevision}) for component '{component.Name}'. Component will be reinstalled."); return false; } - if (!ParseVersion (component.PkgRevision, out Version? expectedPkgVer) || expectedPkgVer == null) + if (!Utilities.ParseAndroidPkgRevision (component.PkgRevision, out Version? expectedPkgVer, out string expectedTag) || expectedPkgVer == null) throw new InvalidOperationException ($"Invalid expected package version for component '{component.Name}': {component.PkgRevision}"); - bool equal = pkgVer == expectedPkgVer; + bool equal = (pkgVer == expectedPkgVer) && (pkgTag == expectedTag); if (!equal) - Log.DebugLine ($"Installed version of '{component.Name}' ({pkgVer}) is different than the required one ({expectedPkgVer})"); + Log.DebugLine ($"Installed version of '{component.Name}' ({pkgRevision}) is different than the required one ({component.PkgRevision})"); return equal; } - bool ParseVersion (string? v, out Version? version) - { - string? ver = v?.Trim (); - version = null; - if (String.IsNullOrEmpty (ver)) - return false; - - if (ver!.IndexOf ('.') < 0) - ver = $"{ver}.0"; - - if (Version.TryParse (ver, out version)) - return true; - - return false; - } - bool IsNdk (AndroidToolchainComponent component) { return component.Name.StartsWith ("android-ndk", StringComparison.OrdinalIgnoreCase); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs index 9e15a17aac1..01149da32da 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/GetAotArguments.cs @@ -312,14 +312,20 @@ string GetLdFlags(NdkTools ndk, AndroidTargetArch arch, int level, string toolPr } string toolchainLibDir; - if (ndk.UsesClang) - toolchainLibDir = GetNdkToolchainLibraryDir (ndk, toolchainPath, arch); - else + if (ndk.UsesClang) { + if (ndk.NoBinutils) { + toolchainLibDir = String.Empty; + } else { + toolchainLibDir = GetNdkToolchainLibraryDir (ndk, toolchainPath, arch); + } + } else toolchainLibDir = GetNdkToolchainLibraryDir (ndk, toolchainPath); var libs = new List (); if (ndk.UsesClang) { - libs.Add ($"-L{toolchainLibDir.TrimEnd ('\\')}"); + if (!String.IsNullOrEmpty (toolchainLibDir)) { + libs.Add ($"-L{toolchainLibDir.TrimEnd ('\\')}"); + } libs.Add ($"-L{androidLibPath.TrimEnd ('\\')}"); if (arch == AndroidTargetArch.Arm) { @@ -329,7 +335,9 @@ string GetLdFlags(NdkTools ndk, AndroidTargetArch arch, int level, string toolPr } } - libs.Add (Path.Combine (toolchainLibDir, "libgcc.a")); + if (!String.IsNullOrEmpty (toolchainLibDir)) { + libs.Add (Path.Combine (toolchainLibDir, "libgcc.a")); + } libs.Add (Path.Combine (androidLibPath, "libc.so")); libs.Add (Path.Combine (androidLibPath, "libm.so")); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs index d3096519471..261f9f9f175 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs @@ -1,23 +1,23 @@ -// +// // ResolveSdksTask.cs -// +// // Author: // Michael Hutchinson // Jonathan Pryor -// +// // Copyright (c) 2010 Novell, Inc. // Copyright (c) 2013 Xamarin Inc. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -85,7 +85,7 @@ public override bool RunTask () } MonoAndroidBinPath = MonoAndroidHelper.GetOSBinPath () + Path.DirectorySeparatorChar; MonoAndroidLibPath = MonoAndroidHelper.GetOSLibPath () + Path.DirectorySeparatorChar; - AndroidBinUtilsPath = MonoAndroidBinPath + "ndk" + Path.DirectorySeparatorChar; + AndroidBinUtilsPath = MonoAndroidBinPath + "binutils" + Path.DirectorySeparatorChar; var minVersion = Version.Parse (MinimumSupportedJavaVersion); var maxVersion = Version.Parse (LatestSupportedJavaVersion); @@ -139,4 +139,3 @@ public override bool RunTask () } } } - diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs index 980d0918fca..4138dcb4846 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs @@ -5,9 +5,11 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Xml.Linq; +using Xamarin.Android.Build; using Xamarin.Android.Tasks; using Xamarin.ProjectTools; using Microsoft.Android.Build.Tasks; @@ -22,6 +24,8 @@ public class BaseTest [SetUpFixture] public class SetUp { + const string BinutilsSubdir = "binutils"; + public static string DeviceAbi { get; private set; @@ -75,6 +79,67 @@ public void BeforeAllTests () } catch (Exception ex) { Console.Error.WriteLine ("Failed to determine whether there is Android target emulator or not: " + ex); } + + CreateBinutilsSymlink (); + } + + void CreateBinutilsSymlink () + { + string hostNdkDir = GetHostBinutilsDir (); + string xabtDir = Path.GetDirectoryName (typeof (BuildApk).Assembly.Location); + string symlinkDir = Path.Combine (xabtDir, hostNdkDir); + + // If directory exists then it's either a valid symlink or a real dir, don't touch anything in such instance + if (Directory.Exists (symlinkDir)) { + if (!SymbolicLink.IsPathSymlink (symlinkDir)) { + Console.Error.WriteLine ($"Warning: a directory exists where a symbolic link was expected, {symlinkDir}"); + } + return; + } + + // If a file exists and is a symlink, then it's probably a dangling link - recreate it + if (File.Exists (symlinkDir)) { + if (!SymbolicLink.IsPathSymlink (symlinkDir)) { + throw new InvalidOperationException ($"File named '{symlinkDir}' exists where a symbolic link to a directory should be."); + } + + File.Delete (symlinkDir); + } + + // We first try the in-tree location... + string binutilsDirFullPath = Path.Combine (XABuildPaths.PrefixDirectory, "lib", "xamarin.android", "xbuild", "Xamarin", "Android", hostNdkDir); + if (!Directory.Exists (binutilsDirFullPath)) { + // ...since it failed, we'll try to find the system location + binutilsDirFullPath = Path.Combine (TestEnvironment.MonoAndroidToolsDirectory, hostNdkDir); + if (!Directory.Exists (binutilsDirFullPath)) { + throw new InvalidOperationException ($"Host NDK directory does not exist, {binutilsDirFullPath}"); + } + } + + if (!SymbolicLink.Create (symlinkDir, binutilsDirFullPath)) { + throw new InvalidOperationException ($"Failed to create a symbolic link from '{symlinkDir}' to '{binutilsDirFullPath}'"); + } + + if (!Directory.Exists (symlinkDir)) { + throw new InvalidOperationException ($"Symbolic link '{symlinkDir}' created but it doesn't appear to point to '{binutilsDirFullPath}"); + } + } + + string GetHostBinutilsDir () + { + if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) { + return BinutilsSubdir; + } + + if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) { + return Path.Combine ("Linux", BinutilsSubdir); + } + + if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) { + return Path.Combine ("Darwin", BinutilsSubdir); + } + + throw new InvalidOperationException ($"Unsupported OS"); } int GetSdkVersion () diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc index aef4ce023bd..eee08fac943 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleLegacy.apkdesc @@ -4,75 +4,75 @@ "AndroidManifest.xml": { "Size": 2584 }, - "res/drawable-mdpi-v4/icon.png": { - "Size": 2200 - }, - "res/drawable-hdpi-v4/icon.png": { - "Size": 4762 - }, - "res/drawable-xhdpi-v4/icon.png": { - "Size": 7462 - }, - "res/drawable-xxhdpi-v4/icon.png": { - "Size": 13092 - }, - "res/drawable-xxxhdpi-v4/icon.png": { - "Size": 20118 - }, - "res/layout/main.xml": { - "Size": 544 - }, - "resources.arsc": { - "Size": 1724 - }, - "classes.dex": { - "Size": 316700 - }, - "assemblies/UnnamedProject.dll": { - "Size": 2851 - }, "assemblies/Java.Interop.dll": { - "Size": 67719 + "Size": 67758 }, "assemblies/Mono.Android.dll": { - "Size": 246165 + "Size": 246233 }, "assemblies/mscorlib.dll": { - "Size": 769192 + "Size": 769324 }, "assemblies/System.Core.dll": { - "Size": 28168 + "Size": 28186 }, "assemblies/System.dll": { - "Size": 9163 + "Size": 9171 }, - "lib/arm64-v8a/libxamarin-app.so": { - "Size": 19696 - }, - "lib/arm64-v8a/libmonodroid.so": { - "Size": 268792 + "assemblies/UnnamedProject.dll": { + "Size": 2862 }, - "lib/arm64-v8a/libxa-internal-api.so": { - "Size": 65312 + "classes.dex": { + "Size": 316760 }, "lib/arm64-v8a/libmono-btls-shared.so": { "Size": 1613872 }, - "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 4050176 - }, "lib/arm64-v8a/libmono-native.so": { "Size": 707024 }, - "META-INF/ANDROIDD.SF": { - "Size": 2225 + "lib/arm64-v8a/libmonodroid.so": { + "Size": 281352 + }, + "lib/arm64-v8a/libmonosgen-2.0.so": { + "Size": 4037584 + }, + "lib/arm64-v8a/libxa-internal-api.so": { + "Size": 65624 + }, + "lib/arm64-v8a/libxamarin-app.so": { + "Size": 19696 }, "META-INF/ANDROIDD.RSA": { "Size": 1213 }, + "META-INF/ANDROIDD.SF": { + "Size": 2225 + }, "META-INF/MANIFEST.MF": { "Size": 2098 + }, + "res/drawable-hdpi-v4/icon.png": { + "Size": 4762 + }, + "res/drawable-mdpi-v4/icon.png": { + "Size": 2200 + }, + "res/drawable-xhdpi-v4/icon.png": { + "Size": 7462 + }, + "res/drawable-xxhdpi-v4/icon.png": { + "Size": 13092 + }, + "res/drawable-xxxhdpi-v4/icon.png": { + "Size": 20118 + }, + "res/layout/main.xml": { + "Size": 544 + }, + "resources.arsc": { + "Size": 1724 } }, - "PackageSize": 3962580 + "PackageSize": 3970772 } \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc index 21a794dffef..b1a25a74093 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64XFormsLegacy.apkdesc @@ -8,13 +8,13 @@ "Size": 7200 }, "assemblies/Java.Interop.dll": { - "Size": 68711 + "Size": 68710 }, "assemblies/Mono.Android.dll": { - "Size": 557367 + "Size": 557342 }, "assemblies/Mono.Security.dll": { - "Size": 68420 + "Size": 68422 }, "assemblies/mscorlib.dll": { "Size": 915407 @@ -44,7 +44,7 @@ "Size": 395644 }, "assemblies/UnnamedProject.dll": { - "Size": 116882 + "Size": 116876 }, "assemblies/Xamarin.AndroidX.Activity.dll": { "Size": 7686 @@ -53,7 +53,7 @@ "Size": 6635 }, "assemblies/Xamarin.AndroidX.AppCompat.dll": { - "Size": 125317 + "Size": 125318 }, "assemblies/Xamarin.AndroidX.CardView.dll": { "Size": 7354 @@ -77,10 +77,10 @@ "Size": 7050 }, "assemblies/Xamarin.AndroidX.Lifecycle.LiveData.Core.dll": { - "Size": 7179 + "Size": 7178 }, "assemblies/Xamarin.AndroidX.Lifecycle.ViewModel.dll": { - "Size": 4859 + "Size": 4860 }, "assemblies/Xamarin.AndroidX.Loader.dll": { "Size": 13574 @@ -113,7 +113,7 @@ "Size": 43488 }, "classes.dex": { - "Size": 3455228 + "Size": 3455168 }, "lib/arm64-v8a/libmono-btls-shared.so": { "Size": 1613872 @@ -122,16 +122,16 @@ "Size": 707024 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 283112 + "Size": 281352 }, "lib/arm64-v8a/libmonosgen-2.0.so": { "Size": 4037584 }, "lib/arm64-v8a/libxa-internal-api.so": { - "Size": 65496 + "Size": 65624 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 142104 + "Size": 140560 }, "META-INF/android.support.design_material.version": { "Size": 12 diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClang.cs b/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClang.cs index 08c81ccab26..0c49e88361e 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClang.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClang.cs @@ -62,7 +62,7 @@ public override string GetToolPath (NdkToolKind kind, AndroidTargetArch arch, in public override string GetToolPath (string name, AndroidTargetArch arch, int apiLevel) { - return MakeToolPath ($"{GetArchTriple (arch)}-{name}"); + return MakeToolPath ($"{GetArchTriple (arch)}-{name}", mustExist: false); } public override string GetClangDeviceLibraryPath () @@ -99,11 +99,11 @@ protected string GetCompilerTriple (AndroidTargetArch arch) return arch == AndroidTargetArch.Arm ? "armv7a-linux-androideabi" : GetArchTriple (arch); } - protected string MakeToolPath (string toolName) + protected string MakeToolPath (string toolName, bool mustExist = true) { string toolPath = Path.Combine (GetToolchainDir (), "bin", toolName); - return GetExecutablePath (toolPath, mustExist: true)!; + return GetExecutablePath (toolPath, mustExist) ?? String.Empty; } protected string GetToolchainDir () diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClangNoBinutils.cs b/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClangNoBinutils.cs index c4b0bb98607..849f8ed9fca 100644 --- a/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClangNoBinutils.cs +++ b/src/Xamarin.Android.Build.Tasks/Utilities/NdkTools/WithClangNoBinutils.cs @@ -14,8 +14,6 @@ public NdkToolsWithClangNoBinutils (string androidNdkPath, NdkVersion version, T { NdkToolNames[NdkToolKind.Linker] = "ld"; NoBinutils = true; - - throw new NotSupportedException ($"NDK {Version} is not supported by this version of Xamarin.Android"); } public override string GetToolPath (NdkToolKind kind, AndroidTargetArch arch, int apiLevel) @@ -31,12 +29,28 @@ public override string GetToolPath (NdkToolKind kind, AndroidTargetArch arch, in } } + public override string GetToolPath (string name, AndroidTargetArch arch, int apiLevel) + { + // The only triple-prefixed binaries in NDK r23+ are the compilers, and these are + // handled by the other GetToolPath overload. + + // Some tools might not have any prefix, let's check that first + string toolPath = MakeToolPath (name, mustExist: false); + if (!String.IsNullOrEmpty (toolPath)) { + return toolPath; + } + + // Otherwise, they might be prefixed with llvm- + return MakeToolPath ($"llvm-{name}"); + } + string GetEmbeddedToolPath (NdkToolKind kind, AndroidTargetArch arch) { string toolName = GetToolName (kind); string triple = GetArchTriple (arch); + string binutilsDir = Path.Combine (MonoAndroidHelper.GetOSBinPath (), "binutils"); - return $"[TODO]/{triple}-{toolName}"; + return GetExecutablePath (Path.Combine (binutilsDir, $"{triple}-{toolName}"), mustExist: true); } } } diff --git a/src/monodroid/CMakeLists.txt b/src/monodroid/CMakeLists.txt index df77ad2489a..26502caa72b 100644 --- a/src/monodroid/CMakeLists.txt +++ b/src/monodroid/CMakeLists.txt @@ -279,7 +279,6 @@ endif() if(ANDROID) add_compile_definitions(HAVE_LZ4) add_compile_definitions(PLATFORM_ANDROID) - add_compile_definitions(__ANDROID_API__=${ANDROID_NATIVE_API_LEVEL}) if(ANDROID_ABI MATCHES "^(arm64-v8a|x86_64)") add_compile_definitions(ANDROID64) diff --git a/tests/MSBuildDeviceIntegration/MSBuildDeviceIntegration.csproj b/tests/MSBuildDeviceIntegration/MSBuildDeviceIntegration.csproj index 9af5f8da79e..44ea1bb01cb 100644 --- a/tests/MSBuildDeviceIntegration/MSBuildDeviceIntegration.csproj +++ b/tests/MSBuildDeviceIntegration/MSBuildDeviceIntegration.csproj @@ -17,6 +17,7 @@ Utilities\%(FileName).cs +