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

[BUG] r22 appears to break cmake compiler and OS detection on Windows #1427

Closed
grendello opened this issue Jan 11, 2021 · 25 comments
Closed
Assignees
Labels

Comments

@grendello
Copy link

Description

Xamarin.Android has been using Android SDK's cmake for quite a while now and
until NDK r22 everything has worked as expected. With r22 the Unix (Linux and macOS) builds still work fine, however the Windows build breaks because
cmake is not able to properly detect the C/C++ compilers (please see the attached error and output logs). Not only that, it appears that the WIN32
cmake variable is not set at all, instead MINGW is set.

We normally use cmake from the SDK (version 3.10.2), but I also tried with cmake 3.18 shipped with VS2019, to the same effect. Our CMakeLists.txt, PR to switch XA to NDK r22, and a sample invocation line:

C:\Users\AzDevOps\android-toolchain\sdk\cmake\3.10.2.4988404\bin\cmake --debug-output -GNinja -DCMAKE_MAKE_PROGRAM=C:\Users\AzDevOps\android-toolchain\sdk\cmake\3.10.2.4988404\bin\ninja -DANDROID_STL="none" -DANDROID_CPP_FEATURES="no-rtti no-e
xceptions" -DANDROID_TOOLCHAIN=clang -DCMAKE_TOOLCHAIN_FILE=C:\Users\AzDevOps\android-toolchain\ndk\build\cmake\android.toolchain.cmake -DANDROID_NDK=C:\Users\AzDevOps\android-toolchain\ndk -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DJDK_INCLUDE="C:\Users\AzDevOps\android-toolchain\jdk-11\include C:\Users\AzDevOps\android-toolchain\jdk-11\include\win32" -DMONO_PATH=C:\a\2\s\external\mono -DCONFIGURATION=Release -DCMAKE_BUILD_TYPE=Debug -DANDROID_NATIVE_API_LEVEL=16 -DANDROID_PLATFORM=android-16 -DANDROID_ABI=armeabi-v7a -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=C:\a\2\s\bin\Release\lib\xamarin.android\xbuild\Xamarin\Android\lib\armeabi-v7a -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=C:\a\2\s\bin\Release\lib\xamarin.android\xbuild\Xamarin\Android\lib\armeabi-v7a C:\a\2\s\src\monodroid\

The same CMakeList.txt (and the same cmake version) works fine with r21 on Windows

Environment Details

Not all of these will be relevant to every bug, but please provide as much
information as you can.

  • NDK Version: 22.0.7026061
  • Build system: cmake
  • Host OS: Windows 10 64bit
  • ABI: all
  • NDK API level: 16 or 21 (others not tested)
  • Device API level: N/A

CMakeError.log.txt
CMakeOutput.log.txt

@grendello grendello added the bug label Jan 11, 2021
@grendello
Copy link
Author

Just a note regarding the command above. I do know that r22 doesn't have support for API16 (at least the runtime libs for it are absent, clang wrapper scripts are still there), but it's not relevant in this case - the error appears to be unrelated at least. However, for API21 build cmake still mis-detects the system as MINGW. Please see the logs attached below - the libraries mentioned in the error log are used only if MINGW is detected.

CMakeError.log.txt
CMakeOutput.log.txt

@DanAlbert
Copy link
Member

Looks like CMake hasn't set the -target for Clang?

Compiler: C:/Users/AzDevOps/android-toolchain/ndk/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe 
Build flags: -g;-DANDROID;-fdata-sections;-ffunction-sections;-funwind-tables;-fstack-protector-strong;-no-canonical-prefixes;-D_FORTIFY_SOURCE=2;-march=armv7-a;-mthumb;-Wformat;-Werror=format-security;
Id flags:  

The output was:
1
clang: warning: argument unused during compilation: '-mthumb' [-Wunused-command-line-argument]
error: unknown target CPU 'armv7-a'
note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, icelake-server, tigerlake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, x86-64

Our QA will have tested Windows before we shipped though. We probably need a repro case here.

at least the runtime libs for it are absent

$ ls android-ndk-r22/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/16/
crtbegin_dynamic.o
crtbegin_so.o
crtbegin_static.o
crtend_android.o
crtend_so.o
libandroid.so
libc++.a
libc.a
libcompiler_rt-extras.a
libc++.so
libc.so
libdl.a
libdl.so
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libjnigraphics.so
liblog.so
libm.a
libm.so
libOpenMAXAL.so
libOpenSLES.so
libstdc++.a
libstdc++.so
libz.a
libz.so

@DanAlbert
Copy link
Member

Assigning to hhb in case he has any ideas.

@grendello
Copy link
Author

Looks like CMake hasn't set the -target for Clang?

It seems as if ARM support wasn't there at all, note this error:

error: unknown target CPU 'armv7-a'

And look at the list of supported CPUs, it contains only x86.

Compiler: C:/Users/AzDevOps/android-toolchain/ndk/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe 
Build flags: -g;-DANDROID;-fdata-sections;-ffunction-sections;-funwind-tables;-fstack-protector-strong;-no-canonical-prefixes;-D_FORTIFY_SOURCE=2;-march=armv7-a;-mthumb;-Wformat;-Werror=format-security;
Id flags:  

The output was:
1
clang: warning: argument unused during compilation: '-mthumb' [-Wunused-command-line-argument]
error: unknown target CPU 'armv7-a'
note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, icelake-server, tigerlake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, x86-64

Our QA will have tested Windows before we shipped though. We probably need a repro case here.

at least the runtime libs for it are absent

My bad, looked in a wrong directory (aarch64) :)

$ ls android-ndk-r22/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/16/
crtbegin_dynamic.o
crtbegin_so.o
crtbegin_static.o
crtend_android.o
crtend_so.o
libandroid.so
libc++.a
libc.a
libcompiler_rt-extras.a
libc++.so
libc.so
libdl.a
libdl.so
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libjnigraphics.so
liblog.so
libm.a
libm.so
libOpenMAXAL.so
libOpenSLES.so
libstdc++.a
libstdc++.so
libz.a
libz.so

@grendello
Copy link
Author

I think the error: unknown target CPU 'armv7-a' error is a red herring and that, ultimately, the problem is the misdetection of the system as MINGW. Looking further at the CMakeOutput.log attached in the OP, it gets the correct compiler options:

Detecting C compiler ABI info compiled with the following output:
Change Dir: C:/Users/Grendel/vc/xamarin-android/src/monodroid/obj/Debug/armeabi-v7a-Debug/CMakeFiles/CMakeTmp

Run Build Command:"C:\Users\Grendel\android-toolchain\sdk\cmake\3.10.2.4988404\bin\ninja" "cmTC_22a78"
[1/2] Building C object CMakeFiles/cmTC_22a78.dir/CMakeCCompilerABI.c.o
[2/2] Linking C executable cmTC_22a78
Android (6875598, based on r399163b) clang version 11.0.5 (https://android.googlesource.com/toolchain/llvm-project 87f1315dfbea7c137aa2e6d362dbb457e388158d)
Target: armv7-none-linux-android16
Thread model: posix
InstalledDir: C:\Users\Grendel\android-toolchain\ndk\toolchains\llvm\prebuilt\windows-x86_64\bin
Found candidate GCC installation: C:/Users/Grendel/android-toolchain/ndk/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi\4.9.x
Selected GCC installation: C:/Users/Grendel/android-toolchain/ndk/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x
Candidate multilib: thumb;@mthumb
Candidate multilib: armv7-a;@march=armv7-a
Candidate multilib: armv7-a/thumb;@march=armv7-a@mthumb
Candidate multilib: .;
Selected multilib: armv7-a/thumb;@march=armv7-a@mthumb

However, I added the following snippet to our CMakeLists.txt:

if(WIN32)
        message(STATUS "WIN32 set")
endif()

if(MINGW)
        message(STATUS "MINGW set")
endif()

And the output is:

-- MINGW set
   Called from: [1]     src/monodroid/CMakeLists.txt
CMake Error at CMakeLists.txt:93 (message):
  Please set the MINGW_DEPENDENCIES_ROOT_DIR variable on command line
  (-DMINGW_DEPENDENCIES_ROOT_DIR=PATH)

@fuchg3
Copy link

fuchg3 commented Jan 13, 2021

It seems cmake 3.19.2 could detect the right platform. That's my temporary workaround.

@hhb
Copy link
Collaborator

hhb commented Jan 13, 2021

It seems cmake 3.19.2 could detect the right platform. That's my temporary workaround.

You probably are using cmake's NDK support instead of NDK toolchain file. In that case CMake >= 3.19 is required for NDK r22.

(I'm investing why MINGW is used there in this issue

@hhb
Copy link
Collaborator

hhb commented Jan 19, 2021

Seems it is not trivial to build Xamarin.Android. Do you have a smaller repro case?

Also can you try to copy r21 android.toolchain.cmake to r22 to see how it does? One of the new changes in r22 is aosp/1413029. Maybe it affects compiler detection somehow?

@grendello
Copy link
Author

Seems it is not trivial to build Xamarin.Android. Do you have a smaller repro case?

You don't really need to build it all. On Windows (from VS prompt), after cloning and restoring submodules, you need the following steps:

  1. In the top source dir run msbuild /t:Prepare Xamarin.Android.sln
  2. Change to the src/monodroid directory and run msbuild /bl (the /bl will create a detailed binary log, msbuild.binlog, which you can replay either with msbuild /v:diag msbuild.binlog or with https://msbuildlog.com/)
  3. CMake generates its files in subdirectories of src/monodroid/obj/{Debug,Release}, you can rerun cmake in any of those with the options needed

Also can you try to copy r21 android.toolchain.cmake to r22 to see how it does? One of the new changes in r22 is aosp/1413029. Maybe it affects compiler detection somehow?

I don't use Windows locally, but I'll try to test that ASAP.

@fuchg3
Copy link

fuchg3 commented Jan 20, 2021

Seems it is not trivial to build Xamarin.Android. Do you have a smaller repro case?

Also can you try to copy r21 android.toolchain.cmake to r22 to see how it does? One of the new changes in r22 is aosp/1413029. Maybe it affects compiler detection somehow?

The problem seems fixed after replacing android.toolchain.cmake file.

@grendello
Copy link
Author

@fuchg3 thanks, you saved me from a few hours of installing software :)

@grendello
Copy link
Author

Seems it is not trivial to build Xamarin.Android. Do you have a smaller repro case?

Also can you try to copy r21 android.toolchain.cmake to r22 to see how it does? One of the new changes in r22 is aosp/1413029. Maybe it affects compiler detection somehow?

I've just tested it on CI and it does fix the detection

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.
@hhb
Copy link
Collaborator

hhb commented Jan 20, 2021

It seems cmake 3.19.2 could detect the right platform. That's my temporary workaround.

Since you have the environment, can you help test what is the minimum cmake version that this issue is fixed? Seems we need to bump this a little bit.

Or maybe we can conservatively make it 3.19?

@fuchg3
Copy link

fuchg3 commented Jan 21, 2021

Since you have the environment, can you help test what is the minimum cmake version that this issue is fixed? Seems we need to bump this a little bit.

Or maybe we can conservatively make it 3.19?

The minimun version is 3.19.0. I changed that value to 3.19 and it worked fine.

@hhb
Copy link
Collaborator

hhb commented Jan 22, 2021

The minimun version is 3.19.0. I changed that value to 3.19 and it worked fine.

Thanks seems what we need is cmake 5192 and cmake 5058? I'll update toolchain file.

@hhb
Copy link
Collaborator

hhb commented Jan 26, 2021

jonpryor pushed a commit to dotnet/android that referenced this issue Feb 9, 2021
Context: mono/mono#20606
Context: https://github.com/android/ndk/wiki/Changelog-r22

Changes: mono/mono@5e9cb6d...c66141a

  * mono/mono@c66141a8c7b: [AOT] Make native linker name configurable (#20816)
  * mono/mono@64368a00d85: Bump msbuild
  * mono/mono@364c87b1a7a: Disable acceptance-tests/roslyn.mk
  * mono/mono@9b139294c04: Bump msbuild to fix build break
  * mono/mono@b9c050faf2e: [aot] Quote the -Wl,install_name argument to clang. (#20660)

Add support for using [NDK r22][0] when building Xamarin.Android apps.

The most important NDK changes:

  * GNU binutils are deprecated (but still used)
  * LLVM 11 is used for the toolchain
  * LLD is now the default linker

Mono changes:

  * Allow the `ld` name to be configurable, as we now prefer e.g.
    `aarch64-linux-android-ld.gold`, not `aarch64-linux-android-ld`,
    as the latter is LLD and not binutils.

Xamarin.Android CI changes:

  * All the binutils tools are listed in a single location, within
    `xaprepare`'s `Configurables.Defaults`.

  * Host NDK binutils are installed by `xaprepare` instead of by
    Xamarin.Android.Build.Tools

  * `UBSAN` checked builds now require `RTTI` and exceptions.

Xamarin.Android App build changes:

  * The `<Aot/>` task now supports using NDK r22

TODO:

  * Add a nightly job (916d24b) which builds Xamarin.Android apps
    against NDK r21, to ensure we don't break support.

  * NDK r22's [`cmake` doesn't work on Windows][1].
    We have worked around this by copying the fixed
    `android.toolchain.cmake` as
    `src-ThirdParty/ndk/android.toolchain.cmake.ndk_r21.3`.

    Once NDK r22 properly includes the fix, we should remove
    `src-ThirdParty/ndk/android.toolchain.cmake.ndk_r21.3`.

[0]: https://github.com/android/ndk/wiki/Changelog-r22
[1]: android/ndk#1427
grendello added a commit to grendello/xamarin-android that referenced this issue Mar 25, 2021
Context: https://github.com/android/ndk/wiki/Changelog-r22#r22b
Context: android/ndk#1427

Upstream changes:

  * [Issue 1377][0]: Fix Clang backend crash in register scavenging.
  * [Issue 1388][1]: Fixed LLVM's incorrect conversion to list files for long command lines on Windows.
  * [Issue 1391][2]: Fixed missing symbols from libz.a.
  * [Issue 1427][3]: Fixed Clang auto-detection for CMake 3.19 and older for Windows.

Fix for issue 1427 above allows us to remove the older Android cmake
toolchain file we've been using to work around the bug on Windows
platforms.

[0]: android/ndk#1377
[1]: android/ndk#1388
[2]: android/ndk#1391
[3]: android/ndk#1427
jonpryor pushed a commit to dotnet/android that referenced this issue Mar 26, 2021
Context: https://github.com/android/ndk/wiki/Changelog-r22#r22b
Context: android/ndk#1427

Upstream changes:

  * [Issue 1377][0]: Fix Clang backend crash in register scavenging.
  * [Issue 1388][1]: Fixed LLVM's incorrect conversion to list files
    for long command lines on Windows.
  * [Issue 1391][2]: Fixed missing symbols from `libz.a`.
  * [Issue 1427][3]: Fixed Clang auto-detection for CMake 3.19 and
    older for Windows.

The fix for issue 1427 above allows us to remove the older Android
cmake toolchain file we've been using (accc846) to work around the
bug on Windows platforms.

[0]: android/ndk#1377
[1]: android/ndk#1388
[2]: android/ndk#1391
[3]: android/ndk#1427
@hhb hhb closed this as completed Apr 1, 2021
@mirabilos
Copy link

This causes lots of warnings with every build now; cmake 3.10 is the latest the Android SDK/NDK offers.

@DanAlbert
Copy link
Member

Did you update? As far as we know this is fixed.

@mirabilos
Copy link

Update what?

Update the NDK to 22.1? Yes, which is when the new build warnings begun to show up.

Update cmake? No, because cmake 3.10 is the latest version that is possible to use with the SDK/NDK. Which, then, is the very cause of this warning because the NDK 22.1 really wants cmake 3.19 or newer. You should make it possible to comply with the raised requirements before you raise them ☺

@DanAlbert
Copy link
Member

The fix does not require CMake 3.19. The fix was specifically to make this work with versions of CMake earlier than 3.19.

We do not have enough information to investigate further. We need a repro case.

As for getting new versions of CMake into the SDK, you're talking to the wrong people. We only maintain the NDK. File a bug against Studio.

@enh-google
Copy link
Collaborator

https://issuetracker.google.com/177245495 seems to be the existing public bug. looks like they have 3.18 in the beta channel.

@mirabilos
Copy link

mirabilos commented Apr 8, 2021 via email

@DanAlbert
Copy link
Member

Yes, I know. But you seem to not have read my initial comment
here, which says: the fix now causes tons of build warnings
in every single project.

Oh! You didn't say the fix caused this, you just said "this", which I took to mean "this bug". That makes sense now.

Doesn’t mean it’s right to release a new version of the NDK that
effectively requires something that’s not available yet.

Nothing is being required here. It's a warning, not an error. That warning is there for a good reason. We used to have bugs filed often for things that happened as a result of compiler ID bypass. The warning is there to communicate "yeah, nothing the NDK can do about it, you need to use a newer version of CMake."

The change in r22b was to raise the minimum version of CMake that was required for using the built-in compiler ID behavior, because prior to 3.19 there were bugs (that's the original report here). We can't revert this to fix the warnings without breaking builds.

FWIW you don't need to wait for the SDK to get 3.20. You can use any version of CMake you want: https://developer.android.com/studio/projects/install-ndk#vanilla_cmake.

@mirabilos
Copy link

mirabilos commented Apr 10, 2021 via email

grendello added a commit to grendello/runtime that referenced this issue Apr 26, 2021
Context: android/ndk#1427 (comment)

Android NDK r22 changed the tree layout by moving `sysroot` from the NDK
root directory to a subdirectory in the toolchains tree and also by
removing per-platform library/header directories from their previous
location to one under the sysroot above.

MonoVM was built using the CMake's built-in Android NDK support which,
alas, is not compatible with NDK r22 before CMake version 3.19.  It is
therefore better to use the Android CMake toolchain definition script
shipped with the NDK, so that the build works regardless of CMake
version installed on the system.

The r22 toolchain will complain about older CMake versions:

    An old version of CMake is being used that cannot
    automatically detect compiler attributes. Compiler identification is
    being bypassed. Some values may be wrong or missing. Update to CMake
    3.19 or newer to use CMake's built-in compiler identification.

This warning can be safely ignored.
marek-safar pushed a commit to dotnet/runtime that referenced this issue Apr 28, 2021
Context: android/ndk#1427 (comment)

Android NDK r22 changed the tree layout by moving `sysroot` from the NDK
root directory to a subdirectory in the toolchains tree and also by
removing per-platform library/header directories from their previous
location to one under the sysroot above.

MonoVM was built using the CMake's built-in Android NDK support which,
alas, is not compatible with NDK r22 before CMake version 3.19.  It is
therefore better to use the Android CMake toolchain definition script
shipped with the NDK, so that the build works regardless of CMake
version installed on the system.

The r22 toolchain will complain about older CMake versions:

    An old version of CMake is being used that cannot
    automatically detect compiler attributes. Compiler identification is
    being bypassed. Some values may be wrong or missing. Update to CMake
    3.19 or newer to use CMake's built-in compiler identification.

This warning can be safely ignored.
@mirabilos
Copy link

mirabilos commented Jun 6, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants