Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xamarin.Android can't find NDK bundle include folder when using latest NDK #5499

Closed
AmrAlSayed0 opened this issue Jan 14, 2021 · 12 comments
Closed
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.

Comments

@AmrAlSayed0
Copy link

AmrAlSayed0 commented Jan 14, 2021

Steps to Reproduce

  1. Build an app, any app, in release mode.

Expected Behavior

Build is successful.

Actual Behavior

Build fails with Error: Android include path not found. Tried: C:\Program Files (x86)\Android\android-sdk\ndk-bundle\sysroot\usr\include (1, 1)

Version Information

Microsoft Visual Studio Comunity 2019
Version 16.8.4
VisualStudio.16.Release/16.8.4+30907.101
Microsoft .NET Framework
Version 4.8.04084

Installed Version: Comunity

Architecture Diagrams and Analysis Tools 00433-90000-00004-AA929
Microsoft Architecture Diagrams and Analysis Tools

Visual C++ 2019 00433-90000-00004-AA929
Microsoft Visual C++ 2019

ASP.NET and Web Tools 2019 16.8.557.25636
ASP.NET and Web Tools 2019

ASP.NET Core Razor Language Services 16.1.0.2052803+84e121f1403378489b842e1797df2f3f5a49ac3c
Provides languages services for ASP.NET Core Razor.

ASP.NET Web Frameworks and Tools 2019 16.8.557.25636
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0 16.8.557.25636
Azure App Service Tools v3.0.0

Azure Functions and Web Jobs Tools 16.8.557.25636
Azure Functions and Web Jobs Tools

C# Tools 3.8.0-5.20604.10+9ed4b774d20940880de8df1ca8b07508aa01c8cd
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Common Azure Tools 1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

EditProj 1.0
This packages allows you to edit project and solution files without the need to unload them first.

Extensibility Message Bus 1.2.6 (master@34d6af2)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.

GitHub.VisualStudio 2.11.106.19330
A Visual Studio Extension that brings the GitHub Flow into Visual Studio.

IntelliCode Extension 1.0
IntelliCode Visual Studio Extension Detailed Info

Microsoft Azure Tools 2.9
Microsoft Azure Tools for Microsoft Visual Studio 2019 - v2.9.30924.1

Microsoft Continuous Delivery Tools for Visual Studio 0.4
Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.

Microsoft JVM Debugger 1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft Library Manager 2.1.113+g422d40002e.RR
Install client-side libraries easily to any web project

Microsoft MI-Based Debugger 1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual C++ Wizards 1.0
Microsoft Visual C++ Wizards

Microsoft Visual Studio Tools for Containers 1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Microsoft Visual Studio VC Package 1.0
Microsoft Visual Studio VC Package

Mono Debugging for Visual Studio 16.8.43 (00471f8)
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager 5.8.1
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/

Project System Tools 1.0
Tools for working with C#, VisualBasic, and F# projects.

ProjectServicesPackage Extension 1.0
ProjectServicesPackage Visual Studio Extension Detailed Info

Snapshot Debugging Extension 1.0
Snapshot Debugging Visual Studio Extension Detailed Info

SQL Server Data Tools 16.0.62012.31170
Microsoft SQL Server Data Tools

Syntax Visualizer 1.0
An extension for visualizing Roslyn SyntaxTrees.

TypeScript Tools 16.0.21016.2001
TypeScript Tools for Microsoft Visual Studio

Visual Basic Tools 3.8.0-5.20604.10+9ed4b774d20940880de8df1ca8b07508aa01c8cd
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.

Visual F# Tools 16.8.0-beta.20507.4+da6be68280c89131cdba2045525b80890401defd
Microsoft Visual F# Tools

Visual Studio Code Debug Adapter Host Package 1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Container Tools Extensions 1.0
View, manage, and diagnose containers within Visual Studio.

Visual Studio Tools for Containers 1.0
Visual Studio Tools for Containers

VisualStudio.DeviceLog 1.0
Information about my package

VisualStudio.Foo 1.0
Information about my package

VisualStudio.Mac 1.0
Mac Extension for Visual Studio

Xamarin 16.8.000.261 (d16-8@bb99248)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer 16.8.0.507 (remotes/origin/d16-8@e87b24884)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin Templates 16.8.112 (86385a3)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.

Xamarin.Android SDK 11.1.0.26 (d16-8/a36ce73)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: 5e9cb6d
Java.Interop: xamarin/java.interop/d16-8@79d9533
ProGuard: Guardsquare/proguard@ebe9000
SQLite: xamarin/sqlite@1a3276b
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-8@2fb1cbc

Xamarin.iOS and Xamarin.Mac SDK 14.8.0.3 (c51fabee8)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

Log File

Possible Cause

I think the problem is here
https://github.com/xamarin/xamarin-android/blob/master/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs#L260-L270
and here
https://github.com/xamarin/xamarin-android/blob/master/src/Xamarin.Android.Build.Tasks/Tasks/NdkUtils.cs#L224-L227
The path is hardcoded to sysroot/usr/include which is fine but my NDK bundle folder at C:\Program Files (x86)\Android\android-sdk\ndk-bundle looks like this
image

I recently updated my NDK to version 22.0.7026061. After downgrading to version 21.3.6528147. The issue didn't happen.

The downgraded NDK bundle looks like this
image

The sysroot and platforms folders are gone. The sysroot folder is moved to an inner directory in the updated version. I couldn't find any folder like the platforms one in the updated NDK.

EDIT:
After some searching I found this and this

Workaround

Downgrade your NDK version to 21.3.6528147

@AmrAlSayed0 AmrAlSayed0 added the Area: App+Library Build Issues when building Library projects or Application projects. label Jan 14, 2021
@kvpt
Copy link

kvpt commented Jan 15, 2021

So it means that now that Azure Pipelines and GitHub Actions pushed R22 NDK in all agent images, all Xamarin Android build that use NDK are broken.
It's strange that nobody has encountered this issue before deploying this change.

@jpobst jpobst added this to the Under Consideration milestone Jan 15, 2021
@grendello
Copy link
Contributor

@AmrAlSayed0 NDK r22 has a big number of incompatible changes that prevent us from building with it ATM. Also, it has a broken detection of the Windows operating system (it detects it as MINGW). Please use r21 (which is LTS) until we can get XA working with r22.

@grendello
Copy link
Contributor

@kvpt Xamarin.Android downloads its own NDK during its build, so no build is broken.

@grendello
Copy link
Contributor

@AmrAlSayed0 I'm going to close this issue as we are aware of the problem. Please keep an eye on the above PR and NDK issue report to track the progress, thanks!

@AmrAlSayed0
Copy link
Author

@grendello There was no pressing reason for me to update NDK, I just like to keep all the components updated so working with r21 is fine.

@grendello
Copy link
Contributor

@AmrAlSayed0 that was also the motivation behind my PR, but alas - the changes are aplenty. Most of them are already in the PR, we just need the NDK issue fixed to move on.

@kvpt
Copy link

kvpt commented Jan 15, 2021

@kvpt Xamarin.Android downloads its own NDK during its build, so no build is broken.

@grendello Are you sure of that ?

Aot-compiler use C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk path and work.

[aot-compiler stdout] Executing the native assembler: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-as" -mfpu=vfp3 -o obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s.o obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s
[aot-compiler stdout] Executing the native linker: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-ld" -Bsymbolic -shared -o obj\Release\110\aot\armeabi-v7a\libaot-System.Data.dll.so.tmp obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s.o
[aot-compiler stdout] Stripping the binary: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-strip" --strip-symbol=$a --strip-symbol=$d obj\Release\110\aot\armeabi-v7a\libaot-System.Data.dll.so.tmp

But mkbundle use C:\Program Files (x86)\Android\android-sdk\ndk-bundle path and fail.

[mkbundle stderr]
##[error]C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2135,3): Error : Android include path not found. Tried: C:\Program Files (x86)\Android\android-sdk\ndk-bundle\sysroot\usr\include
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2135,3): error : Android include path not found. Tried: C:\Program Files (x86)\Android\android-sdk\ndk-bundle\sysroot\usr\include

I use the Xamarin.Android build task in a windows-2019 agent in Azure Pipeline, since the deployment of NDK R22 it fail.
Can I pass a parameter to force using the right version or we have to wait the PR with the fix ?

@grendello
Copy link
Contributor

@kvpt Xamarin.Android downloads its own NDK during its build, so no build is broken.

@grendello Are you sure of that ?

You said "Xamarin Android build" so I assumed you meant XA itself and, yes , I'm sure that Xamarin Android builds using its own NDK. If you mean an application which needs NDK, then in this case it uses whatever it can find. Which will usually be whatever VS installs and I don't suppose VS2019 installs NDK r22 - so if it's using an r22 on Azure, then the VS installation there must have been overridden with a new version of the NDK.

Aot-compiler use C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk path and work.

[aot-compiler stdout] Executing the native assembler: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-as" -mfpu=vfp3 -o obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s.o obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s
[aot-compiler stdout] Executing the native linker: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-ld" -Bsymbolic -shared -o obj\Release\110\aot\armeabi-v7a\libaot-System.Data.dll.so.tmp obj\Release\110\aot\armeabi-v7a\System.Data.dll\temp.s.o
[aot-compiler stdout] Stripping the binary: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\ndk\arm-linux-androideabi-strip" --strip-symbol=$a --strip-symbol=$d obj\Release\110\aot\armeabi-v7a\libaot-System.Data.dll.so.tmp

But mkbundle use C:\Program Files (x86)\Android\android-sdk\ndk-bundle path and fail.

[mkbundle stderr]
##[error]C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2135,3): Error : Android include path not found. Tried: C:\Program Files (x86)\Android\android-sdk\ndk-bundle\sysroot\usr\include
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2135,3): error : Android include path not found. Tried: C:\Program Files (x86)\Android\android-sdk\ndk-bundle\sysroot\usr\include

I use the Xamarin.Android build task in a windows-2019 agent in Azure Pipeline, since the deployment of NDK R22 it fail.
Can I pass a parameter to force using the right version or we have to wait the PR with the fix ?

you can set the AndroidNdkDirectory MSBuild property to point it to somewhere else. The PR may take a while to complete, unfortunately, I'd suggest filing an issue with Azure regarding the NDK r22 rollout (we'll try to escalate it internally too). Thanks!

@jvalkyrie
Copy link

jvalkyrie commented Jan 19, 2021

you can set the AndroidNdkDirectory MSBuild property to point it to somewhere else. The PR may take a while to complete, unfortunately, I'd suggest filing an issue with Azure regarding the NDK r22 rollout (we'll try to escalate it internally too). Thanks!

Hi @grendello! How can I obtain the directory to a different NDK? I'm using the "macos-latest" image for my DevOps pipeline (macos-10.15) but I can't find an example anywhere on how to get it. I'm specifically looking for the directory of the NDK "21.3.6528147" to use with AndroidNdkDirectory. Thanks!

@grendello
Copy link
Contributor

@jvalkyrie I don't know the next thing about Azure images, but you could download the NDK (it's huge, alas) from https://developer.android.com/ndk/downloads and unzip it anywhere (it's a self-contained zip archive without location preferences), then point to that directory.

@kvpt
Copy link

kvpt commented Jan 19, 2021

@jvalkyrie I had the same problem but on Windows.
They give the command to install but not the install directory, the log of the installer is truncated and don't permit to know where the ndk is uncompressed.
After many failed builds, I found that the ndk 22 path was $(ANDROID_HOME)\ndk-bundle and the path of the ndk 21 was $(ANDROID_HOME)\ndk\21.3.6528147.
I don't know if the path if the same on a Windows agent, you can try.

@jvalkyrie
Copy link

Thank you @kvpt & @grendello, your suggestions worked!

Here are the changes I made in my yaml file just in case someone else stumbles on this page:

- script: ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.3.6528147"
  displayName: 'Download NDK r21'

- task: XamarinAndroid@1
  inputs:
    projectFile: '**/*.Android.csproj'
    outputDirectory: '$(outputDirectory)'
    configuration: '$(buildConfiguration)'
    msbuildArguments: '/p:AndroidNdkDirectory="$(ANDROID_HOME)/ndk/21.3.6528147"'
    jdkOption: 'JDKVersion'
    createAppPackage: true

Before I run XamarinAndroid@1, I first download the NDK 21.3.6528147. Then inside the build task, I point the AndroidNdkDirectory to this version.

I'll revert these changes once XamarinAndroid@1 has been updated to be compatible with NDK r22.

Thanks again!

grendello added a commit to grendello/xamarin-android-tools that referenced this issue Jan 20, 2021
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out an
update which includes NDK r22 and, thus, it breaks builds for customers
using any form of Xamarin.Android AOT build.

In attempt to detect broken/incompatible NDK versions as well as select
the "best one", this commit adds code to scan the known NDK locations in
search of the preferred version.  The search is conducted as follows:

  1. If the user selected a preferred NDK location, it is always used.
  2. Locations specified in the `ANDROID_{HOME,SDK_ROOT}` environment
     variables are returned next.
  3. Directories in the `PATH` environment variable are examined to find
     a valid NDK location.
  4. OS-specific known NDK locations are considered.

For each of the returned locations, we now look for the Android SDK
packages containing the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
grendello added a commit to grendello/xamarin-android-tools that referenced this issue Jan 20, 2021
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out an
update which includes NDK r22 and, thus, it breaks builds for customers
using any form of Xamarin.Android AOT build.

In attempt to detect broken/incompatible NDK versions as well as select
the "best one", this commit adds code to scan the known NDK locations in
search of the preferred version.  The search is conducted as follows:

  1. If the user selected a preferred NDK location, it is always used.
  2. Locations specified in the `ANDROID_{HOME,SDK_ROOT}` environment
     variables are returned next.
  3. Directories in the `PATH` environment variable are examined to find
     a valid NDK location.
  4. OS-specific known NDK locations are considered.

For each of the returned locations, we now look for the Android SDK
packages containing the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
grendello added a commit to grendello/xamarin-android-tools that referenced this issue Jan 20, 2021
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out an
update which includes NDK r22 and, thus, it breaks builds for customers
using any form of Xamarin.Android AOT build.

In attempt to detect broken/incompatible NDK versions as well as select
the "best one", this commit adds code to scan the known NDK locations in
search of the preferred version.  The search is conducted as follows:

  1. If the user selected a preferred NDK location, it is always used.
  2. Locations specified in the `ANDROID_{HOME,SDK_ROOT}` environment
     variables are returned next.
  3. Directories in the `PATH` environment variable are examined to find
     a valid NDK location.
  4. OS-specific known NDK locations are considered.

For each of the returned locations, we now look for the Android SDK
packages containing the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
grendello added a commit to grendello/xamarin-android-tools that referenced this issue Jan 20, 2021
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out an
update which includes NDK r22 and, thus, it breaks builds for customers
using any form of Xamarin.Android AOT build.

In attempt to detect broken/incompatible NDK versions as well as select
the "best one", this commit adds code to scan the known NDK locations in
search of the preferred version.  The search is conducted as follows:

  1. If the user selected a preferred NDK location, it is always used.
  2. Locations specified in the `ANDROID_{HOME,SDK_ROOT}` environment
     variables are returned next.
  3. Directories in the `PATH` environment variable are examined to find
     a valid NDK location.
  4. OS-specific known NDK locations are considered.

For each of the returned locations, we now look for the Android SDK
packages containing the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
jonpryor pushed a commit to dotnet/android-tools that referenced this issue Jan 20, 2021
Context: actions/runner-images#2420
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out
an update which includes NDK r22 and, thus, it breaks builds for
customers using any form of Xamarin.Android AOT build.

In an attempt to detect broken/incompatible NDK versions as well as
to select the "best one", this commit adds code to scan the known NDK
locations in search of the preferred version.

Given an `AndroidSdkInfo` creation of:

	var info = new AndroidSdkInfo (logger:logger,
	        androidSdkPath: sdkPath,
	        androidNdkPath: ndkPath,
	        javaSdkPath: javaPath);
	var usedNdkPath = info.AndroidNdkPath;

If `ndkPath` is not `null` and otherwise valid, then `usedNdkPath`
is `ndkPath`.

If `ndkPath` is `null` or is otherwise invalid (missing `ndk-stack`,
etc.), then we search for an `info.AndroidNdkPath` value as follows:

 1. If `androidSdkPath` is not `null` and valid, then we check for
    Android SDK-relative NDK locations, in:

      * `{androidSdkPath}/ndk/*`
      * `{androidSdkPath}/ndk-bundle`

    For each found SDK-relative NDK directory, we filter out NDKs for
    which we cannot determine the package version, as well as those
    which are "too old" (< `MinimumCompatibleNDKMajorVersion`) or
    "too new" (> `MaximumCompatibleNDKMajorVersion`), currently r22.

    We prefer the NDK location with the highest version number. 

 2. If `androidSdkPath` is not `null` and valid and if there are no
    Android SDK-relative NDK locations, then we use the user-selected
    "preferred NDK location".  See also
    `AndroidSdkInfo.SetPreferredAndroidNdkPath()`.

 3. If `androidSdkPath` is not `null` and valid and if the preferred
    NDK location isn't set or is invalid, then we check directories
    specified in `$PATH`, and use the directory which contains
    `ndk-stack`.

 4. If `androidSdkPath` is not `null` and valid and `$PATH` didn't
    contain `ndk-stack`, then we continue looking for NDK locations
    within the Android SDK locations specified by the `$ANDROID_HOME`
    and `$ANDROID_SDK_ROOT` environment variables.
    As with (1), these likewise look for e.g. `${ANDROID_HOME}/ndk/*`
    or `${ANDROID_SDK_ROOT}/ndk-bundle` directories and select the
    NDK with the highest supported version.

 5. If `androidSdkPath` is `null`, then *first* we try to find a
    valid Android SDK directory, using on Unix:

     a. The preferred Android SDK directory; see also
        `AndroidSdkInfo.SetPreferredAndroidSdkPath().

     b. The `$ANDROID_HOME` and `ANDROID_SDK_ROOT`
        environment variables.

     c. Directories within `$PATH` that contain `adb`.

    Once an Android SDK is found, steps (1)…(4) are performed.

In (1) and (4), we now look for the Android SDK packages containing
the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
jonpryor pushed a commit to dotnet/android-tools that referenced this issue Jan 20, 2021
Context: actions/runner-images#2420
Context: dotnet/android#5499
Context: dotnet/android#5526
Context: android/ndk#1427
Context: https://developer.android.com/studio/command-line/variables#envar

Xamarin.Android is not (yet) compatible with the recently released
Android NDK r22 version.  Azure build images have recently rolled out
an update which includes NDK r22 and, thus, it breaks builds for
customers using any form of Xamarin.Android AOT build.

In an attempt to detect broken/incompatible NDK versions as well as
to select the "best one", this commit adds code to scan the known NDK
locations in search of the preferred version.

Given an `AndroidSdkInfo` creation of:

	var info = new AndroidSdkInfo (logger:logger,
	        androidSdkPath: sdkPath,
	        androidNdkPath: ndkPath,
	        javaSdkPath: javaPath);
	var usedNdkPath = info.AndroidNdkPath;

If `ndkPath` is not `null` and otherwise valid, then `usedNdkPath`
is `ndkPath`.

If `ndkPath` is `null` or is otherwise invalid (missing `ndk-stack`,
etc.), then we search for an `info.AndroidNdkPath` value as follows:

 1. If `androidSdkPath` is not `null` and valid, then we check for
    Android SDK-relative NDK locations, in:

      * `{androidSdkPath}/ndk/*`
      * `{androidSdkPath}/ndk-bundle`

    For each found SDK-relative NDK directory, we filter out NDKs for
    which we cannot determine the package version, as well as those
    which are "too old" (< `MinimumCompatibleNDKMajorVersion`) or
    "too new" (> `MaximumCompatibleNDKMajorVersion`), currently r22.

    We prefer the NDK location with the highest version number. 

 2. If `androidSdkPath` is not `null` and valid and if there are no
    Android SDK-relative NDK locations, then we use the user-selected
    "preferred NDK location".  See also
    `AndroidSdkInfo.SetPreferredAndroidNdkPath()`.

 3. If `androidSdkPath` is not `null` and valid and if the preferred
    NDK location isn't set or is invalid, then we check directories
    specified in `$PATH`, and use the directory which contains
    `ndk-stack`.

 4. If `androidSdkPath` is not `null` and valid and `$PATH` didn't
    contain `ndk-stack`, then we continue looking for NDK locations
    within the Android SDK locations specified by the `$ANDROID_HOME`
    and `$ANDROID_SDK_ROOT` environment variables.
    As with (1), these likewise look for e.g. `${ANDROID_HOME}/ndk/*`
    or `${ANDROID_SDK_ROOT}/ndk-bundle` directories and select the
    NDK with the highest supported version.

 5. If `androidSdkPath` is `null`, then *first* we try to find a
    valid Android SDK directory, using on Unix:

     a. The preferred Android SDK directory; see also
        `AndroidSdkInfo.SetPreferredAndroidSdkPath().

     b. The `$ANDROID_HOME` and `ANDROID_SDK_ROOT`
        environment variables.

     c. Directories within `$PATH` that contain `adb`.

    Once an Android SDK is found, steps (1)…(4) are performed.

In (1) and (4), we now look for the Android SDK packages containing
the NDK.  There are two kinds of such packages:

  * `ndk-bundle` is the older package which allows for installation of
    only one NDK inside the SDK directory
  * `ndk/*` is a newer package which allows for installation of several
    NDK versions in parallel.  Each subdirectory of `ndk` is an `X.Y.Z`
    version number of the NDK.

In each of these directories we look for the `source.properties` file
from which we then extract the NDK version and then we sort thus
discovered NDK instances using their version as the key, in the
descending order.  The latest compatible (currently: less than 22 and
more than 15) version is selected and its path returned to the caller.
@ghost ghost locked as resolved and limited conversation to collaborators Jun 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

No branches or pull requests

5 participants