【问题标题】:Using CrystaX with Qt to build android application: java.lang.UnsatisfiedLinkError使用 CrystaX 和 Qt 构建 android 应用程序:java.lang.UnsatisfiedLinkError
【发布时间】:2015-12-04 07:19:46
【问题描述】:

我正在尝试使用Qt Creator 为Android 构建Qt application。我将CrystaX NDK 用于android 而不是goolge 的,因为我需要在我的项目中使用boost libraries,并且正如CrystaX 的官方网站所说,它是自带的。

我正在使用以下版本的工具:

  • Qt Creator 3.4.2
  • Qt 5.5.0
  • CrystaX NDK 10.2.1

起初,我不得不在我的.pro 文件中手动添加库和头文件路径,因为它没有被自动找到。出现编译器错误:can't locate libcrystax,源文件中有一些关于包含boost headers 的错误。我在我的项目文件中添加了以下几行:

android {
    INCLUDEPATH +=  $$NDK_ROOT/sources/crystax/include \
                    $$NDK_ROOT/sources/boost/1.58.0/include \
                    $$PWD/ssl
    LIBS += -L"$$PWD/ssl" -lssl -lcrypto
    LIBS += -L"$$NDK_ROOT/sources/crystax/libs/$$ANDROID_TARGET_ARCH"
    ANDROID_EXTRA_LIBS = $$NDK_ROOT/sources/crystax/libs/$$ANDROID_TARGET_ARCH/libcrystax.so
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
}

再次重建后,我收到了一个错误 (runtime error),上面写着 libgnustl_shared requires libcrystax, but libcrystax is not loaded 或类似的东西。

在搜索互联网后,我发现它正在发生,因为一个需要另一个库的库在它之前加载,而第二个库没有被搜索,在应用程序目录中,仅在系统路径中。

我找到了一种解决方法 - 手动加载所需的库。我将默认 QtActivity.java 复制到我的项目目录 (android/src/.../QtActivity.java) 以替换默认值并添加以下代码:

static {
    System.loadLibrary( "crystax" );
}

在那之后我没有收到那个错误,但现在我遇到了另一个错误:

java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1285]: 37 cannot locate '__aeabi_ldiv0'...

是否可以使用Qt + CrystaX NDK 构建安卓应用程序?我做错了吗?如果我弄错了或者我误解了整个概念,请解释如何正确地做到这一点。任何帮助表示赞赏。

【问题讨论】:

    标签: android qt android-ndk qt5


    【解决方案1】:

    发生这种情况是因为您尚未与 libgcc.a 关联。我不知道您的构建系统究竟是如何工作的(好吧,Qt 就是这样),但一般来说,将 libgcc.a 添加到其他库列表中应该会有所帮助:

    ANDROID_EXTRA_LIBS = $$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9/libgcc.a
    

    这一行指定arm 的变体libgcc.a;显然,您应该根据ANDROID_TARGET_ARCH 值使用正确的值。

    【讨论】:

    • 感谢您的回答!你能看看 libgcc.a 文件的 nm 输出吗?可以吗,它有两个未定义的符号和一个弱的名称(__aeabi_ldiv0)? nm $$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9/armv7-a/libgcc.a | grep ldiv0: U __aeabi_ldiv0, U __aeabi_ldiv0, 00000000 W __aeabi_ldiv0
    • 是的,没关系。这就是libgcc.a 的构造方式——它是由一堆目标文件 (.o) 构建的,其中两个需要 __aeabi_ldiv0(因此它在 nm 输出中显示为 U __aeabi_ldiv0),一个定义它(因此它出现在 nm 输出中为 W __aeabi_ldiv0)。之所以将__aeabi_ldiv0 定义为弱符号,是因为它允许开发人员在需要时替换它——例如,提供替代的、更优化的版本。但是,如果开发人员不想用自己的版本替换它,它就可以工作。
    • 谢谢!我发现libgnustl_shared 需要libcrystax 才能加载,而libQt5Core 需要libgnustl_shared 才能加载。 libQt5Core.so 使用 Google NDK 构建并由 Qt 5 框架提供。我正在尝试使用CrystaX NDK 构建android 包。所以这个包是用来自Crystax NDKlibQt5Corelibgnustl_shared完成的,它们期望来自Google NDKlibgnustl_shared。这可能是该错误的原因吗?我已经手动链接了libgcc.a,但似乎已经过分了,因为它已经被构建工具链接了。
    • 嗯,很难说你的情况下错误的确切原因是什么。它实际上很大程度上取决于我不知道的 Qt 的构建系统。我计划看看 Qt,并发表关于使用 Qt + CrystaX NDK 的文章,但还没有完成。但是,通常最好使用 Google 的 Android NDK 或 CrystaX NDK 构建所有二进制文件,而不是将它们交错。在 CrystaX NDK 中,我们不保证与 Google 的 Android NDK 的二进制兼容性,我们只保证 CrystaX NDK 可以用作 Google 的替代品。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多