Android NDK模块依赖于另一个模块

时间:2014-03-19 10:45:02

标签: android android-ndk java-native-interface dependencies android.mk

我有一个使用Android NDK编写的android项目。在项目中,我使用两个预建的共享库(GpkgSDK和spatialite)并构建另外两个共享库(WFSHelpers和com_example_gpkgviewer_jni_WKTConverter)。与应用程序的Java级别交互的唯一库是com_example_gpkgviewer_jni_WKTConverter库。

库之间的依赖关系如下所示:

  • WFSHelpers依赖于GpkgSDK和spatialite
  • com_example_gpkgviewer_jni_WKTConverter依赖于WFSHelpers

我遇到的问题是,当我尝试运行ndk-build时,在尝试构建com_example_gpkgviewer_jni_WKTConverter库时,我收到了大量未定义的引用。其他库已成功构建。我通常解决这些未定义引用的方法是在com_example_gpkgviewer_jni_WKTConverter模块定义中包含以下内容:

LOCAL_SHARED_LIBRARY := WFSHelpers

我不确定是否还需要包含WFSHelpers所依赖的库,如下所示:

LOCAL_SHARED_LIBRARY := WFSHelpers GpkgSDK spatialite

我也尝试过不同的顺序,但它似乎无法解决我的问题:

  • LOCAL_SHARED_LIBRARY:= GpkgSDK spatialite WFSHelpers

我的Application.mk包含在下面:

NDK_TOOLCHAIN_VERSION := 4.8
# APP_STL := stlport_shared  --> does not seem to contain C++11 features
APP_STL := gnustl_shared

# Enable c++11 extentions in source code
APP_CPPFLAGS += -std=c++11
APP_CPPFLAGS += -frtti 
APP_CPPFLAGS += -fexceptions

APP_MODULES := GpkgSDK spatialite WFSHelpers com_example_gpkgviewer_jni_WKTConverter

APP_ABI := armeabi armeabi-v7a

我的Android.mk如下所示:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := GpkgSDK
LOCAL_SRC_FILES := libMP.so
LOCAL_EXPORT_C_INCLUDES := \
$(LOCAL_PATH)/include \
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := spatialite
LOCAL_SRC_FILES := spatialamal/prebuilt/$(TARGET_ARCH_ABI)/libspatialite.so
LOCAL_EXPORT_C_INCLUDES :=     spatialamal/headers/spatialite \
                            spatialamal/headers
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := WFSHelpers
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
LOCAL_SRC_FILES := \
GPKGReader/Debug.h \
GPKGReader/DLLExport.h \
GPKGReader/DBQueryResult.cpp \
GPKGReader/GeoPackageDB.cpp \
GPKGReader/GPKGReader.cpp \
GPKGReader/order32.h \
GPKGReader/SpecDefinitions.h \
GPKGReader/WKBGenericGeometry.cpp \
GPKGReader/WKBLineString.cpp \
GPKGReader/WKBMultiLineString.cpp \
GPKGReader/WKBMultiPolygon.cpp \
GPKGReader/WKBPoint.cpp \
GPKGReader/WKBPolygon.cpp \
GPKGDataLayer/GPKGDataLayer.cpp
LOCAL_SHARED_LIBRARIES := GpkgSDK spatialite
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
LOCAL_MODULE    := com_example_gpkgviewer_jni_WKTConverter
LOCAL_SRC_FILES := com_example_gpkgviewer_jni_WKTConverter.cpp
LOCAL_SHARED_LIBRARY := WFSHelpers GpkgSDK spatialite
include $(BUILD_SHARED_LIBRARY)

我得到的未定义参考错误的示例如下所示:

[armeabi] SharedLibrary  : libcom_example_gpkgviewer_jni_WKTConverter.so
jni/com_example_gpkgviewer_jni_WKTConverter.cpp:59: error: undefined reference
o 'WKBGenericGeometry::readInt32(unsigned char, unsigned char*, unsigned int)'
collect2.exe: error: ld returned 1 exit status
make.exe: *** [obj/local/armeabi/libcom_example_gpkgviewer_jni_WKTConverter.so]
Error 1

导致此错误的com_example_gpkgviewer_jni_WKTConverter.cpp中的代码行如下所示:

*id_arg = WKBGenericGeometry::readInt32(byte_order, &(bytes[4]), length - 4);

有关如何解决依赖关系的任何建议。

1 个答案:

答案 0 :(得分:4)

在尝试建立多年后,我终于能够让它发挥作用了。虽然,我不太清楚差异是什么,所以任何能够阐明这一点的人都欢迎这样做。我的问题是我依赖其他库。文档说明如下:

  

LOCAL_SHARED_LIBRARIES
  共享库模块列表   模块依赖于运行时。这在链接时是必要的   在生成的文件中嵌入相应的信息。

     

LOCAL_LDLIBS
  构建共享库或可执行文件时要使用的其他链接器标志的列表。通过这个有用   具有' -l'的特定系统库的名称字首。例如,   以下内容将告诉链接器生成一个链接到的模块   /system/lib/libz.so在加载时:

LOCAL_LDLIBS := -lz
     

有关可与此NDK版本链接的公开系统库列表,请参阅STABLE-APIS   注意:对于静态库,这将被忽略,如果是,ndk-build将打印警告   你在这样一个模块中定义它。

因此,在我的Android.mk文件中,我不得不使用LOCAL_LDLIBS而不是LOCAL_SHARED_LIBRARIES来指示依赖项。

我的新Android.mk如下所示:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := GpkgSDK
LOCAL_SRC_FILES := libMP.so
LOCAL_EXPORT_C_INCLUDES := \
$(LOCAL_PATH)/include \
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := spatialite
LOCAL_SRC_FILES := spatialamal/prebuilt/$(TARGET_ARCH_ABI)/libspatialite.so
LOCAL_EXPORT_C_INCLUDES :=     spatialamal/headers/spatialite \
                            spatialamal/headers
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := WFSHelpers
LOCAL_SRC_FILES := \
GPKGReader/Debug.h \
GPKGReader/DLLExport.h \
GPKGReader/DBQueryResult.cpp \
GPKGReader/GeoPackageDB.cpp \
GPKGReader/GPKGReader.cpp \
GPKGReader/order32.h \
GPKGReader/SpecDefinitions.h \
GPKGReader/WKBGenericGeometry.cpp \
GPKGReader/WKBLineString.cpp \
GPKGReader/WKBMultiLineString.cpp \
GPKGReader/WKBMultiPolygon.cpp \
GPKGReader/WKBPoint.cpp \
GPKGReader/WKBPolygon.cpp \
GPKGDataLayer/GPKGDataLayer.cpp
LOCAL_LDLIBS := libs/$(TARGET_ARCH_ABI)/libGpkgSDK.so
LOCAL_LDLIBS += libs/$(TARGET_ARCH_ABI)/libspatialite.so
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := com_example_gpkgviewer_jni_WKTConverter
LOCAL_SRC_FILES := com_example_gpkgviewer_jni_WKTConverter.cpp
LOCAL_LDLIBS := libs/$(TARGET_ARCH_ABI)/libWFSHelpers.so
LOCAL_LDLIBS += libs/$(TARGET_ARCH_ABI)/libGpkgSDK.so
include $(BUILD_SHARED_LIBRARY)

我会暂时搁置这个答案,因为我不完全确定LOCAL_LDLIBS和LOCAL_SHARED_LIBRARIES之间的区别是什么。如果有人可以向我提供解释,请做。如果没有,我会在给出一些时间之后将此答案标记为已接受。谢谢!