警告:.../Android.mk:链接器标志中存在非系统库

7

在运行$ANDROID_NDK_ROOT/ndk-build时,我收到了这个警告。以下是Android.mk的内容。

$ $ANDROID_NDK_ROOT/ndk-build 

WARNING:/Users/jwalton/Android-CryptoPP/jni/Android.mk:prng:
    non-system libraries in linker flags: -lcryptopp -lstlport_shared    
    This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES    
    or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
    current module
...

然而,当我按照说明从LOCAL_LDLIBS中删除-lcryptopp -lstlport_shared时,我会得到与libstlport_shared.so相关的符号链接错误。以下是Android.mk文件后显示的错误示例。
那么,ndk-build对Android.mk有什么具体要求呢?
为什么我必须将$(STLPORT_INCL)添加到LOCAL_C_INCLUDES,并将$(STLPORT_LIB)添加到LOCAL_LDFLAGS呢?为什么APP_STL := stlport_shared不能立即正确设置STL?
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

TARGET_ARCH_ABI := armeabi
TARGET_ABI      := android-9-armeabi

CRYPTOPP_INCL   := /usr/local/cryptopp-android-9/include
CRYPTOPP_LIB    := /usr/local/cryptopp-android-9/lib

STLPORT_INCL    := /opt/android-ndk-r9/sources/cxx-stl/stlport/stlport
STLPORT_LIB     := /opt/android-ndk-r9/sources/cxx-stl/stlport/libs/armeabi

APP_STL         := stlport_shared
APP_MODULES     := stlport_shared cryptopp

LOCAL_CPP_FEATURES := rtti exceptions

LOCAL_C_INCLUDES := $(CRYPTOPP_INCL) $(CRYPTOPP_INCL)/cryptopp $(STLPORT_INCL)

LOCAL_LDFLAGS  := -L $(CRYPTOPP_LIB) -L $(STLPORT_LIB)
LOCAL_LDLIBS   := -lcryptopp -lstlport_shared -llog -landroid
# LOCAL_LDLIBS   := -llog -landroid
# LOCAL_SHARED_LIBRARIES := -lcryptopp -lstlport_shared

LOCAL_MODULE    := prng
LOCAL_SRC_FILES := libprng.cpp

include $(BUILD_SHARED_LIBRARY)

当尝试按照建议从LOCAL_LDLIBS中删除本地库时,以下是错误示例:

$ $ANDROID_NDK_ROOT/ndk-build 
Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 9 in /Users/jwalton/Android-CryptoPP/AndroidManifest.xml    
Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup       : libs/armeabi/gdb.setup
Compile++ thumb  : prng <= libprng.cpp
SharedLibrary  : libprng.so
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::__node_alloc::allocate(unsigned int&):/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_alloc.h:158: error: undefined reference to 'std::__node_alloc::_M_allocate(unsigned int&)'
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::__node_alloc::deallocate(void*, unsigned int):/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_alloc.h:161: error: undefined reference to 'std::__node_alloc::_M_deallocate(void*, unsigned int)'
/opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/jwalton/Android-CryptoPP/obj/local/armeabi/objs-debug/prng/libprng.o: in function std::ios_base::_M_check_exception_mask():/opt/android-ndk-r9/sources/cxx-stl/stlport/stlport/stl/_ios_base.h:193: error: undefined reference to 'std::ios_base::_M_throw_failure()'

...

1个回答

11

我将“链接器标志中的非系统库”消息解释为警告,提示您未使用默认的系统库(位于usr/lib),这可能完全没有问题,但这也可能导致错误(不同库版本之间的不兼容性)。这个警告是否会让您困扰完全取决于您自己。

然后,关于您尝试解决它的方式,我认为您错误地使用了NDK的LOCAL_SHARED_LIBRARIES变量。

我在此贴出一个使用Assimp的Android.mk文件示例:

#------------------------------------------------------------------ Assimp
include $(CLEAR_VARS)

LOCAL_MODULE := Assimp
LOCAL_EXPORT_C_INCLUDES := $(GENERATED_INCLUDE_PATH)/assimp/include
LOCAL_SRC_FILES := $(GENERATED_PATH)/assimp/lib/libassimp.a

include $(PREBUILT_STATIC_LIBRARY)

...

LOCAL_STATIC_LIBRARIES := \
Assimp \
<Your other libs here>

如您所见,我声明了一个自定义名称的 LOCAL_MODULE,设置了一些变量,然后包含 PREBUILT_STATIC_LIBRARY 脚本,告诉 NDK 使用此库。

然后在 LOCAL_STATIC_LIBRARIES 中,我列出了我使用的库及其模块名称,而不是像您在这里所做的链接器标志。

在您的情况下,例如对于 stl,我认为您应该执行以下操作:

include $(CLEAR_VARS)

LOCAL_MODULE := STLPortShared
LOCAL_EXPORT_C_INCLUDES := <path to stlport includes>
LOCAL_SRC_FILES := <path to stlport library>

include $(PREBUILT_SHARED_LIBRARY)

...
#Notice the name, identical to the one specified for LOCAL_MODULE
LOCAL_SHARED_LIBRARIES = STLPortShared 

我认为这应该可以解决问题。当然,对于每个引起问题的库,都要重复此过程,并在每个库规范之间不要忘记include(CLEAR_VARS)


1
这是我不明白的地方:LOCAL_EXPORT_C_INCLUDES := <path to stlport includes>。Android提供了该库。他们提供了一个糟糕的构建系统。应该像--sysroot一样包含这个东西。相反,他们让开发者受尽折磨。而且他们隐藏了输出,所以你甚至看不到实验结果,试图让这个东西工作起来。 - jww
但是对于标准库,我不必像这样(我同意你的看法)经历相当可怕的混乱,只需要在我的Application.mk中添加一个APP_STL=gnustl_shared... - JBL
是的,情况变得更糟了。该死的构建系统拒绝将依赖库(STLport和Crypto++)复制到“../libs/armeabi”文件夹中。 - jww
1
@jww 不要低估 ndk-build 中的 V=1 参数。 - Alex Cohn
2
ndk-build -n 也可以用来查看 make 将执行的所有命令列表(而不实际执行它们)。 - Colin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接