bar*_*cha 9 c++ java android multiplatform android-ndk
我有一个奇怪的问题.我有一个aar库,它包含并使用本机.so库.现在,我想编写另一个lib,它依赖于该库,并且还具有本机部分,具体取决于来自第一个lib的本机lib.依赖库使用第一个lib中的本机代码和java包装器.
我想知道,有没有办法,如何通过标准gradle依赖(从第一个lib复制的头文件)来做到这一点?或者让我直接从源代码构建第二个库?
为什么我需要这个:我们有一个基本功能的多平台lib,对于android as aar.这个lib可以在标准的android应用程序中使用,我们在多个项目中使用它,它没有其他本机代码.
但在一个应用程序中,我们想要编写多平台共享应用程序代码,具体取决于lib,我希望将这些库分开.
谢谢!
这是一个可行的基本示例OpenCV,您可以为您做同样的事情first lib.
打包jar,*.so导出headers(请参阅OpenCV4Android/opencv/build.gradle链接项目中的文件如何将标题附加到aar).
你可以first.aar从建筑物中获得first lib.
first.aar在需要时添加其他项目.
allprojects {
repositories {
jcenter()
flatDir {
dirs '/path/to/aar'
}
}
}
// in your app's build.gradle
dependencies {
// ...
compile 'com.example:example-with-header@aar'
// ...
}
Run Code Online (Sandbox Code Playgroud)
将本机库链接到first.aar本机构建系统.
如果你使用CMake,它应该是这样的
add_library(first
SHARED
IMPORTED)
set_target_properties(
first
PROPERTIES IMPORTED_LOCATION
../../../../build/intermediates/exploded-aar/org.example/example-debug/jni/${ANDROID_ABI}/libfirst.so
# use find command to figure out the location of the first lib before use it, not sure if it's different in different build environment
# for android studio gradle plugin latest version use
# ../../../../build/intermediates/transforms/mergeJniLibs/debug/folders/2000/1f/main/lib/${ANDROID_ABI}/libfirst.so
)
# also use find command to figure the actual location of the exported header from aar
# this might be different in your environment for different version of gradle plugin
include_directories(build/intermediates/exploded-aar/com.example/example-debug/cpp/include)
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
first
${log-lib} )
Run Code Online (Sandbox Code Playgroud)
正如您提到的 Gradle,我假设您正在使用最新的 Android Studio。我使用的是 1.2.2,发现从许多教程中构建简单的 NDK 项目很容易,但构建任何复杂的 NDK 项目却非常困难。我将总结我的发现,但我强烈建议阅读 此博客 和StackOverflow。
我的项目和你的类似,但不完全一样。对我来说,诀窍是弄清楚如何让 Android Studio 使用我的 Android.mk,然后找到正确的 makefile 变量。希望这会有所帮助。
原生 Android Studio 将完全忽略您创建的任何自定义 Android.mk 文件,而是自动生成自己的文件。要纠正此问题,您必须首先破解项目的build.gradle
脚本,该脚本位于project/app/build.gradle。如果需要,您可能可以破解顶级 build.gradle。
这是我破解的 build.gradle。我是在 Windows 机器上构建的,所以我只针对 Windows 进行了修改。如果您使用的是 OSX 或 Linux,请取消注释这些行。
项目/应用程序/build.gradle:
//import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.sample.app"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//ENABLE CUSTOM ANDROID.MK >>
sourceSets.main.jni.srcDirs= [] //Disable automatic ndk-build.
sourceSets.main.jniLibs.srcDir 'src/main/libs'
//Call regular ndk-build script from app directory
task ndkBuild(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd()
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task cleanNative(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd(), 'clean'
}
clean.dependsOn cleanNative
}
//ENABLE CUSTOM ANDROID.MK <<
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:7.5.0'
}
//ENABLE CUSTOM ANDROID.MK >>
def getNdkDir() {
if (System.env.ANDROID_NDK_ROOT != null)
return System.env.ANDROID_NDK_ROOT
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkdir = properties.getProperty('ndk.dir', null)
if (ndkdir == null)
throw new GradleException("NDK location not found. Define location with ndk.dir in the local.properties file")
return (ndkdir)
}
def getNdkBuildCmd() {
def ndkbuild = getNdkDir() + "/ndk-build.cmd"
// def ndkbuild = getNdkDir() + "/ndk-build"
// if (Os.isFamily(Os.FAMILY_WINDOWS))
// ndkbuild += ".cmd"
return ndkbuild
}
//ENABLE CUSTOM ANDROID.MK <<
Run Code Online (Sandbox Code Playgroud)
现在我可以创建我的多库 Android.mk。这将构建两个静态链接库,然后构建最终的动态链接库和前两个库中的链接。涉及到的目录有:
目录:
project/
app/
build.gradle
src/
main/
java/
jni/
Android.mk
include/
libmp3lame/
MiniMp3/
mp3_jni.c
mpglib/
Run Code Online (Sandbox Code Playgroud)
Android.mk:
TOP_PATH := $(call my-dir)
LOCAL_PATH := $(TOP_PATH)/libmp3lame
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := libmp3lame
LOCAL_SRC_FILES := \
bitstream.c \
...
version.c
include $(BUILD_STATIC_LIBRARY)
MY_LOCAL_STATIC_LIBRARIES += libmp3lame
LOCAL_PATH := $(TOP_PATH)/mpglib
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_C_INCLUDES += $(TOP_PATH)/libmp3lame
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := mpglib
LOCAL_SRC_FILES := \
common.c \
...
tabinit.c
include $(BUILD_STATIC_LIBRARY)
MY_LOCAL_STATIC_LIBRARIES += mpglib
LOCAL_PATH := $(TOP_PATH)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TOP_PATH)/include
LOCAL_CFLAGS := -DSTDC_HEADERS
LOCAL_MODULE := Mp3
LOCAL_STATIC_LIBRARIES := $(MY_LOCAL_STATIC_LIBRARIES)
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
./mp3_jni.c
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
您需要调整 Android.mk。
| 归档时间: |
|
| 查看次数: |
3038 次 |
| 最近记录: |