Android NDK - как статически связать библиотеку C ++ с другой библиотекой C ++ - PullRequest
2 голосов
/ 10 сентября 2011

У меня есть библиотека C ++ с именем mylib , скомпилированная с помощью ndk-сборки Android NDK r6b под CYGWIN.Полученный файл библиотеки называется libmylib.so .

У меня есть простое приложение под названием helloworld , которое включает в себя файлы .hpp mylib и должно быть связано с libmylib.so.

Я могу скомпилировать helloworld, сказав компоновщику искать libmylib.so.«Странные» факты:

  1. libmylib.so не объединен с libhelloworld.so, поэтому мне нужно скопировать libmylib.so в каталог helloworld / libs / armeabi вручную
  2. в коде Java, я должен явно загрузить mylib с System.loadLibrary, и я должен загрузить mylib ДО ТОГО, как я загружу библиотеку helloworld (то есть: System.loadLibrary("mylib"); System.loadLibrary("ndkfoo");), в противном случае приложение вылетает.

Еслия делаю 1 и 2, приложение работает отлично (проверено как на эмуляторе, так и на реальном устройстве).Я хотел бы знать, как можно заставить компоновщик создать libhelloworld.so, слитый с libmylib.so, чтобы избежать 1,2 и 3, как упомянуто выше.

Спасибо.

Ps.

Android.mk mylib:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS)
LOCAL_MODULE    := mylib
LOCAL_SRC_FILES := mylib.cpp 
include $(BUILD_SHARED_LIBRARY)
#include $(BUILD_STATIC_LIBRARY)

Если я использую BUILD_SHARED_LIBRARY, я получаю libmylib.so как обычно.Если я использую вместо этого BUILD_STATIC_LIBRARY, то ndk-build не генерирует .so или .a.Я действительно хотел бы увидеть простое руководство, которое объясняет, как создать приложение JNI (с кодом JAVA + c ++), которое использует внешнюю библиотеку, написанную на C ++ и помещенную в другой каталог (не в каталог jni приложения).

ПСС.Когда я компилирую с помощью BUILD_STATIC_LIBRARY mylib, я получаю следующее (в основном, единственный созданный файл находится в каталоге dir / mylib / libs / armeabi / и называется gdb.setup и gdbserver):

$ /cygdrive/d/android/android-ndk-r6b/ndk-build NDK_LOG=1 V=1 -B
Android NDK: NDK installation path auto-detected: '/cygdrive/d/android/android-n
dk-r6b'
Android NDK: GNU Make version 3.81 detected
Android NDK: Host OS was auto-detected: windows
Android NDK: Host CPU was auto-detected: x86
Android NDK: HOST_TAG set to windows
Android NDK: Host awk tool was auto-detected: awk
Android NDK: Host awk test returned: Pass
Android NDK:  Probing for 'cygpath' program
Android NDK:  'cygpath' found as: /usr/bin/cygpath
Using cygwin substitution rules:
/cygdrive/d => D:
/cygdrive/c => C:
/cygdrive/D => D:
/cygdrive/C => C:
/usr/lib => C:/cygwin/lib
/usr/bin => C:/cygwin/bin
/ => C:/cygwin
Android NDK:  This NDK supports the following toolchains and target ABIs:
Android NDK:    arm-linux-androideabi-4.4.3:  armeabi armeabi-v7a
Android NDK:    x86-4.4.3:  x86
Android NDK: Found platform root directory: /cygdrive/d/android/android-ndk-r6b/
platforms
Android NDK: Found supported platforms: android-3 android-4 android-5 android-8
android-9
Android NDK: PLATFORM android-3 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-3/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-3/arch-x86
Android NDK: PLATFORM android-4 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-4/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-4/arch-x86
Android NDK: PLATFORM android-5 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-5/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-5/arch-x86
Android NDK: PLATFORM android-8 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-8/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-8/arch-x86
Android NDK: PLATFORM android-9 supports: arm x86
Android NDK:   ABI arm sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-9/arch-arm
Android NDK:   ABI x86 sysroot is: /cygdrive/d/android/android-ndk-r6b/platforms
/android-9/arch-x86
Android NDK: Found stable platform levels: 3 4 5 8 9
Android NDK: Found max platform level: 9
Android NDK: Looking for AndroidManifest.xml in /cygdrive/d/android/workspace/my
lib/jni
Android NDK: Looking for AndroidManifest.xml in /cygdrive/d/android/workspace/my
lib
Android NDK:     Found it !
Android NDK: Found project path: /cygdrive/d/android/workspace/mylib
Android NDK: Parsing /cygdrive/d/android/workspace/mylib/jni/Application.mk
Android NDK:   Found APP_PLATFORM=android-9 in /cygdrive/d/android/workspace/myl
ib/default.properties
Android NDK:   Defaulted to APP_BUILD_SCRIPT=/cygdrive/d/android/workspace/mylib
/jni/Android.mk
Android NDK: Application 'local' *is* debuggable
Android NDK: Selecting debug optimization mode (app is debuggable)
Android NDK: Adding import directory: /cygdrive/d/android/android-ndk-r6b/source
s
Android NDK: Building application 'local' for ABI 'armeabi'
Android NDK: Using target toolchain 'arm-linux-androideabi-4.4.3' for 'armeabi'
ABI
Android NDK: Looking for imported module with tag 'cxx-stl/system'
Android NDK:   Probing /cygdrive/d/android/android-ndk-r6b/sources/cxx-stl/syste
m/Android.mk
Android NDK:     Found in /cygdrive/d/android/android-ndk-r6b/sources/cxx-stl/sy
stem
Android NDK: Module 'mylib' has C++ sources
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/lib*.so /cygdrive/d/andro
id/workspace/mylib/libs/armeabi-v7a/lib*.so /cygdrive/d/android/workspace/mylib/
libs/x86/lib*.so
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/gdbserver /cygdrive/d/and
roid/workspace/mylib/libs/armeabi-v7a/gdbserver /cygdrive/d/android/workspace/my
lib/libs/x86/gdbserver
rm -f /cygdrive/d/android/workspace/mylib/libs/armeabi/gdb.setup /cygdrive/d/and
roid/workspace/mylib/libs/armeabi-v7a/gdb.setup /cygdrive/d/android/workspace/my
lib/libs/x86/gdb.setup
Gdbserver      : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
mkdir -p /cygdrive/d/android/workspace/mylib/libs/armeabi
install -p /cygdrive/d/android/android-ndk-r6b/toolchains/arm-linux-androideabi-
4.4.3/prebuilt/gdbserver /cygdrive/d/android/workspace/mylib/libs/armeabi/gdbser
ver
Gdbsetup       : libs/armeabi/gdb.setup
mkdir -p /cygdrive/d/android/workspace/mylib/libs/armeabi
echo "set solib-search-path D:/android/workspace/mylib/obj/local/armeabi" > /cyg
drive/d/android/workspace/mylib/libs/armeabi/gdb.setup
echo "directory D:/android/android-ndk-r6b/platforms/android-9/arch-arm/usr/incl
ude D:/android/android-ndk-r6b/sources/cxx-stl/system/include D:/android/workspa
ce/mylib/jni" >> /cygdrive/d/android/workspace/mylib/libs/armeabi/gdb.setup

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Заметил, что в том, что вы перечислили для своего файла Android.mk, у вас есть в самом конце:

#include $(BUILD_STATIC_LIBRARY)

вместо:

include $(BUILD_STATIC_LIBRARY)

Последнее, вероятно, то, что вам нужно. Обратите внимание на исключение хеш-тега в «фиксированной» версии. Я нашел эту аномалию и погуглил для примера файл android.mk. Первый, который я нажал и, конечно же, был для примера Hello-World, похожего на то, что вы, вероятно, пытаетесь сделать. Надеюсь, это поможет.

** Edit: Даже если мой ответ решит некоторые ваши проблемы, прислушайтесь к совету NuSkooler. Его ответ описывает, как make files «видит» имя вашего файла mylib.a. Поверьте ему, если вы поставите libmylib вместо mylib.a, это сработает. Я сделал это в файлах make для компиляторов GCC, таких как MinGW32. **

0 голосов
/ 10 сентября 2011

Создайте mylib как статическую библиотеку вместо общего объекта (файл .so). Затем в вашем Android.mk, который определяет helloworld, перечислите статическую библиотеку как зависимость:

LOCAL_STATIC_LIBRARIES := libmylib
...