Skip to content

Configure NDK Path

gfan edited this page May 2, 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):

  • in this doc, Android Studio is the same as Android Gradle Plugin(AGP)
  • AGP version is in project's build.gradle:
    classpath 'com.android.tools.build:gradle:4.1.0-alpha02'

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! 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 ndkVersion 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 to use NDK is the ndkVersion way:

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 install NDK yourself with AGP 3.6.

Under the hood

For the apps that do not use ndkVersion, AGP 3.6 and later versions embed a 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 default NDK version, AGP 3.6+ searches NDK in the following locations for the needed version:

Location using ndkVersion without ndkVersion
$SDK/ndk/${ndk-version} required version the internal default NDK Version
$SDK/ndk-bundle required version(deprecated) the internal default NDK version(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 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](#ndkversion) way, NDKs are expected to be installed in a new default location

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

Refer to ndkVersion for additional information about the feature.

From AGP 3.5 and onward, developers are recommended to use the ndkVersion:

  • configure your NDK version to android.ndkVersion in module’s build.gradle
  • with Android Studio, the required NDK will be prompted to download if not there
  • if using command line environment or CI, you need to 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 ndkVersion considered, AGP 3.5 finds the matching NDK in the following locations:

NDK Location with ndkVersion non-ndkVersion
$SDK/ndk/${ndk-version} required version the newest NDK there
$SDK/ndk-bundle required version any version
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:

  • ndk.dir in local.properties
  • ANDROID_NDK_HOME environment variable
  • $SDK/ndk-bundle (default location for Studio 3.4)

Refer to “Install NDK” for NDK installation details.

NDK Version Specification

There are 4 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 exact NDK version format in 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 work!

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

The recommendation is:

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

The 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, as it is now for Android R time, 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 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 available only 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

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 the “SDK Manager Toolkit”

  2. left hand pane, “Appearance & Behaviour” > “System Settings” > “Android SDK”

  3. tab “SDK Tools”

  4. enable “Show Package Details” at the lower right corner

  5. Select NDK

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

      • expand “NDK(Side by Side)”
      • 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

  6. “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}/cmdline-tools/latest/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

Note: depending on your SDK version, your sdkmanager tool might be under tools/bin.

Example:

${sdk}/tools/bin/sdkmanager --channel=3 --install "ndk;21.1.6273396"

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

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

For additional sdkmanager usages, refer to the formal documentation.

The Manual Way

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 the same 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 way. Please refer to NDK Version Specification for your specific AGP version’s requirement about version string format!

non-ndkVersion

If application does not use the new ndkVersion feature, Studio is working in the legacy mode:

  • legacy mode = !android.ndkVersion

We strongly recommend developers to use the modern ndkVersion way!

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

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

please remember to remove the 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: one gets changed, the other will be mirrored automatically; you could find “Android NDK location” under “File” > “Project Structure” > “Android NDK location”:

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 was 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 got populated into ndk.dir/Studio IDE
  • ANDROID_NDK_HOME is old and deprecated

The replacement for ANDROID_NDK_HOME is the modern_ 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 ndkVersion feature, and
  • the default version 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 ndkVersion were set with the following:

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

From here, all android.ndkVersion path searching rules apply, check the related AGP version description in this documentation for the expected 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.