Ndk-build输出添加符号错误.文件格式错误



我想在我的Android项目中使用c++编写的exiv2库。为了做到这一点,我尝试使用Android NDK交叉编译库。

对于交叉编译,我遵循以下步骤:
  1. 将NDK路径添加到变量path

    PATH="/home/patrycja/android-packages/ndk:${PATH}"
    export PATH
    
  2. 安装用于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.
    
  3. 设置一些环境变量,以便配置和构建过程将使用正确的编译器。

    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++'
    
  4. 构建静态库和足够的头文件

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

我将创建的静态库libexiv2.ainclude文件夹复制到我的Android项目appName/src/main/jni/prebuild中。

Android.mk看起来像:

LOCAL_PATH := $(call my-dir)
# Static library information
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/libexiv2.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include/
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)
# Wrapper information
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 <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");
    }
}

但是ndk-build输出它找不到它。

[arm64-v8a] Compile++      : helloJNI &lt;= 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

我认为交叉编译中的标志有问题。我已经尝试了几种方法,但还是有问题。

我遵循了这些说明:如何从本地Android代码使用外部c++库

您已经为armv5+设备编译了exiv2,至少运行Android 5.0 (Lollipop)。这里ndk-build失败了,因为它试图从它正在构建的arm64-v8a库链接它。

不使用ndk-build的交叉编译很难在Android上正确进行,特别是当你不仅要支持armv5,还要支持armv7, x86, x86_64, arm64-v8a等时。

您应该首先将--platform选项设置为与最低SDK级别相同的级别。然后重新构建库并将其放在../prebuild/armeabi下。

然后交叉编译你的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重复相同的过程。

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

LOCAL_PATH := $(call my-dir)
# Static library information
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 information
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)

应用程序内部。Mk (如果不存在,创建一个新文件),指定您支持的架构和您针对的最小平台:

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

相关内容

  • 没有找到相关文章

最新更新