【问题标题】:How can I merge two Android.mk files when adding a library?添加库时如何合并两个 Android.mk 文件?
【发布时间】:2017-05-29 07:49:09
【问题描述】:

我是 Android 新手,所以我不完全了解如何制作 Android.mk 文件。 我的项目运行良好,遵循提供 Android.mk 的在线教程。但后来我需要添加一个缺少的库,并且该教程有另一个 Android.mk,现在我正在尝试将两者合并在一起。

这是我的 Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#opencv
OPENCVROOT:= C:\OpenCV-2.4.10-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES := com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp


LOCAL_LDLIBS += -llog

LOCAL_MODULE := MyOpencvLibs


include $(BUILD_SHARED_LIBRARY)

这是我需要添加的 Android.mk:

LOCAL_PATH  := $(call my-dir)
OPENCV_PATH := D:/CODE/OpenCV-2.4.10-android-sdk/sdk/native/jni

include $(CLEAR_VARS)
LOCAL_MODULE    := nonfree
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES := on
OPENCV_CAMERA_MODULES  := off
include $(OPENCV_PATH)/OpenCV.mk

LOCAL_C_INCLUDES :=             \
    $(LOCAL_PATH)               \
    $(OPENCV_PATH)/include

LOCAL_SRC_FILES :=              \
    nonfree_jni.cpp

LOCAL_MODULE := nonfree_demo
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS := -llog -ldl
LOCAL_SHARED_LIBRARIES += nonfree

include $(BUILD_SHARED_LIBRARY)

我对最后一个Android.mk感兴趣的是libnonfree.so而已,我不需要cpp文件。

这是我的项目结构:

编辑:

感谢您的回答。我已经按照建议做了,我的 Android.mk 现在看起来像这样:

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

#opencv
OPENCVROOT:= C:\OpenCV-2.4.10-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES := com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp
LOCAL_LDLIBS += -llog
LOCAL_SHARED_LIBRARIES += nonfree
LOCAL_MODULE := MyOpencvLibs
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := nonfree
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)

但问题仍然存在。我对 libnonfree.so 应该添加的方法有“未定义的引用”。我认为问题出在 Android.mk 上,但可能出在其他地方。

我已将System.loadLibrary("nonfree"); 添加到我的MainACtivity

#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/nonfree/features2d.hpp"

我不知道我做错了什么。

编辑 2:

这是错误:

Application.mk:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16

我不知道在我的 build.gradle 中在哪里设置 arguments="V=1"

我的 build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.adrien.ndkopencvtest4"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    sourceSets.main {
        //jniLibs.srcDirs = ['src/main/jniLibs']
        jni.srcDirs = [] //disable automatic ndk-build call
    }
    task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
        commandLine "C:/Users/Adrien/AppData/Local/Android/sdk/ndk-bundle/ndk-build.cmd",
                'NDK_PROJECT_PATH=build/intermediates/ndk',
                'NDK_LIBS_OUT=src/main/jniLibs',
                'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
                'NDK_APPLICATION_MK=src/main/jni/Application.mk'
    }
    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.github.wseemann:FFmpegMediaMetadataRetriever-armeabi-v7a:1.0.14'
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile project(':openCVLibrary2410')

}

编辑 3:

“ndk-build V=1”的结果:

C:\Users\Adrien\AndroidStudioProjects\NDKOpencvTest4\app\src\main\jni>ndk-build V=1

[armeabi-v7a] SharedLibrary  : libMyOpencvLibs.so
C:/Users/Adrien/AppData/Local/Android/sdk/ndk-bundle/build//../toolchains/llvm/preb
uilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libMyOpencvLibs.so -shared --sysroo
t=C:/Users/Adrien/AppData/Local/Android/sdk/ndk-bundle/build//../platforms/android-
16/arch-arm C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/obj/l
ocal/armeabi-v7a/objs/MyOpencvLibs/com_example_adrien_ndkopencvtest4_OpencvNativeCl
ass.o C:/Users/Adrien/AppData/Local/Android/sdk/ndk-bundle/build//../sources/cxx-st
l/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a -lgcc C:/Users/Adrien/Andro
idStudioProjects/NDKOpencvTest4/app/src/main/obj/local/armeabi-v7a/libopencv_java.s
o C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/obj/local/armea
bi-v7a/libnonfree.so  -gcc-toolchain C:/Users/Adrien/AppData/Local/Android/sdk/ndk-
bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -no-c
anonical-prefixes -target armv7-none-linux-androideabi -Wl,--fix-cortex-a8  -Wl,--b
uild-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-sh
ared-textrel -Wl,--fatal-warnings   -LC:/Users/Adrien/AppData/Local/Android/sdk/ndk
-bundle/build//../platforms/android-16/arch-arm/usr/lib -llog -lc -lm -o C:/Users/A
drien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/obj/local/armeabi-v7a/libMy
OpencvLibs.so
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_a
drien_ndkopencvtest4_OpencvNativeClass.cpp:214: error: undefined reference to 'cv::
SURF::SURF(double, int, int, bool, bool)'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_a
drien_ndkopencvtest4_OpencvNativeClass.cpp:222: error: undefined reference to 'cv::
SURF::SURF()'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_a
drien_ndkopencvtest4_OpencvNativeClass.cpp:204: error: undefined reference to 'VTT
for cv::SURF'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_a
drien_ndkopencvtest4_OpencvNativeClass.cpp:204: error: undefined reference to 'VTT
for cv::SURF'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_a
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp:204: error: undefined
reference to 'VTT for cv::SURF'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp:449: error: undefined
reference to 'cv::SURF::SURF(double, int, int, bool, bool)'
C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/jni/com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp:457: error: undefined
reference to 'cv::SURF::SURF()'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/obj/local/armeabi-v7a/libMyOpencvLibs.so] Error 1

解决方案:

我的 libnonfree.so 文件不正确,我下载了另一个。我还将我的Application.mk 文件更改为:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16

【问题讨论】:

  • 请显示您看到的错误。要了解您的 Android.mk 是如何解释的,请从命令行运行 ndk-build V=1(或者您可以在 build.gradle 文件中设置 arguments="V=1")。请注意,您也应该非常小心 Application.mk 文件的内容。并确保您的 APK 仅构建 armeabi-v7a,因为您没有用于其他 ABI 的 libnonfree.so
  • 我已经编辑了我的答案,感谢您的宝贵时间。
  • 你有这个commandLine 字符串。添加'V=1' 作为其参数之一。
  • Android Studio v. 2.3 已在 android gradle 插件中集成了 externalNativeBuild,因此您不需要自定义 gradle 任务的技巧。参见例如这个build.gradle.
  • 酷。 C:/Users/Adrien/AndroidStudioProjects/NDKOpencvTest4/app/src/main/obj/local/armeabi-v7a/libnonfree.so 文件真的存在吗?

标签: android android-ndk


【解决方案1】:

如果您想在项目中添加预构建的共享库,则不需要单独的 Android.mk

让我们来看看你的剧本,

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#opencv
OPENCVROOT:= C:\OpenCV-2.4.10-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES := com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp


LOCAL_LDLIBS += -llog

LOCAL_MODULE := MyOpencvLibs


include $(BUILD_SHARED_LIBRARY)

只需在底部添加您需要的额外模块:

include $(CLEAR_VARS)
LOCAL_MODULE    := nonfree
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)

现在C:\Users\Adrien\AndroidStudioProjects\NDKOpencvTest4\app\src\main\jni\libnonfree.so 文件将被打包到您的 APK 中。

如果您需要此库来链接您的 libMyOpencvLibs.so(这意味着,如果您在 com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp 中的代码使用从 libnonfree.so 导出的一些函数,你也应该在你的模块中引用它:

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

#opencv
OPENCVROOT:= C:\OpenCV-2.4.10-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES := com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp
LOCAL_LDLIBS += -llog
LOCAL_SHARED_LIBRARIES += nonfree
LOCAL_MODULE := MyOpencvLibs
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := nonfree
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)

【讨论】:

    【解决方案2】:

    修改你的 android.mk 为:

    LOCAL_PATH  := $(call my-dir)
    OPENCV_PATH := D:/CODE/OpenCV-2.4.10-android-sdk/sdk/native/jni
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := nonfree
    LOCAL_SRC_FILES := libnonfree.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    
    #opencv
    OPENCVROOT:= C:\OpenCV-2.4.10-android-sdk
    OPENCV_CAMERA_MODULES:=on
    OPENCV_INSTALL_MODULES:=on
    OPENCV_LIB_TYPE:=SHARED
    include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk
    
    LOCAL_SRC_FILES := com_example_adrien_ndkopencvtest4_OpencvNativeClass.cpp
    
    LOCAL_SHARED_LIBRARIES += nonfree
    
    LOCAL_LDLIBS += -llog
    
    LOCAL_MODULE := MyOpencvLibs
    
    include $(BUILD_SHARED_LIBRARY)
    

    这里的预编译库,即 libnonfree.so 在 android.mk 中声明,稍后通过

    引用它
    LOCAL_SHARED_LIBRARIES += nonfree
    

    现在要使用它,您需要在您的 MainActivity 中加载最新构建的库,即

    System.loadLibrary("MyOpencvLibs");
    

    就是这样,现在您已经将两个 android.mk 文件合并到一个名为:MyOpencvLibs 的新模块中

    为了更好地理解你可以阅读我的博客:https://androidtutsweb.wordpress.com/2017/04/04/android-mk-for-ndk-build-using-pre-build-libraries/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多