我在Android studio(3)中使用Gradle 3.0.1尝试编译FFMPEG,而armeabi-v7a有两个共享库,一个是霓虹灯,另一个没有。通常在gradle之前的旧时代,ndkbuild会编译我的项目而没有任何问题,现在使用gradle和new ndkbuild,出现了一堆问题。以下内容并不完全是我的代码,但您可以在https://github.com/matthewn4444/VPlayer_lib中查看我的代码。我有3个关于用ndk建立gradle的问题。
我预先构建了两个版本的libffmpeg.so,一个用于霓虹灯中的armeabi-v7a,另一个没有。我在Android.mk文件中有一个应用程序氖和应用程序模块。我不确定是否有办法只有1个.so文件,但由于FFMPEG很复杂,我不想只是为了创建一个共享库来包装霓虹灯调用。
我的第一个问题是,是否有可能在ndk中只有一个共享库导入到java中,霓虹灯和非霓虹灯支持链接到更大的第三方库或者更容易拥有2个独立的库?
如果我尝试编译arm64-v8a等其他架构,我会收到错误:
* What went wrong:
Execution failed for task ':VPlayer_library:externalNativeBuildDebug'.
> Unexpected native build target application-neon. Valid values are: <projects>
这是因为在我的Android.mk文件中,我有一个非霓虹灯模块和一个主要用于armeabi-v7a的霓虹灯模块。我得到上面的错误,因为霓虹灯模块仅适用于armeabi-v7a,arm 64将没有,因此编译时弹出错误。如果我创建一个虚拟的霓虹灯构建,它将允许项目编译,但然后它将假的霓虹灯共享库捆绑到apk中。我正在考虑像这样构建它,然后在将共享库合并到apk之前从构建部分中删除arm64,x86等所有虚拟共享库。
我的第二个问题是,有没有办法绕过这个错误或者在构建(abiFilters)时没有所有这些黑客的特定架构的特殊目标?代码如下。
Android.mk
... <the module for normal application project>
ifdef FEATURE_NEON
include $(CLEAR_VARS)
LOCAL_ALLOW_UNDEFINED_SYMBOLS=false
LOCAL_MODULE := application-neon
LOCAL_SRC_FILES := application.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include \
$(LOCAL_PATH)/application
LOCAL_SHARED_LIBRARY := application-neon
LOCAL_LDLIBS += -landroid
LOCAL_LDLIBS += -llog -ljnigraphics -lz -lm -g $(LOCAL_PATH)/ffmpeg-build/$(TARGET_ARCH_ABI)/libffmpeg-neon.so
include $(BUILD_SHARED_LIBRARY)
else
# This is the dummy app to get the project to compile.
include $(CLEAR_VARS)
LOCAL_MODULE := application-neon
LOCAL_ALLOW_UNDEFINED_SYMBOLS=false
include $(BUILD_SHARED_LIBRARY)
endif
-------------------------------------------------------
build.gradle
externalNativeBuild {
ndkBuild {
targets "application", "cpufeatures", "application-neon" // fails for 'arm64-v8a' without that dummy module
}
}
接下来,当我更改abiFilters时,它将包括我之前构建的所有架构,除了我选择的架构。例如,如果我建立了
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
then....
ndk {
abiFilters 'arm64-v8a'
}
并制作了一个apk然后决定只构建arm64-v8a并构建了一个apk,所有armeabi-v7a共享库也都在apk中。 Android studio不会从构建文件夹中删除其他体系结构编译数据,但也会将它们捆绑到apk中。所以现在我有一个gradle任务从构建文件夹中删除它们(代码在最后)。
我的第三个问题是,如果我做错了什么或者我能做些什么更容易,不需要下面的gradle代码?
def deleteOtherArchFromFolder(config, path) {
new File(path).listFiles().each { folder ->
if (!config.ndk.abiFilters.contains(folder.name)) {
delete {
delete folder
}
}
}
}
task prebuildTask() {
doLast {
def config = android.defaultConfig
// delete the obj files in build directory
deleteOtherArchFromFolder(config, project.buildDir.absolutePath + '/intermediates/ndkBuild/debug/obj/local')
}
}
preBuild.dependsOn(prebuildTask)
提前致谢!