Android 库项目中的 NDK Dev 与 Gradle &安卓工作室 [英] NDK Dev in an Android library project with Gradle & Android Studio

查看:25
本文介绍了Android 库项目中的 NDK Dev 与 Gradle &安卓工作室的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试破解使用 JNI 的 Gradle 管理的 Android 项目,但遇到了一些麻烦.我知道 NDK 支持仍然相对较新,而且大多没有记录,但我已经设法找到了将其硬塞到 Gradle 构建中的基本元素.显然,诀窍是将所有本机代码包含在 src/main/jni 下,并将以下内容放入其中一个配置中(例如,在 defaultConfig 块中):

I've been trying to hack on a Gradle managed Android project that uses JNI and I'm having a bit of trouble. I understand NDK support is still relatively new and mostly undocumented, but I have managed to find the basic elements for shoe-horning it into a Gradle build. Apparently the trick is to include all of your native code under src/main/jni and drop the following in one of your configs (e.g. in the defaultConfig block):

ndk {
    moduleName "mylib"
}

问题是,当我尝试构建我的项目时,ndk 插件会生成一个 Android.mk 文件,其中包含到本机源的绝对路径.这会导致 make 窒息,因为它仍然认为路径是相对的.就我而言,我有一个简单的库项目,在 src/main/jni 下有 1 个 cpp 源/头文件组合,我使用这个 gradle.build:

The problem is that when I try to build my project, the ndk plugin generates an Android.mk file which includes absolute paths to the native source. This causes make to choke as it STILL considers the paths to be relative. In my case I have a simple library project with 1 cpp source/header combo under src/main/jni and I use this gradle.build:

apply plugin: 'android-library'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
        ndk {
            moduleName "mylib"
        }
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:19.+'
}

运行构建会在 build/ndk/debug 下生成这个 Android.mk:

Running the build generates this Android.mk under build/ndk/debug:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := mylib
LOCAL_SRC_FILES := \
    /Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/Android.mk \
    /Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.cpp \

LOCAL_C_INCLUDES += /Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni
LOCAL_C_INCLUDES += /Users/clifton/dev/Multi/MultiAndroid/lib/src/debug/jni

include $(BUILD_SHARED_LIBRARY)

...当运行时产生这个错误:

…which, when run generates this error:

make: *** No rule to make target `/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug//Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.cpp', needed by `/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug/obj/local/armeabi-v7a/objs/mylib//Users/clifton/dev/Multi/MultiAndroid/lib/src/main/jni/myNativeSectionTextProvider.o'.  Stop.

...因为绝对路径被错误地转换为相对路径.如果我手动编辑文件并将路径更改为相对路径:

…because the absolute paths are converted mistakenly to relative. If I manually edit the file and change the paths to relative like so:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := mylib
LOCAL_SRC_FILES := \
    ../../../src/main/jni/Android.mk \
    ../../../src/main/jni/myNativeSectionTextProvider.cpp \

LOCAL_C_INCLUDES += ../../../src/main/jni
LOCAL_C_INCLUDES += ../../../src/debug/jni

include $(BUILD_SHARED_LIBRARY)

...然后我收到此错误:

...I then get this error:

/Users/clifton/dev/Multi/MultiAndroid/lib/build/ndk/debug/../../../src/main/jni/com_craig_multiandroid_app_NativeSectionTextProvider.h:2:17: fatal error: jni.h: No such file or directory

我的问题是我能做些什么来解决这个问题?我开始破解我自己对 .aar 构建的自定义 gradle 支持,但在试图找出哪个 Gradle 任务负责生成 .aar 文件时迷路了.(Gradle 文档虽然丰富,但很难找到特定 Android Gradle 任务 API 的详细信息.)我有一个部分工作的 gradle.build 它将通过 cmd 行运行 ndk-build,生成 .so 但我可以t 弄清楚如何(或者即使我应该)将 .so 内联到 .aar 中.我使用的是 Android Studio 0.5.7 和 Gradle 1.11.几个月前我已经提取了 Gradle 源代码,这就是我想出如何在常规 .apk 项目中内联 .so 和 gdbserver 文件的方法,但这些规则似乎不适用于 .aar 项目.有没有其他人尝试过这个?我在哪里可以找到答案?

My question is what can I do to fix this? I started to hack my own custom gradle support for .aar builds but got lost trying to figure out which Gradle task is responsible for generating the .aar file. (The Gradle docs, while plentiful, make it difficult to find the details on a specific Android Gradle task API.) I have a partially working gradle.build which will run ndk-build via cmd line, generate the .so but I can't figure out how to (or even if I should) inline the .so inside the .aar. I am using Android Studio 0.5.7 and Gradle 1.11. I've pulled Gradle source a few months ago which is how I figured out how to inline the .so and gdbserver files in a regular .apk project but those rules don't seem to apply to .aar projects. Has anyone else attempted this? Where can I go for answers?

推荐答案

我终于想通了!您必须使用最新的 NDK 以获得较新的 Gradle NDK 支持.我的 local.properties(和我的 ~/.bashrc)指向 android-ndk-r8e 以解决 android-ndk-r9d 中损坏的 gdb-server 支持,但是当我更新到 android-ndk-r9d 时,我的 gradle 构建开始工作没有额外的黑客.所以总而言之,只要您的 local.properties 指向 NDK 的 9b+ 版本,上面的示例就可以工作.

I figured it out finally! You have to use the latest NDK for the newer Gradle NDK support. My local.properties (and my ~/.bashrc) was pointing to android-ndk-r8e to work around broken gdb-server support in android-ndk-r9d however when I updated to android-ndk-r9d my gradle build began to work without the extra hacks. So in summary, the above example DOES work so long as your local.properties points to version 9b+ of the NDK.

这篇关于Android 库项目中的 NDK Dev 与 Gradle &安卓工作室的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆