使用gradle构建和链接多个NDK库

5

我有一个Android项目,将一堆源代码链接在一起形成单个的JNI库。我想将这个单个库拆分成多个较小的库,并在它们之间建立一些依赖关系。如何使用新的gradle构建系统实现这一点?


1
你好,我有完全相同的疑虑,你找到实现这个的方法了吗?谢谢。 - Alejandro Zurcher
1个回答

1
你可以使用实验性Gradle插件系列中的独立Android原生插件来实现此目标。新插件基于Gradle组件方法对构建进行建模。使用新系统有许多优点
例如:
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。请注意,静态链接一堆东西到STL是不好的,因为您将最终得到多个STL副本。这可能会真正搞砸事情。
请注意,默认的gcc工具链现已停用。最好使用:
model {
    android {
        ndk {
            toolchain 'clang'
            stl 'c++_shared'
        }
    }
} 

最后,你绝对不需要一个aar,我只是为了完整性而包含它。应用程序项目可以直接依赖于独立的本地库项目,因为应用程序插件也完全支持NDK。

我的C语言经验有限,请原谅我提出一些愚蠢的问题: 1)什么是“lub”? 2)导出的头文件字段只是C头文件的位置,没有什么特别之处吗?和我们以前在LOCAL_C_INCLUDES中使用的一样吗? - Anthony
@Anthony 关于问题 #2,是的。它指的是你链接的组件公共 API 所在的位置。其他 Gradle 项目需要知道如何找到它们所依赖的组件的头文件。 - dcow
你是否成功创建了多个依赖项? dependencies { project ":lib" project ":lub" } 只获取第一个项目。如果我交换它们,缺失的依赖项就会切换,但似乎不会添加两者。 - Anthony
@Anthony 多重依赖项对我来说可行。你有什么方面的问题? - dcow
基本上,无论哪个依赖项排在第二位,都会导致大量与第二个依赖项相关的“未定义引用”。如果我交换依赖项的顺序,那么我会在另一个库中得到同样的结果。我已经为此提出了一个问题,我们可以在那里继续讨论,如果我们解决了这个问题,就可以给予信用: http://stackoverflow.com/questions/35964577/android-native-dependencies - Anthony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接