【问题标题】:Build and link multiple NDK libraries using gradle使用 gradle 构建和链接多个 NDK 库
【发布时间】:2014-06-24 13:56:36
【问题描述】:

我有一个 Android 项目,它将一堆源代码链接到一个单一的整体 JNI 库中。我想将这个单个库拆分为多个较小的库,它们之间存在一些依赖关系。如何使用新的 gradle 构建系统实现这一目标?

【问题讨论】:

  • 您好,我也有同样的担忧,您找到实现此目的的方法了吗?问候。

标签: android-ndk gradle


【解决方案1】:

您可以使用来自experimental gradle plugin family 的独立安卓原生插件来实现这一点。新插件基于gradle component approach towards modeling builds。有many advantages to using the new system

例如:

root
+ lib -> 'com.android.model.native'
+ lub -> 'com.android.model.native'
+ aar -> 'com.android.model.library'
+ app -> 'com.android.model.application'

build.gradle

configure([project(':lib'), project(':lub'), project(':aar'), project(':app')]) {
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha5'
        }
    }
}

lib/build.gradle

apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion 23
    ndk {
        moduleName "foo"
    }
    sources {
        main {
            jni {
                exportedHeaders {
                    srcDir "src/main/headers"
                }
            }
        }
    }
}

lub/build.gradle

apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion 23
    ndk {
        moduleName "bar"
    }
    sources {
        main {
            jni {
                exportedHeaders {
                    srcDir "include"
                }
            }
        }
    }
}

aar/build.gradle

apply plugin: "com.android.model.library"

model {
    android {
        buildToolsVersion '23.0.2'
        compileSdkVersion 23
    ndk {
        moduleName "aggregate-jni"
        stl "stlport_shared" // using cpp?
    }
    sources {
        main {
            jni {
                dependencies {
                    project ":lib"
                    project ":lub"
                }
            }
        }
    }
}    

app/build.gradle

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

model {
    android {
        buildToolsVersion '23.0.2'
        compileSdkVersion 23 

        defaultConfig {
            applicationId "com.example.app"
            minSdkVersion.apiLevel 21
            targetSdkVersion.apiLevel 23
            versionCode 1
            versionName "1.0"
        }
    }
}

dependencies {
    compile project(':aar')
}

如果链接是动态的(ndk 的默认值),aar 将包含:

libfoo.so libbar.so libaggregate-jni.so libstlport.so

还有你的镜像 java 类。你可以简单地

System.load("aggregate-jni");

在您的 java 类和引用的库中也会加载。如果链接是静态的,那么无论如何您最终都会得到一个 libaggregate-jni.so。请注意,像end up with multiple copies of the stl in your binary 那样将一堆东西静态链接到 stl 是不好的。这真的会把事情搞砸。

注意默认gcc toolchain is now deprecated。最好使用:

model {
    android {
        ndk {
            toolchain 'clang'
            stl 'c++_shared'
        }
    }
} 

最后,您绝对不需要 aar,我只是为了完整性而将其包括在内。应用程序项目可以直接依赖独立的原生库项目,因为应用程序插件也完全支持 ndk。

【讨论】:

  • 我在 c 方面的经验有限,所以请原谅几个无知的问题:1)什么是“lub”? 2)导出的headers字段就是c头文件的位置,没什么特别的吧?我们之前会提供给 LOCAL_C_INCLUDES 的东西是一样的吗?
  • @Anthony re #2 是的。它是构成您要链接的组件的公共 API 的标头的位置。其他 gradle 项目需要知道在哪里可以找到它们所依赖的组件的标头。
  • 你是否成功创建了多个依赖? dependencies { project ":lib" project ":lub" } 只抢第一个项目。如果我交换它们缺少的依赖项开关,但它似乎并没有同时添加。
  • @Anthony 多个依赖项对我有用。哪个方面不适合您?
  • 基本上,无论哪个依赖项次之,都会导致大量与第二个依赖项相关的“未定义引用”。如果我交换依赖项的顺序,那么我在另一个库中得到相同的东西。我为它提出了一个问题,我们可以在那里继续讨论,所以如果我们弄清楚了,可以给予信用:stackoverflow.com/questions/35964577/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多