我有一个使用Android NDK编写的android项目。在项目中,我使用两个预建的共享库(GpkgSDK和spatialite)并构建另外两个共享库(WFSHelpers和com_example_gpkgviewer_jni_WKTConverter)。与应用程序的Java级别交互的唯一库是com_example_gpkgviewer_jni_WKTConverter库。
库之间的依赖关系如下所示:
我遇到的问题是,当我尝试运行ndk-build时,在尝试构建com_example_gpkgviewer_jni_WKTConverter库时,我收到了大量未定义的引用。其他库已成功构建。我通常解决这些未定义引用的方法是在com_example_gpkgviewer_jni_WKTConverter模块定义中包含以下内容:
LOCAL_SHARED_LIBRARY := WFSHelpers
我不确定是否还需要包含WFSHelpers所依赖的库,如下所示:
LOCAL_SHARED_LIBRARY := WFSHelpers GpkgSDK spatialite
我也尝试过不同的顺序,但它似乎无法解决我的问题:
我的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);
有关如何解决依赖关系的任何建议。
答案 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之间的区别是什么。如果有人可以向我提供解释,请做。如果没有,我会在给出一些时间之后将此答案标记为已接受。谢谢!