微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android – ndk-build输出错误添加符号.文件格式错误’

我想在我的Android项目中使用用C编写的exiv2库.为此,我尝试使用Android NDK交叉编译库.

对于交叉编译,我遵循以下步骤:

>将ndk路径添加到变量PATH

$PATH="/home/patrycja/android-packages/ndk:${PATH}"
$export PATH 

>安装标准工具链,以便为Android交叉编译C/C++.

./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.

>设置一些环境变量,以便配置和构建过程将使用正确的编译器.

$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静态库和足够的标头

./configure --prefix=$(pwd)/build --host=arm-linux-androideabi --disable-shared --disable-xmp --disable-nls

结果我创建了’build’类别文件

    ├── bin
    │   └── exiv2
    ├── include
    │   └── exiv2
    │       ├── *.hpp
    │
    ├── lib
    │   ├── libexiv2.a
    │   ├── libexiv2.la
    │   └── pkgconfig
    │       └── exiv2.pc
    └── share
        └── man
            └── man1
                └── exiv2.1

我在appName / src / main / jni / prebuild中复制了创建的静态库libexiv2.a并将文件夹包含到我的Android项目中.

Android.mk看起来像:

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)

在Android的包装器中,我尝试使用该库.它看起来如下:

#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");
    } 
}

但是ndk-build输出它无法找到它.

[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

我相信交叉编译中的标志有问题.我尝试了几种选择,但仍有问题.
我遵循了这些说明:https://groups.google.com/forum/#!topic/android-ndk/mYh1LzMu_0U

最佳答案
你为至少运行Lollipop的armv5设备编译了exiv2.这里ndk-build失败了,因为它试图从它正在构建的arm64-v8a库中链接它.

不使用ndk-build进行交叉编译很难在Android上正确使用,特别是因为你不仅应该支持armv5,而且还应该支持armv7,x86,x86_64,arm64-v8a ……

您应该首先将–platform选项设置为与最低SDK级别相同的级别.然后重建您的lib并将其放在../prebuild/armeabi下.
然后交叉编译你的lib也用于x86架构:

./make-standalone-toolchain.sh --platform=android-9 --install-dir=/tmp/my-android-toolchain-x86 --ndk-dir='/home/patrycja/android-packages/ndk/' --arch=x86 --toolchain=x86-4.8 --system=linux-x86_64

$export PATH=/tmp/my-android-toolchain-x86/bin:$PATH
$export CC="i686-linux-android-gcc"
$export CXX="i686-linux-android-g++"
$export CFLAGS='-O2 -mtune=atom -mssse3 -mfpmath=sse' 
$export CXXFLAGS='-O2 -mtune=atom -mssse3 -mfpmath=sse' 
$export LDFLAGS='' 
$export LIBS='-lstdc++ -lsupc++' 

./configure --prefix=$(pwd)/build-x86 --host=x86 --disable-shared --disable-xmp --disable-nls

并将创建的.a移动到../prebuild/x86.

理想情况下,您应该对armeabi-v7a,mips,mips64,arm64-v8a重复相同的过程.

最后,您可以使用TARGET_ARCH_ABI变量在Android.mk中包含正确的.a,如下所示:

LOCAL_PATH := $(call my-dir)

#static library info
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/$(TARGET_ARCH_ABI)/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)

在Application.mk(创建一个文件,如果它不存在)中,指定您支持的体系结构和您要定位的最小平台:

APP_ABI := armeabi x86 # ideally,this should be set to "all"
APP_PLATFORM := android-14 # should the same as -platform and your minSdkVersion.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐