ANDROID:如何在创建依赖于静态库的共享库时正确地 link 对抗静态库

ANDROID: How to properly link against static libraries while creating shared libraries with dependencies on the static ones

我必须在我的 android 应用程序中使用一些 C++ 代码。此代码已在 iOS 项目中成功使用。 该代码依赖于 2 个外部库:zero-mq 和 protocol buffers。

我将 zmq 库编译为静态库,如解释的那样 here。我将静态 (.a) 库和 .jar 添加到我的项目中。

我使用以下配置创建了 protobuf 库:

./configure --host=arm-eabi --with-sysroot=x/android-ndk-r10d/platforms/android-21/arch-arm CC="x/android-ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot x/android-ndk-r10d/platforms/android-21/arch-arm" --enable-cross-compile --with-protoc=protoc LIBS=-lc
make

我将真实目录更改为 x 以缩短它们。

在我的 Android Project(IDE: Android Studio) 中,我准备了所有必要的东西。我创建了一个 JNI 文件夹并停用了 makefile 的自动创建。

Application.mk:

APP_MODULE := proxy
APP_STL := gnustl_shared
APP_CPPFLAGS := -frtti -fexceptions --std=c++11
APP_ABI := armeabi-v7a             ##all later
NDK_TOOLCHAIN_VERSION := 4.9

Android.mk:

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

LOCAL_MODULE := zmq_static
LOCAL_SRC_FILES := zmq/libzmq.a
include $(PREBUILD_STATIC_LIBRARY)

LOCAL_MODULE := protobuf_static1
LOCAL_SRC_FILES := protobuf/libprotobuf.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)

LOCAL_MODULE := protobuf_static2
LOCAL_SRC_FILES := protobuf/libprotobuf-lite.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)

LOCAL_MODULE := protobuf_static3
LOCAL_SRC_FILES := protobuf/libprotoc.a
LOCAL_EXPORT_C_INCLUDES := google/protobuf protobuf/
include $(PREBUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := proxy
LOCAL_CFLAGS := -I/include -pthread -lpthread -D__GXX_EXPERIMENTAL_CXX0X__ -        frtti
LOCAL_CPPFLAGS := -I/include -pthread -lpthread -D__GXX_EXPERIMENTAL_CXX0X__ -frtti
LOCAL_CPP_FEATURES += exceptions
LOCAL_LDLIBS := -llog

LOCAL_SRC_FILES := \
usersession.cpp\



## LOCAL_ALLOW_UNDEFINED_SYMBOLS := true    will compile the code but   shutdown on runtime

LOCAL_C_INCLUDES +=     C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\main\jni
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\arm\jni
LOCAL_C_INCLUDES += C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\debug\jni
LOCAL_C_INCLUDES +=  C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\armDebug\jni
LOCAL_C_INCLUDES += \zmq
LOCAL_C_INCLUDES += \protobuf

LOCAL_STATIC_LIBRARIES := zmq_static protobuf_static1 protobuf_static2 protobuf_static3
LOCAL_WHOLE_STATIC_LIBRARIES := zmq_static protobuf_static1 protobuf_static2 protobuf_static3

include $(BUILD_SHARED_LIBRARY)

zmq库在zmq子目录下,protobuf库在protobuf子目录下

现在对象的 linking 仍然不起作用。执行 ndk-build 时的错误输出:

C:\Users\M\Dropbox\Workspace\ndk_swig_test\app\src\main\jni>ndk-build
[armeabi-v7a] SharedLibrary  : libproxy.so
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu-   libstdc++/4.9/include/ext/new_allocator.h:127: error: undefined reference to    'ControlledInstance::ControlledInstan  (std::shared_ptr<protogen::Application>, std:
:shared_ptr<protogen::Role>, std::shared_ptr<protogen::User>)'
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu-   libstdc++/4.9/include/bits/shared_ptr_base.h:511: error: undefined reference to   'protogen::User::User()'
C:/Users/M/Documents/ndk/sources/cxx-stl/gnu-  libstdc++/4.9/include/bits/shared_ptr_base.h:914: error: undefined reference to    'google::protobuf::internal::empty  tring_'
   C:/Users/M/Dropbox/Workspace/ndk_swig_test/app/src/main//jni/controlledinstance.h    :23: error: undefined reference to 'protogen::MetaGraph::~MetaGraph()'
collect2.exe: error: ld returned 1 exit status
make.exe: ***    [C:/Users/M/Dropbox/Workspace/ndk_swig_test/app/src/main//obj/local/armeabi-  v7a/libproxy.so] Error 1

我尝试了 Android.mk 的许多版本,并多次使用我在 Internet 上找到的不同选项重新创建了库。 我还查看了 Whosebug 上的许多线程,它们对我没有帮助。(由于声誉低下,我不允许 link 它们) 此外,我从 ndk 中阅读了大部分文档文件,例如PREBUILTS。 我在我的 JNI 目录中添加了一些其他目录,例如包含原始文件和目录(编译器、io、存根...)的目录。如果预构建库成功 linked 到我的共享库,我认为这个目录应该提供必要方法的导出——但事实并非如此。 我尝试的远远超过我在几分钟内所能解释的,我认为如果我添加我尝试过的所有东西就太过分了,因为没有任何帮助。

因为这是我的第一个问题,所以我没有包含超过 2 个 link 的声誉。对不起。

可能还有其他问题,但您至少有一个错字 - 它应该是 include $(PREBUILT_STATIC_LIBRARY),如 BUILT,而不是 BUILD