How to use ndkVersion in gradle

9,535 views
Skip to first unread message

Andi McClure

unread,
Jan 23, 2020, 12:02:48 AM1/23/20
to android-ndk
Short question: Gradle is not recognizing the android.ndkVersion property, what is wrong?

Long question:

Today I checked out my existing gradle+ndk project on a new machine and attempted to build it. It compiles fine on the old machine but on the new machine it did not work. Gradle gives the error:

* What went wrong:
A problem occurred configuring project ':cmakelib'.
> NDK not configured. 
  Download it with SDK manager.

However, I had already downloaded "NDK (side by side)", the only NDK option in the SDK Manager's SDK Tools listing, and I got this error anyway.

I did research and learned this: https://stackoverflow.com/a/59275504 Apparently "NDK (side by side)" means in new Android Studio you can download multiple NDK versions at once, and this means you are now required to tell Gradle which NDK to use or it won't know which one to pick. Okay.

That stack overflow answer said to use `android { ndkVersion "VERSIONHERE" }` in the gradle file. I find the same advice in this NDK build guide in the official docs: https://developer.android.com/studio/projects/install-ndk at the bottom, under "Configure specific versions of the NDK in your project".

So, the top of my build.gradle file now looks like:

apply plugin: 'com.android.library'

android {
compileSdkVersion 26
buildToolsVersion '29.0.2'
ndkVersion "20.0.5594570"

defaultConfig {
minSdkVersion 23
targetSdkVersion 25
...

When I try to build this, with `gradlew build`, I get this error on line 6, the "ndkVersion" line:

* What went wrong:
A problem occurred evaluating project ':cmakelib'.
> Could not find method ndkVersion() for arguments [20.0.5594570] on object of type com.android.build.gradle.LibraryExtension.

Experimentally, I tried moving the ndkVersion call inside of the defaultConfig {} block. That gave an even uglier error:

* What went wrong:
A problem occurred evaluating project ':cmakelib'.
> Could not find method ndkVersion() for arguments [20.0.5594570] on DefaultConfig_Decorated{name=main, dimension=null, minSdkVersion=DefaultApiVersion{mApiLevel=23, mCodename='null'}, targetSdkVersion=DefaultApiVersion{mApiLevel=25, mCodename='null'}, renderscriptTargetApi=null, renderscriptSupportModeEnabled=null, renderscriptSupportModeBlasEnabled=null, renderscriptNdkModeEnabled=null, versionCode=null, versionName=null, applicationId=null, testApplicationId=null, testInstrumentationRunner=null, testInstrumentationRunnerArguments={}, testHandleProfiling=null, testFunctionalTest=null, signingConfig=null, resConfig=null, mBuildConfigFields={}, mResValues={}, mProguardFiles=[], mConsumerProguardFiles=[], mManifestPlaceholders={}, mWearAppUnbundled=null} of type com.android.build.gradle.internal.dsl.DefaultConfig.

What am I doing wrong? As far as I can tell, I am doing exactly what the documentation says to do.

Note: I am aware I can get my script working the way it did on the old machine by either installing the "NDK (deprecated)" package or by setting the ANDROID_NDK_HOME environment variable to the exact path of the ndk version install. I would prefer to get my code working through the supported paths though.

Dan Albert

unread,
Jan 23, 2020, 12:07:27 AM1/23/20
to android-ndk
What version of the Gradle plugin are you using? I think that was added in 3.5, but it may have been 3.4. if you're using an older version and don't want to deal with upgrading the Gradle plugin right this moment, you can set ndk.dir (in your local.properties) to point to the NDK you want to use, in the SDK directory or otherwise.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/fa2b8d4e-ba6d-45b4-8ce3-a718aa2bbc19%40googlegroups.com.
Message has been deleted
Message has been deleted

Andi McClure

unread,
Jan 23, 2020, 11:13:22 AM1/23/20
to android-ndk
Thanks for the suggestion, I tried upgrading everything I have the option to upgrade and it didn't change the error. My versions are currently:
Android Studio.app [in about box]: 3.5.3 for mac
Android SDK Platform-Tools [in Android Studio SDK Manager]: 29.0.5
Android SDK Tools [in Android Studio SDK Manager]: 26.1.1
BuildToolsVersion [in the gradle file]: 29.0.2

gradlew -v:
------------------------------------------------------------
Gradle 4.7
------------------------------------------------------------

Build time:   2018-04-18 09:09:12 UTC
Revision:     b9a962bf70638332300e7f810689cb2febbd4a6c

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_202-release (JetBrains s.r.o 25.202-b49-5587405)
OS:           Mac OS X 10.13.6 x86_64

Note I am not using Android Studio except to download things via the SDK manager, I am building by running gradlew at the command line.
I do not know how to get the version of "the gradle plugin" that I am running independent of Android Studio.app.

Re: ndk.dir or ANDROID_NDK_HOME: I am not blocked on any particular machine right now, but I maintain a list of instructions for setting up a new machine so it would be great if everything could just work in the .gradle file out of the box without needing to input system-configuration-specific like the version of NDK installed. The problem there is I don't know how to simply describe to the user how to figure out which SDK they have installed or what "the newest SDK" they have installed is. 

On Thursday, January 23, 2020 at 12:07:27 AM UTC-5, Dan Albert wrote:
What version of the Gradle plugin are you using? I think that was added in 3.5, but it may have been 3.4. if you're using an older version and don't want to deal with upgrading the Gradle plugin right this moment, you can set ndk.dir (in your local.properties) to point to the NDK you want to use, in the SDK directory or otherwise.

To unsubscribe from this group and stop receiving emails from it, send an email to andro...@googlegroups.com.

Andrew Esh

unread,
Jan 23, 2020, 11:44:58 AM1/23/20
to android-ndk
In your top level build.gradle file (next to "app directory in your project root), there is a section like this:

    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0-alpha09'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

Android Studio maintains this file, and prompts to update the gradle plugin when needed. The code to parse NDK version strings in a ndkVersion() call are probably in that module, since it is specific to Android (not generic to gradle). If ndkVersion() was not parsing new NDK version numbers, that plugin is what I would try upgrading.

BTW, I have NDK "20.0.5594570" installed, but it is the only one, so I do not have a "ndkVersion" setting in my build.gradle files.

Andrew Esh

unread,
Jan 23, 2020, 1:29:15 PM1/23/20
to android-ndk
Does you local.properties file contain a definition for "ndk.dir" which points at a valid NDK directory? In Android Studio, File->Project Structure->Android NDK Location menu sets this value.

Dan Albert

unread,
Jan 23, 2020, 3:38:43 PM1/23/20
to android-ndk, Jomo Fisher
+jomof in case I got any of the facts wrong here.
 
I maintain a list of instructions for setting up a new machine so it would be great if everything could just work in the .gradle file out of the box without needing to input system-configuration-specific like the version of NDK installed

Your best bet would be to upgrade to 3.6 or higher (3.6 is the latest stable atm but once 4.0 is out that'll also work),  of the gradle plugin. The behavior of which NDK gets used has improved over the recent releases.

Pre 3.5: ndk-bundle would be used. It was up to users to make sure they had the right version for the project they were building.
3.5: android.ndkVersion is used, otherwise the newest installed NDK would be used
3.6: android.ndkVersion is used, otherwise each version of the gradle plugin has a default version of the NDK, so you don't need to specify anything in your build.gradle unless you have a reason to use something other than the default.

Caveat for all (current) versions: ndk.dir or ANDROID_NDK_HOME will override the behaviors above. For 3.5+, if the android.ndkVersion does not match it is an error (or perhaps just a warning), but of nothing is explicitly specified for android.ndkVersion then ndk.dir or ANDROID_NDK_HOME will be used. These are probably going away in the future to improve predictability here.

3.6+ is going to give you the best chance of having a reproducible build on any given machine. AIUI currently gradle won't automatically download the NDK unless there's an explicit android.ndkVersion specified, but I think there's a pop up in AS that starts the download if they don't already have it. Without AS, users will need to use the SDK manager to get the correct NDK themselves. (I'm not really a fan of this behavior, and am trying to get it changed to just always do the download if needed by the project, but that won't happen until after 4.0.)

On Thu, Jan 23, 2020 at 10:29 AM Andrew Esh <andre...@qterics.com> wrote:
Does you local.properties file contain a definition for "ndk.dir" which points at a valid NDK directory? In Android Studio, File->Project Structure->Android NDK Location menu sets this value.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/276ca813-b5d8-43c8-8fc2-283acdd8dc1c%40googlegroups.com.

Andi McClure

unread,
Jan 23, 2020, 3:40:37 PM1/23/20
to android-ndk
"In your top level build.gradle file… there is a section like "dependencies { classpath 'com.android.tools.build:gradle:4.0.0-alpha09' }"

Hm, so I do not think there was any such section in this particular gradle file. But I copied the following from another gradle file:

buildscript { repositories { google(); jcenter(); }; dependencies { classpath 'com.android.tools.build:gradle:3.2.0' } }

It did not make a difference. Dan Albert above mentions a version 3.5. So I tried changing the number from "3.2.0" to "3.5.2" (from this page: https://developer.android.com/studio/releases/gradle-plugin ):

buildscript { repositories { google(); jcenter(); }; dependencies { classpath 'com.android.tools.build:gradle:3.5.2' } }

This caused a number of files to download on first run, but I *still get the "Could not find method ndkVersion()" error*.

Is this com.android.tools.build:gradle the "the gradle plugin" which you and Dan Albert mention? What is its proper name? "The Android Gradle plugin"? Is there some way for me to get a list of which versions of this plugin I have installed on a given machine (so I can delete old versions if needed)?

"BTW, I have NDK "20.0.5594570" installed, but it is the only one, so I do not have a "ndkVersion" setting in my build.gradle files."

You may get a surprise the next time you install a new copy of Android Studio on a machine. As of this second in my testing Android Studio on both Mac and Windows offers two options for NDK, "NDK (side by side)" and "NDK (obsolete)". The (obsolete) option only appears if you uncheck "Hide Obsolete Packages". I think if you look in the Android Studio on your computer, you will find the package you have installed has been renamed to "NDK (obsolete)". This is what I found yesterday on my computer with an existing Android Studio+NDK installation. Unless I am missing something greatly, if you have any version of "NDK (side by side)" installed (even if it is the only one you have installed), you are required to set up each gradle project with a path to the ndk, be it using ANDROID_NDK_HOME, ndk.dir in local.properties or this ndkVersion directive that is not working for me.

"Does you local.properties file contain a definition for "ndk.dir" which points at a valid NDK directory? In Android Studio, File->Project Structure->Android NDK Location menu sets this value."

I am not using Android Studio (except to download sdks), I am compiling from the command line with gradlew. So no local.properties file will exist unless I create one.

(I could create one, or set ANDROID_NDK_HOME as an env var, but again it would be ideal if I could use the documented gradle ndkVersion directive instead…)

Thanks

Andi McClure

unread,
Jan 23, 2020, 3:46:08 PM1/23/20
to android-ndk
"Your best bet would be to upgrade to 3.6 or higher…" [detailed description follows]

Okay, this is *very* helpful. However now I am confused because you say "3.6 is the latest stable", but looking at this page:
https://developer.android.com/studio/releases/gradle-plugin
The newest version it lists is 3.5.2. Is this a documentation fault or are we talking about something other than "the Android Gradle plugin"?
Is there a place which canonically lists the versions/newest stable version of the Android Gradle plugin?

FYI I tried:
buildscript { repositories { google(); jcenter(); }; dependencies { classpath 'com.android.tools.build:gradle:3.6' } }
In my build.gradle and got:

* What went wrong:
A problem occurred configuring project ':cmakelib'.
> Could not resolve all artifacts for configuration ':cmakelib:classpath'.
   > Could not find com.android.tools.build:gradle:3.6.
     Searched in the following locations:
     Required by:
         project :cmakelib

On Thursday, January 23, 2020 at 3:38:43 PM UTC-5, Dan Albert wrote:
+jomof in case I got any of the facts wrong here.
 
I maintain a list of instructions for setting up a new machine so it would be great if everything could just work in the .gradle file out of the box without needing to input system-configuration-specific like the version of NDK installed

Your best bet would be to upgrade to 3.6 or higher (3.6 is the latest stable atm but once 4.0 is out that'll also work),  of the gradle plugin. The behavior of which NDK gets used has improved over the recent releases.

Pre 3.5: ndk-bundle would be used. It was up to users to make sure they had the right version for the project they were building.
3.5: android.ndkVersion is used, otherwise the newest installed NDK would be used
3.6: android.ndkVersion is used, otherwise each version of the gradle plugin has a default version of the NDK, so you don't need to specify anything in your build.gradle unless you have a reason to use something other than the default.

Caveat for all (current) versions: ndk.dir or ANDROID_NDK_HOME will override the behaviors above. For 3.5+, if the android.ndkVersion does not match it is an error (or perhaps just a warning), but of nothing is explicitly specified for android.ndkVersion then ndk.dir or ANDROID_NDK_HOME will be used. These are probably going away in the future to improve predictability here.

3.6+ is going to give you the best chance of having a reproducible build on any given machine. AIUI currently gradle won't automatically download the NDK unless there's an explicit android.ndkVersion specified, but I think there's a pop up in AS that starts the download if they don't already have it. Without AS, users will need to use the SDK manager to get the correct NDK themselves. (I'm not really a fan of this behavior, and am trying to get it changed to just always do the download if needed by the project, but that won't happen until after 4.0.)

On Thu, Jan 23, 2020 at 10:29 AM Andrew Esh <andr...@qterics.com> wrote:
Does you local.properties file contain a definition for "ndk.dir" which points at a valid NDK directory? In Android Studio, File->Project Structure->Android NDK Location menu sets this value.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to andro...@googlegroups.com.

Dan Albert

unread,
Jan 23, 2020, 4:02:45 PM1/23/20
to android-ndk
Can you share your build.gradle files? It sounds like you've done it correctly, but the behavior you're describing doesn't match what I'd expect.
 
Is this com.android.tools.build:gradle the "the gradle plugin" which you and Dan Albert mention? What is its proper name? "The Android Gradle plugin"?

Yes and yes. I just can never remember the full artifact name. "Android Gradle Plugin" or just "AGP" is mostly what you'll hear.
 
Is there some way for me to get a list of which versions of this plugin I have installed on a given machine (so I can delete old versions if needed)?

 Okay, this is *very* helpful. However now I am confused because you say "3.6 is the latest stable", but looking at this page:
https://developer.android.com/studio/releases/gradle-plugin
The newest version it lists is 3.5.2. Is this a documentation fault or are we talking about something other than "the Android Gradle plugin"?

That's my mistake. I thought 3.6 was stable since to me it feels like 4.0 is getting close, but 3.6 is still in RC.

Is there a place which canonically lists the versions/newest stable version of the Android Gradle plugin?

https://maven.google.com/web/index.html. Search for gradle and expand the com.android.tools.build -> gradle section and you'll get a list of published versions. Stable versions are just the ones that aren't explicitly labeled as alpha/beta/rc or something like that.

I'm guessing this thread is probably the best documentation for any of the above currently. It's kind of discussed at https://developer.android.com/studio/projects/install-ndk, but doesn't contain most of those details. I'll try to find some time to get this info into our actual docs.

To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/c8c1574f-1a42-46d7-bf6a-bcf0658617f1%40googlegroups.com.

Dan Albert

unread,
Jan 23, 2020, 4:15:51 PM1/23/20
to android-ndk
Is there some way for me to get a list of which versions of this plugin I have installed on a given machine (so I can delete old versions if needed)?
 
Looks like ~/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle is the cache directory for them, but they're tiny (5MB) so probably not a thing to worry about.

Andi McClure

unread,
Jan 23, 2020, 6:46:06 PM1/23/20
to android-ndk
"Can you share your build.gradle files?"

While attempting to get an example into a git repo, I actually found the problem! There was a second build.gradle in the same directory as gradlew, containing its own "classpath" directive, and it was overriding the build.gradle I thought I was executing. When I updated the classpath in the other build.gradle, my problem went away. You can see the (fixed) project here https://github.com/mcclure/lovr-oculus-mobile/tree/ndkversion-test (I have been trying to build the gradle project in "cmakelib") but my problem is resolved now so there is no need. Thanks so much for the help.

As a piece of feedback, it is awkward that the version of the android gradle plugin you have installed is apparently very important, but is also relatively hidden. I created my build.gradle by copying a build.gradle from someone else's Android project and didn't realize a particular version of the android gradle plugin had been hardcoded by it. Your installed version(s) of the Android Gradle plugin aren't listed in the Android Studio sdk tools like other things, it doesn't show up in gradlew -v. While I was getting the error I was trying to find a way of getting Gradle to tell me which versions of the plugins I was loading (in case— as eventually turned out to be happening-- I was requesting 3.5.2 but actually getting something else) and wasn't able on my own to figure out how to do this. The docs I saw (for example, the final section of https://developer.android.com/studio/projects/install-ndk#apply-specific-version ) did not make it clear that the features being discussed were version-dependent or even that plugin version is something you need to be aware of (I initially assumed the android plugin automatically upgraded when you upgrade Android Studio). It's possible I just wasn't paying attention or didn't read the right document!, but also maybe the plugin version could be made a little more visible.

On Thursday, January 23, 2020 at 4:02:45 PM UTC-5, Dan Albert wrote:
Can you share your build.gradle files? It sounds like you've done it correctly, but the behavior you're describing doesn't match what I'd expect.
 
Is this com.android.tools.build:gradle the "the gradle plugin" which you and Dan Albert mention? What is its proper name? "The Android Gradle plugin"?

Yes and yes. I just can never remember the full artifact name. "Android Gradle Plugin" or just "AGP" is mostly what you'll hear.
 
Is there some way for me to get a list of which versions of this plugin I have installed on a given machine (so I can delete old versions if needed)?

 Okay, this is *very* helpful. However now I am confused because you say "3.6 is the latest stable", but looking at this page:
https://developer.android.com/studio/releases/gradle-plugin
The newest version it lists is 3.5.2. Is this a documentation fault or are we talking about something other than "the Android Gradle plugin"?

That's my mistake. I thought 3.6 was stable since to me it feels like 4.0 is getting close, but 3.6 is still in RC.

Is there a place which canonically lists the versions/newest stable version of the Android Gradle plugin?

https://maven.google.com/web/index.html. Search for gradle and expand the com.android.tools.build -> gradle section and you'll get a list of published versions. Stable versions are just the ones that aren't explicitly labeled as alpha/beta/rc or something like that.

I'm guessing this thread is probably the best documentation for any of the above currently. It's kind of discussed at https://developer.android.com/studio/projects/install-ndk, but doesn't contain most of those details. I'll try to find some time to get this info into our actual docs.

Dan Albert

unread,
Jan 23, 2020, 7:56:46 PM1/23/20
to android-ndk
Glad you found the answer!

Agreed that gradle behavior is pretty confusing at first. It's sort of described here, but not very well. I'll see if we can get that improved (there are a lot of different interacting components, so keeping it brief enough to be comprehensible while also getting enough detail to be useful is a tough balance). Thanks for the feedback on that, having the details helps quite a bit. Feel free to raise issues whenever the docs aren't good enough. I'm always happy to help get those triaged if they aren't something I can fix myself.

To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/30bf2c4f-8438-4927-a798-0db6e257c704%40googlegroups.com.

Jomo Fisher

unread,
Jan 24, 2020, 11:32:38 AM1/24/20
to Dan Albert, android-ndk, Arif Sukoco
Looks right to me. I would add that, in AS 3.5+, you will get a deprecation warning if ANDROID_NDK_HOME is set. Support for this environment variable will be removed in a future release.

Andi McClure

unread,
Jan 27, 2020, 2:27:22 PM1/27/20
to android-ndk
Okay. Understood, though I'd like to note my objection to this change. As well as being slightly easier to script, setting ANDROID_NDK_HOME is easier to describe to my project's users than describing to them how to create a local.properties file.


On Friday, January 24, 2020 at 11:32:38 AM UTC-5, Jomo Fisher wrote:
Looks right to me. I would add that, in AS 3.5+, you will get a deprecation warning if ANDROID_NDK_HOME is set. Support for this environment variable will be removed in a future release.

On Thu, Jan 23, 2020 at 12:38 PM Dan Albert <dana...@google.com> wrote:
+jomof in case I got any of the facts wrong here.
 
I maintain a list of instructions for setting up a new machine so it would be great if everything could just work in the .gradle file out of the box without needing to input system-configuration-specific like the version of NDK installed

Your best bet would be to upgrade to 3.6 or higher (3.6 is the latest stable atm but once 4.0 is out that'll also work),  of the gradle plugin. The behavior of which NDK gets used has improved over the recent releases.

Pre 3.5: ndk-bundle would be used. It was up to users to make sure they had the right version for the project they were building.
3.5: android.ndkVersion is used, otherwise the newest installed NDK would be used
3.6: android.ndkVersion is used, otherwise each version of the gradle plugin has a default version of the NDK, so you don't need to specify anything in your build.gradle unless you have a reason to use something other than the default.

Caveat for all (current) versions: ndk.dir or ANDROID_NDK_HOME will override the behaviors above. For 3.5+, if the android.ndkVersion does not match it is an error (or perhaps just a warning), but of nothing is explicitly specified for android.ndkVersion then ndk.dir or ANDROID_NDK_HOME will be used. These are probably going away in the future to improve predictability here.

3.6+ is going to give you the best chance of having a reproducible build on any given machine. AIUI currently gradle won't automatically download the NDK unless there's an explicit android.ndkVersion specified, but I think there's a pop up in AS that starts the download if they don't already have it. Without AS, users will need to use the SDK manager to get the correct NDK themselves. (I'm not really a fan of this behavior, and am trying to get it changed to just always do the download if needed by the project, but that won't happen until after 4.0.)

On Thu, Jan 23, 2020 at 10:29 AM Andrew Esh <andr...@qterics.com> wrote:
Does you local.properties file contain a definition for "ndk.dir" which points at a valid NDK directory? In Android Studio, File->Project Structure->Android NDK Location menu sets this value.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to andro...@googlegroups.com.

Dan Albert

unread,
Jan 27, 2020, 3:14:52 PM1/27/20
to android-ndk
ANDROID_NDK_HOME is easier to describe to my project's users than describing to them how to create a local.properties file.

The goal is that they'll need to do neither. Your build.gradle will pick an NDK version (or it'll use the default, but wait for AGP 3.6 before doing that) and your users will never have to think about it. If you explicitly specify your NDK version that's the behavior today, but using the default they'll need to manually download (which I think is something that should be fixed).

To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/45684a40-655a-4d3e-9dbf-c5fab2e4aaa4%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages