Skip to content

Configure NDK Path

Gerry edited this page Apr 16, 2020 · 7 revisions

Introduction

This document guides developers through NDK configuration in recent Android Gradle Plugin (AGP) versions. For Android Studio, this document assumes it uses the same version of Android Gradle Plugin (AGP).

The possible directories that AGP locates NDK are:

Android Studio/Gradle Plugin Version
4.1 4.0 - 3.6 3.5 3.4
Default NDK Location $SDK/ndk/$version

$SDK/ndk-bundle

$SDK/ndk/$version

$SDK/ndk-bundle

$SDK/ndk/$version

$SDK/ndk-bundle

$SDK/ndk-bundle
ndkPath available Not available Not available Not available
ANDROID_NDK_HOME removed deprecated deprecated available
ndk.dir deprecated available available available

The related available features that could affect which version of NDK to use are:

Android Studio/Gradle Plugin Version
4.1 4.0 3.6 3.5 3.4
ndkVersion defines specific NDK version Not available
Default NDK Version assign one NDK version by AGP Not available Not available
Autodownload $default & $ndkVersion $ndkVersion not available not available not available

Out of the NDK path configuration channels,

ndkVersion feature added in version 3.5 and above provides a major flexibility for applications: NDK dependency moves from project level to module level, and we strongly recommend developers to take full advantage of the feature.

With the addition of android.ndkVersion, Android Studio may work in 2 ways:

  • ndkVersion way: where android.ndkVersion is used in the application
  • legacy way: NDK version does not matter to your application -- any one would work

The motivation for the evolutions is:

  • NDK usage is being integrated into build.gradle DSL
  • let sdkmanager tool to manage NDK installation

Configure NDK for Android Gradle Plugins

This section outlines the NDK path resolution with regard to recent Android Studio/Android Gradle Plugin versions; assuming that Android Studio uses the same version of AGP, the instructions directly apply to Android Studio IDE.

NDK with AGP 4.1

With AGP 4.1, NDK path configuration is automatically done with:

  • if you need a specific NDK for any module, use ndkVersion in module’s build.gradle
  • otherwise, make sure do not use ndkVersio and AGP will behave as if ndkVersion was set to the default NDK version

If you have the needed NDK versions on your local system, it will be used; otherwise, AGP 4.1 will automatically download it to the $SDK/ndk/$version and proceed to build.

That is all for AGP 4.1! If you want to know more, read onto the next section.

Under the hood

AGP 4.1.x, added the android.ndkPath to support some special usage cases such as that your own NDK must be in certain locations or even have your own customized NDK; on the other hand, AGP 4.1 deprecates ndk.dir and $SDK/ndk-bundle. Taking all of the possible ways into the consideration, AGP 4.1 searches the needed NDK in the following directories:

NDK Location if using ndkVersion if not using ndkVersion
$SDK/ndk/${ndk-version} the exact version the internal default NDK Version
$SDK/ndk-bundle the exact version(deprecated) the internal default NDK version (deprecated)
android.ndkPath Not Used any version
ndk.dir the exact version (deprecated) any version(deprecated)

With the above, you could use any NDK locations to configure your local development system to fit your special needs.

NDK with AGP 4.0 and 3.6

The correct way is to use NDK is ndkVersion way:

  • configure your NDK version to

>>>> GDC alert: undefined internal link (link text: "android.ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

android.ndkVersion in module’s build.gradle;

  • if building from command line with gradle, you need to

>>>> GDC alert: undefined internal link (link text: "install the NDK"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

install the NDK

The location for NDK is $SDK/ndk/$ndk-version. One noticeable difference is that AGP 4.0, when used inside Android Studio IDE, will auto download the needed NDK version if it is NOT installed locally; you need to

>>>> GDC alert: undefined internal link (link text: "install NDK"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

install NDK yourself with AGP 3.6.

Under the hood

For the apps that do not use

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion, AGP 3.6 and later versions embed a

>>>> GDC alert: undefined internal link (link text: "default NDK version"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

default NDK version, which is the NDK version used to test this AGP version at the release time. The purpose is to offer a “known good” NDK for applications that does not specify any particular NDK.

Including the

>>>> GDC alert: undefined internal link (link text: "default NDK version"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

default NDK version, AGP 3.6+ searches NDK in the following locations for the needed version:

Location using

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion

without

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion

$SDK/ndk/${ndk-version} required version

>>>> GDC alert: undefined internal link (link text: "the internal default"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

the internal default

>>>> GDC alert: undefined internal link (link text: "AGP ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

AGP ndkVersion

$SDK/ndk-bundle required version

(deprecated)

>>>> GDC alert: undefined internal link (link text: "the internal default"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

the internal default

>>>> GDC alert: undefined internal link (link text: "AGP ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

AGP ndkVersion

(deprecated)

ndk.dir required version any version

The above behaviour provides some flexibility when developers have to customize NDK path.

NDK with AGP 3.5

Android Gradle Plugin(AGP) 3.5.x added the

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion feature (also called NDK “side by side”, SxS, means multiple NDKs could be installed under the same directory) to support NDK dependency at module level: different modules could use different NDKs to build a single application or multiple applications. ndkVersion creates a new NDK default location at $SDK/ndk/$version:

Under ndkVersion way, NDKs are expected to be installed in a

>>>> GDC alert: undefined internal link (link text: "new default location"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

new default location

    $SDK/ndk/${ndk-version-1}
    $SDK/ndk/${ndk-version-2}

Refer to

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion for additional information about the feature.

From AGP 3.5, developers are recommended to use the

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion:

  • configure your NDK version to android.ndkVersion in module’s build.gradle
  • with Android Studio, the required NDK will be prompted to download automatically if not there
  • if using command line environment or CI, you need to

>>>> GDC alert: undefined internal link (link text: "install the NDK"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

install the NDK

and that is all to get NDK working with Android Gradle Plugin/Android Studio 3.5.

Under the hood

With this great

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion considered, AGP 3.5 finds the matching NDK in the following locations:

NDK Location with

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion

>>>> GDC alert: undefined internal link (link text: "non-ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

non-ndkVersion way

>>>> GDC alert: undefined internal link (link text: "$SDK/ndk/${ndk-version}"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

$SDK/ndk/${ndk-version}

required version the newest NDK there

>>>> GDC alert: undefined internal link (link text: "$SDK/ndk-bundle"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

$SDK/ndk-bundle

required version any version

>>>> GDC alert: undefined internal link (link text: "ndk.dir"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndk.dir

required version any version

NDK with AGP 3.4

Android Gradle Plugin 3.4 is legacy now, configuring NDK path is relatively fixed and straightforward:

>>>> GDC alert: undefined internal link (link text: "ndk.dir"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndk.dir in local.properties

  • ANDROID_NDK_HOME environment variable

>>>> GDC alert: undefined internal link (link text: "$SDK/ndk-bundle "). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

$SDK/ndk-bundle (default location for Studio 3.4)

Refer to “

>>>> GDC alert: undefined internal link (link text: "Install NDK"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

Install NDK” for NDK installation details.

NDK Version Specification

There are 3 parts to NDK version number as $major.$minor.$build-$suffix, for example, NDK 21.0.6011959-beta2:

  • major version, i.e. 21
  • minor version, i.e. 0
  • build number, i.e. 6113669
  • suffix, i.e. “beta2”,

The NDK version could be found in the ${ndk}/source.properties file; however when looking at the SDKManager or using sdkmanager command line tool, the suffix string, follows “rc”(release candidate) scheme, for example, the above version would become

  “`21.0.6011959 rc2"`

The required NDK version format in

>>>> GDC alert: undefined internal link (link text: "android.ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

android.ndkVersion are AGP version dependent:

AGP Version $major.$minor.$build$suffix $major.$minor.$build $major.$minor
4.1 / 4.0 21.0.6011959 rc2"

21.0.6011959-beta2"

all works!

"21.0.6011959" works NO
3.6 NO NO
3.5 NO "21.0" works

Recommendation is:

  • $major.$minor.$build: for AGP version 4.0/4.1, ignore the lengthy suffix format
  • $major.$minor.$build$suffix: AGP 3.5/3.6 have to use the full version, all legal suffixes string would work ( “beta”, “rc”)

regex format is not supported!

NDK Release Channels

Similar to other SDK components, NDKs are also released through different channels:

  • Stable for stable releases
  • Beta for beta release
  • Canary including developer preview NDKs

Formal releases could be installed with all installation channels, but the developer preview releases are only installable through Android SDK Manager (UI or command line tool) that has a canary channel.

Install NDKs

The preferred way is to let AGP/Android Studio (4.0+) to auto download NDK into the $SDK/ndk/$version.

For AGP versions that could not auto-download NDK, there are at least 3 common ways available to install NDK, probably the easiest one is to use the sdkmanager tool (UI or the command line version) shipped inside Android SDK for best compatibility purpose with your AGP version.

SDK Manager UI

Before using SDK Manager, if you need to install NDKs only available on canary channel, you would need to turn it on. Canary Channel could be enabled inside Android Studio IDE:

  • Preferences > Appearance & Behavior > System Settings > Updates \

>>>> GDC alert: inline image link here (to images/Untitled-document0.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>

alt_text

SDK Manager GUI is integrated into Android Studio IDE. You could start SDK Manager GUI within Android Studio IDE:

  1. menu Tools > SDK Manager, or use “SDK Manager Toolkit”

>>>> GDC alert: inline image link here (to images/Untitled-document1.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>

alt_text

  1. left hand pane, “Appearance & Behaviour” > “System Settings” > “Android SDK”
  2. tab “SDK Tools”
  3. enable “Show Package Details” at the lower right corner \

>>>> GDC alert: inline image link here (to images/Untitled-document2.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>

alt_text

  1. Select NDK
    1. for Android Studio 3.5.0+, install “Side by Side NDK”

      1. expand “NDK(Side by Side)”
      2. select the right version you need

      NDK will be installed to ${sdk}/ndk/${selected_version}

    2. for Android Studio versions before 3.5.0, select “NDK”:
      the latest NDK at the time will be picked up automatically, and installed to ${sdk}/ndk-bundle

  2. “Apply” or “OK” button to install NDK.

The sdkmanager command line tool

The sdkmanager command line tool shipped inside SDK could also be used to install all NDKs; for some scenarios like CI environment, the command line tool might be more helpful. The generic syntax for NDK purpose is:

${sdk}/tools/bin/sdkmanager --install "ndk-selection"  --channel=${channel}

the relevant options are

  • ndk-selection:
    • ndk;${your-ndk-version}”: for “side by side” NDK; installed location is $SDK/ndk/${your-ndk-version}
    • ndk-bundle” for legacy ndk-bundle way; installed location is ${SDK}/ndk-bundle
  • channels for NDK
    • 0: Stable NDK
    • 1: beta NDK
    • 3: canary NDK, including Developer Preview NDKs

To view how many NDK versions are available, use "--list" option:

    ${sdk}/tools/bin/sdkmanager --channel=${channel} --list

For additional sdkmanager usages, refer to the formal documentation.

Manually install NDK

For some reason you need to install NDK manually, you could do that:

There might be differences comparing to the SDK Manager way to install, for example

  • currently you may not manually download canary NDKs

Terminologies

ndkVersion

In order to support multiple NDKs co-existing:

  • different NDKs to build different modules in one project
  • different NDKs to build different projects inside Studio IDE

Android Studio 3.5+ implemented the module level android.ndkVersion gradle DSL, for example in app/build.gradle :

    android {
    ndkVersion "21.1.6273396"
}

ndkVersion is the modern NDK SxS** (**side by side) way for Android Studio:

  • NDK SxS = android.ndkVersion: it is (still relatively new and) modern Studio way.

Otherwise Studio works in the old fashioned legacy mode. Please refer to

>>>> GDC alert: undefined internal link (link text: "NDK Version Specification"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

NDK Version Specification for specific AGP version’s requirement about version string format!

non-ndkVersion

If application does not use the new

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion feature, Studio is working in the legacy mode:

  • legacy mode = !android.ndkVersion

We strongly recommend developers to use the modern

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion way!

Android Studio 4.1+ added a new way to customize NDK location with android.ndkPath, for example, in module build.gradle, you could simply do:

    android {
    ndkPath "/Users/ndkPath/ndk21"  // pointing to your own NDK
}

please remember to remove ndkPath before distributing your source code: it should be left outside your version control system.

ndk.dir

Android Studio creates file local.properties at the root of the project to save project level settings including NDK and SDK paths, for example:

  • sdk.dir=/Users/ndkPath/dev/sdk
  • ndk.dir=/Users/ndkPath/dev/latest_ndk

The cached NDK path is called **ndk.dir, normally it is the first place that AGP/Android Studio looks for NDK; on the other hand, ndk.dir is deprecated from AGP 4.1.

The value of ndk.dir may come from 3 sources:

  • ANDROID_NDK_HOME environment variable when Studio starts up
  • **“Android NDK location” **within Android Studio IDE
  • brutally editing ndk.dir in local.properties file

Android NDK location” in Android Studio IDE would always be in sync with ndk.dir: change one, the other will be mirrored automatically; you could find “Android NDK location” under “File” > “Project Structure” > “Android NDK location”:

>>>> GDC alert: inline image link here (to images/Untitled-document3.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>

alt_text

Cautions for ndk.dir:

  1. ndk.dir’s setting is local to your system: file local.properties is Studio generated file; as the name implies, it is local to your development machine , and should not be distributed with source code.
  2. ndk.dir is being deprecated from AGP 4.1+.
  3. The ANDROID_NDK_HOME environment variable is deprecated from AGP 3.6+.

ANDROID_NDK_HOME

The ANDROID_NDK_HOME environment setting is the oldest of all NDK path configurations: an antique! It is the development system wise configuration: once set, it applies to all -- Android Studio reads this settings and caches it to UI/ndk.dir at starting up:

  • $ANDROID_NDK_HOME → ndk.dir/Studio IDE
  • ANDROID_NDK_HOME is old and deprecated

The replacement for ANDROID_NDK_HOME is the modern_

>>>> GDC alert: undefined internal link (link text: "ndkVersion way"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion way_: configure NDK in your modules, and install NDK to $SDK/ndk/$version

For CI purposes, the environmental variable ANDROID_NDK_HOME(deprecated) might be useful when building on the command line

  • Gradle does check ANDROID_NDK_HOME to find NDK if no local.properties file exists.
  • You could make ANDROID_NDK_HOME into your project’s ndkPath, for example, in module gradle file:
    ndkPath = System.getenv("ANDROID_NDK_HOME")

The default NDK version

AGP 3.6+ embeds a default NDK version (ANDROID_GRADLE_PLUGIN_FIXED_DEFAULT_NDK_VERSION

), the “known-good” version when a specific AGP was released for application to use if application does not specify a particular NDK version:

  • the default version will not be used when application uses

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion feature, and

  • it will not be used if application uses ndk.dir inside local.properties

Please be reminded that each AGP version has its own embedded default NDK version number.

Once the default NDK version is triggered, the application behaves as if

>>>> GDC alert: undefined internal link (link text: "ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

ndkVersion were set with the following:

    android.ndkVersion "${the-default-NDK-version}"

From here, all

>>>> GDC alert: undefined internal link (link text: "android.ndkVersion"). Did you generate a TOC?
(Back to top)(Next alert)
>>>>

android.ndkVersion path searching rules apply, check each AGP version in this documentation about the designed behaviors.

The default NDK location

Unless Android Studio/Android Gradle Plugin(AGP) is purposely configured to go to a specific local directory for NDK, the default NDK locations will be used; in that sense, the default NDK locations are behind the customized NDK location(s).

The exact default NDK location depends on AGP version:

  • $SDK/ndk/: This is the new location for ndkVersion way. Multiple NDKs could be installed under this default NDK location, like:

    • SDK/ndk/version1
    • SDK/ndk/version2 The subdirectory names under 'SDK/ndk' could be anything, sdkmanager tool by default chooses to use the ${version number}'s as sub-directory names, but you could name them freely: AGP finds the version string in source.properties packed inside NDK.
  • $SDK/ndk-bundle: existed before ndkVersion was added. It could only host one NDK version and is deprecated now but still part of the AGP’s NDK search path. Refer to the specific AGP version section for the deprecation status.

Clone this wiki locally