Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to specify NDK_TOOLCHAIN_VERSION in gradle file for android ndk build

I am moving my Android project that uses ndk-build to use the gradle build system as described in the examples of the new build tools for android. In this link http://tools.android.com/tech-docs/new-build-system. I am looked at the gradle-samples-0.11 at the bottom of the page for inspiration.

So I managed to configure all of the pieces I need by including the following code in my build.gradle default config section.

ndk {
            moduleName "MyModuleName"
            ldLibs "log"
            cFlags "-std=c++11 -fexceptions"
            stl "gnustl_static"
}

I have this line in my Application.mk file in the original project: NDK_TOOLCHAIN_VERSION := 4.9 It is the last piece I can't configure.

I am using NDK Revision 10. I need this NDK_TOOLCHAIN_VERSION:=4.9 because my build is reporting Error:(25, 11) error: expected nested-name-specifier before 'Integer' and the c++ code at that line looks like this.

using Integer = int16_t;

Does anyone have an idea on how I can solve this, please?

like image 718
maiatoday Avatar asked Aug 26 '14 14:08

maiatoday


2 Answers

I've been trying to solve this too. But in the ended up by writing custom tasks to make Android Studio use Application.mk and Android.mk just like in eclipse.

My build.gradle looks like this

apply plugin: 'com.android.application'

android {

    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 20
        versionCode 1
    }

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }

    sourceSets.main {
        jniLibs.srcDir 'src/main/libs'
        jni.srcDirs = [] //disable automatic ndk-build call
    }
}

task buildNative(type: Exec) {
    def ndkBuild = null;
    def ndkBuildingDir = new File("src/main/jni");
    def hasNdk = false;
    if (System.getenv("NDK_BUILD_CMD") != null) {
        hasNdk = true;
        ndkBuild = new File(System.getenv("NDK_BUILD_CMD"))
    }

    commandLine ndkBuild, "--directory", ndkBuildingDir

    doFirst {
        if (!hasNdk) {
            logger.error('##################')
            logger.error("NDK build failed!!")
            logger.error('Reason: NDK_BUILD_CMD not set.')
            logger.error('##################')
        }
        assert hasNdk: "NDK_BUILD_CMD not set."
    }
}
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn buildNative }

task cleanNative(type: Exec) {
    def ndkBuild = null;
    def ndkBuildingDir = new File("src/main/jni");
    def hasNdk = false;

    if (System.getenv("NDK_BUILD_CMD") != null) {
        hasNdk = true;
        ndkBuild = new File(System.getenv("NDK_BUILD_CMD"))
    }

    commandLine ndkBuild, "--directory", ndkBuildingDir, "clean"

    doFirst {
        if (!hasNdk) {
            logger.error('##################')
            logger.error("NDK build failed!!")
            logger.error('Reason: NDK_BUILD_CMD not set.')
            logger.error('##################')
        }
        assert hasNdk: "NDK_BUILD_CMD not set."
    }
}
clean.dependsOn 'cleanNative'

For this to work, you need to set an environment variable NDK_BUILD_CMD to be set the the exact ndk-build executable.

On Windows, you can just set an environment variable NDK_BUILD_CMD point to your ndk-build.exe

On Mac,the path variables you set in your .bash_profile is not accessible on GUI applications(hence Android Studio will not be able to read them). So edit your .bash_profile to be something like

GRADLE_HOME={path_to_gradle}
ANDROID_SDK_ROOT={path_to_sdk_dir}
ANDROID_HOME=$ANDROID_SDK_ROOT/platform-tools
ANDROID_NDK_HOME={path_to_ndk}
NDK_BUILD_CMD=$ANDROID_NDK_HOME/ndk-build 

export PATH=$GRADLE_HOME/bin:$ANDROID_HOME:$ANDROID_SDK_ROOT/tools:$ANDROID_NDK_HOME:/opt/local/bin:/opt/local/sbin:$PATH

launchctl setenv GRADLE_HOME $GRADLE_HOME
launchctl setenv ANDROID_HOME $ANDROID_HOME
launchctl setenv ANDROID_NDK_HOME $ANDROID_NDK_HOME
launchctl setenv NDK_BUILD_CMD $NDK_BUILD_CMD

The launchctl lines will make your environment variables visible inside your Android Studio. PS: The .bash_profile is run every time you open the terminal. So for this to work properly with Android Studio, you need to launch the terminal once and then run Android Studio. Otherwise the build will fail saying NDK_BUILD_CMD not set. I haven't found any way to set the values when Mac starts. If someone else can find a way, please feel free to suggest.

like image 62
Sugesh Avatar answered Oct 18 '22 04:10

Sugesh


I've just had this problem, but my solution was actually in your initial question. The latest version of the NDK uses GCC 4.9 by default (https://developer.android.com/tools/sdk/ndk/index.html). This is only default on a 64bit machine it would seem. So you no longer need to set the NDK_TOOLCHAIN_VERSION property in your build.gradle file. So simply setting:

cFlags "-std=c++11 -fexceptions"
stl "gnustl_static"

in ndk{} Should be enough. Works for me.

like image 34
docjaq Avatar answered Oct 18 '22 05:10

docjaq