ВНИМАНИЕ: /Android.mk: флаги несистемных библиотек в компоновщике

Я получаю это предупреждение при запуске $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
...

Однако, когда я следую инструкциям и удаляю -lcryptopp -lstlport_shared из LOCAL_LDLIBS, я получаю ошибки ссылок, связанные с символами из 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()'

...


person jww    schedule 04.09.2014    source источник


Ответы (1)


Я интерпретирую сообщение «несистемные библиотеки в флагах компоновщика» как предупреждение о том, что вы не используете системные библиотеки по умолчанию (в usr/lib), что может быть совершенно нормально, но также может привести к ошибкам (несовместимость между версиями разных библиотек) . Будет ли вас беспокоить это предупреждение, полностью зависит от вас.

Затем, о том, как вы пытались решить эту проблему, я думаю, вы неправильно используете переменную LOCAL_SHARED_LIBRARIES NDK.

Я вставляю сюда образец из одного из моих Android.mk файлов, в котором используется Assimp.

#------------------------------------------------------------------ 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) между спецификациями каждой библиотеки.

person JBL    schedule 04.09.2014
comment
Вот чего я не понимаю: LOCAL_EXPORT_C_INCLUDES := <path to stlport includes>. Android поставляет чертову библиотеку. Они предоставляют долбаную систему сборки. st должен быть включен как --sysroot. Вместо этого они мучают этим разработчиков. И они скрывают вывод, так что вы даже не можете увидеть результаты экспериментов, пытаясь заставить это дерьмо работать. - person jww; 04.09.2014
comment
Но для стандартной библиотеки мне не нужно проходить через этот (я согласен с вами в этом) довольно ужасный беспорядок, и у меня есть только APP_STL=gnustl_shared в моем Application.mk... - person JBL; 04.09.2014
comment
Да, становится еще лучше. Чертова система сборки отказывается копировать зависимые библиотеки (STLport и Crypto++) в папку ../libs/armeabi. - person jww; 04.09.2014
comment
@jww не недооценивайте параметр V=1 до ndk-build - person Alex Cohn; 05.09.2014
comment
ndk-build -n также работает, чтобы увидеть список всех команд, которые make будет выполнять (без их выполнения) - person Colin; 11.11.2014