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
。
我必须在我的 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
。