ndk-build produits " erreur lors de l'ajout de symboles. Fichier en format incorrect’
Je veux utiliser exiv2 bibliothèque écrite en C++ dans mon projet Android. Pour le faire j'ai essayer de cross-compiler la bibliothèque à l'aide de Android NDK.
Pour la cross-compilation-je suivre présenté les étapes ci-dessous:
- Ajouter le ndk chemin à CHEMIN de la variable
$ PATH="/home/patrycja/android-packages/ndk:${PATH}" $ export PATH
- Installer le standard de la chaîne de cross-compilation C/C++ pour Android.
./make-standalone-toolchain.sh --platform=android-21 --install-dir=/tmp/my-android-toolchain --ndk-dir='/home/patrycja/android-packages/ndk/' --toolchain=arm-linux-androideabi-4.9 --system=linux-x86_64 Copying prebuilt binaries... Copying sysroot headers and libraries... Copying c++ runtime headers and libraries... Copying files to: /tmp/my-android-toolchain Cleaning up... Done.
- Définir certaines variables d'environnement ainsi que la configuration et le processus de création d'utiliser le bon compilateur.
$ export PATH=/tmp/my-android-toolchain/bin:$PATH $ export CC="arm-linux-androideabi-gcc" $ export CXX="arm-linux-androideabi-g++" $ export CFLAGS='-mthumb -O2' $ export CXXFLAGS='-mthumb -O2' $ export LDFLAGS='-Wl,--fix-cortex-a8' $ export LIBS='-lstdc++ -lsupc++'
- Bulid la bibliothèque statique et suffisante en-têtes
./configure --prefix=$(pwd)/build --host=arm-linux-androideabi --disable-shared --disable-xmp --disable-nls
Résultat: j'ai créé la "construction" de la catégorie fichiers:
├── bin
│ └── exiv2
├── include
│ └── exiv2
│ ├── *.hpp
│
├── lib
│ ├── libexiv2.a
│ ├── libexiv2.la
│ └── pkgconfig
│ └── exiv2.pc
└── share
└── man
└── man1
└── exiv2.1
J'ai copié créé bibliothèque statique libexiv2.a
et include
dossier de mon projet Android dans appName/src/main/jni/prebuild
.
Android.mk
ressemble:
LOCAL_PATH := $(call my-dir)
#static library info
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/libexiv2.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include/
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)
#wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../prebuild/include/
LOCAL_MODULE := helloJNI
LOCAL_SRC_FILES := helloJNI.cpp
LOCAL_STATIC_LIBRARIES := exiv2
include $(BUILD_SHARED_LIBRARY)
Dans mon wrapper Android, et j'essaie d'utiliser la bibliothèque. Il semble comme suit:
#include <string.h>
#include <jni.h>
#include <exiv2/exiv2.hpp>
extern "C" {
JNIEXPORT jstring JNICALL Java_com_example_patrycja_testndi2_MyActivity_helloJNI(JNIEnv *env, jobject thiz)
{
std::ostringstream os;
std::string file("/storage/emmc/DCIM/100MEDIA/IMAG0021.jpg");
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
return env->NewStringUTF("asldjaljd");
}
}
Cependant ndk-build
sorties qu'il ne peut pas le trouver.
[arm64-v8a] Compile++ : helloJNI <= helloJNI.cpp
[arm64-v8a] SharedLibrary : libhelloJNI.so
jni/../prebuild/libexiv2.a: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [obj/local/arm64-v8a/libhelloJNI.so] Error 1
Je crois qu'il y a quelque chose de mal avec des drapeaux de compilation croisée. J'ai essayé plusieurs options, mais quelque chose est toujours mal.
J'ai suivi ces instructions: https://groups.google.com/forum/#!topic/android-ndk/mYh1LzMu_0U
OriginalL'auteur rocksparrow | 2015-06-04
Vous devez vous connecter pour publier un commentaire.
vous ai compilé exiv2 pour armv5+ les appareils fonctionnant au moins Sucette. Ici ndk-build échoue parce qu'il essaie de lien à partir d'un arm64-v8a de la bibliothèque du bâtiment.
La compilation croisée sans l'aide de ndk-build est dur pour obtenir le droit sur Android, d'autant que l'on doit soutenir non seulement armv5, mais aussi armv7, x86, x86_64, arm64-v8a...
Vous devez d'abord définir la
--platform
option au même niveau que votre minimum SDK niveau. Puis reconstruire votre lib et de le placer sous../prebuild/armeabi
.Ensuite, la compilation croisée votre lib pour architecture x86:
et déplacer le créé .un de
../prebuild/x86
.Idéalement, vous devez répéter le même processus pour armeabi-v7a, mips, mips64, arm64-v8a.
Enfin, vous pouvez inclure le droit .un à l'intérieur de votre Android.mk à l'aide de la
TARGET_ARCH_ABI
variable, comme ceci:et à l'intérieur de Application.mk (créer un nouveau fichier si il n'existe pas), spécifier les architectures que vous êtes le soutien et la plate-forme minimum que vous ciblez:
jni/../prebuild/armeabi-v7a/libexiv2.a(pngchunk.o):pngchunk.cpp:function Exiv2::Internal::PngChunk::parseChunkContent(Exiv2::Image*, unsigned char const*, long, Exiv2::DataBuf): error: undefined reference to 'std::__throw_out_of_range_fmt(char const*, ...)'
J'ai utilisé une mauvaise version de gcc. Il fonctionne avec 4.8.
Cette solution suppose l'héritage ndk gradle construire. Avec la nouvelle gradle-expérimentale système de build, il n'y a pas de Application.mk.
la question d'origine était sur le ndk-build donc la réponse est toujours précis. Si vous avez le même genre de problème avec gradle et l'expérimental plugin, vous devez ouvrir une nouvelle question.
OriginalL'auteur ph0b