ANDROID:如何在创建具有静态库依赖项的共享库时正确链接静态库

时间:2015-02-14 18:29:02

标签: android c++ android-ndk shared-libraries protocol-buffers

我必须在我的Android应用程序中使用一些c ++代码。此代码已在iOS项目中成功使用。 代码依赖于2个外部库:零mq和协议缓冲区。

我将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项目(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中。

现在对象的链接仍然不起作用。执行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并使用我在互联网上找到的不同选项不止一次地重新创建了库。 我还查看了stackoverflow上的几十个线程,这些线程对我没有帮助。(由于信誉低,我不允许链接它们) 另外,我从ndk读取大多数doc文件,例如PREBUILTS。 我在JNI目录中添加了一些其他目录,例如包含原始文件和目录的目录(编译器,io,存根...)。我认为如果prebuild库成功链接到我的共享库,这个目录应该提供必要方法的导出 - 事实并非如此。 我尝试的远远超过了我能在几分钟内解释的内容,如果我添加了所有我尝试过的东西,我认为这样做会有点过头了。

因为这是我的第一个问题,所以我不具备包含2个以上链接的声誉。对不起。

1 个答案:

答案 0 :(得分:0)

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