如何使用 Gradle 为 Android NDK 指定外部 C++ 源文件夹

How to specify external C++ source folders for Android NDK with Gradle

我想将一些不在项目树中的 C++ 源文件添加到我的 Android Studio 项目中。我是 Gradle 的新手,并尝试尽可能多地研究它。根据我的阅读,以下 build.gradle 文件应该可以工作,但实际上没有。关于 jni.sourceDirs 的部分来自这个 post:http://www.shaneenishry.com/blog/2014/08/17/ndk-with-android-studio/

这是正确的方法吗?

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.mycompany.myapp"
        minSdkVersion 22
        targetSdkVersion 22

        ndk {
            moduleName "mymodule"
            ldLibs "log"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    sourceSets.main {
        jni.srcDirs '../external/source/dir'
    }
}

看看我关于这个的文章: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

There are two things you need to know here. By default, if you have external libs that you want loaded into the Android application, they are looked for in the (module)/src/main/jniLibs. You can change this by using setting sourceSets.main.jniLibs.srcDirs in your module’s build.gradle. You’ll need a subdirectory with libraries for each architecture you’re targeting (e.g. x86, arm, mips, arm64-v8a, etc…)

The code you want to be compiled by default by the NDK toolchain will be located in (module)/src/main/jni and similarly to above, you can change it by setting sourceSets.main.jni.srcDirs in your module’s build.gradle

以及来自该页面的示例 Gradle 文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.sureshjoshi.android.ndkexample"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
            cFlags "-std=c++11 -fexceptions" // Add provisions to allow C++11 functionality
            stl "gnustl_shared" // Which STL library to use: gnustl or stlport
        }
    }

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

此外,在 /jni 目录外部指定时,尝试使用完整构建路径(使用宏之一,例如):

'${project.buildDir}/../../thirdParty/blah/blah/'

到这里,你明白了:

android.ndk {
    moduleName = "mydemo"

    //Specify a library relative to this project path
    CFlags.add('-I' + String.valueOf(project.buildDir) + '/../my/inc/path')

    //or CPP
    cppFlags.add('-I' + String.valueOf(project.buildDir) + '/../my/inc/path')

    //Linker works the same way
    ldFlags.add("-L/custom/lib/path")
    ldLibs.addAll(["log", "GLESv2", "myCustomLibrary"])
}

目前,使用 'gradle-experimental:0.7.3' 这个定义有点改变。 在这个新版本中,要设置为 'srcDirs' 的对象必须是可迭代对象,因此可以包含多个 c++ 源路径。

在下一个示例中,包含两个文件夹,当前主文件夹 ('src/main/jni') 和 [=18= 中的第二个文件夹 ('../../common') ] 项目文件夹树:

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion  23
        buildToolsVersion  "23.0.2"
        defaultConfig.with {
            applicationId  "com.test.androidTest"
            minSdkVersion.apiLevel  21
            targetSdkVersion.apiLevel  23
            versionCode = 1
            versionName = "1.0"
       }
    }

    android.ndk {
        moduleName = "jni_lib_name"
        platformVersion = 9
        toolchain "gcc"
        debuggable true
        cppFlags.add("-fexceptions")
        cppFlags.add("-std=c++14")

        ....
    }

    android {
        sources {
            main {
                jni {
                    source {
                        srcDirs = ["src/main/jni".toString(), "../../common".toString()]
                    }
                }
            }
        }
    }

    ...
}