android - 使用独立工具链编译的 Libogg(由 NDK 脚本生成)尝试从不正确的文件加载自身 - libogg.so.0 而不是 libogg.so

标签 android c android-ndk shared-libraries ogg

我正在尝试将 libogg 添加到我的 android NDK 项目中。

我正在使用 SDL 库附带的项目模板。

我在 Windows 上,所以以下所有脚本都是在 MSYS(一个 Linux 终端仿真器)下执行的。

首先,我生成了一个独立的工具链。

android-ndk/build/tools/make-standalone-toolchain.sh --platform=android-12 --system=windows-x86_64 --toolchain=arm-linux-androideabi-4.9 --install-dir=Y:/gcc_android_androideabi-4.9_api12/

然后我构建了库。

make clean
configure CC="/y/gcc_android_androideabi-4.9_api12/bin/arm-linux-androideabi-gcc" LIBS="-lgnustl_shared" CFLAGS="-mthumb" --host=arm-linux-androideabi
make

然后我将生成的 libogg.so 复制到我的项目文件夹并将以下内容添加到我的 jni/src/Android.mk:

...

include $(CLEAR_VARS)
LOCAL_MODULE := ogg-prebuilt
LOCAL_SRC_FILES := ../../prebuilt-libs/$(TARGET_ARCH_ABI)/libogg.so
include $(PREBUILT_SHARED_LIBRARY)

...

LOCAL_SHARED_LIBRARIES := ... ogg-prebuilt ...

...

类似的代码适用于我使用的其他库。

ndk-build 成功找到我的库并将它们添加到 .apk

当我在运行时调用 System.loadLibrary("ogg"); 时出现问题。动态链接器给我的错误消息是这样的

Can't find library "libogg.so.0".

我确定我的库加载代码没有问题,因为它适用于我拥有的其他库。

动态链接器的错误很有趣,因为 make 不只是生成单个 libogg.so。它生成了 3 个完全相同但名称不同的文件:libogg.solibogg.so.0libogg.so.0.8.2

我尝试用 libogg.so.0 替换 libogg.so 并正确调整 Android.mk ,但是 NDK 构建脚本在我,说预建的共享库必须有 .so 扩展名。我试图将 libogg.so.0 复制到 libs/ 文件夹,但是 NDK 构建脚本在构建 .apk 时忽略了它。

然后我在十六进制编辑器中打开 libogg.so 并搜索 libogg。我只发现了一个:libogg.so.0[NUL]。我用 2 个 [NUL] 替换了 .0,所以它变成了 libogg.so[NUL][NUL][NUL] 和现在的库完美加载。


我可以使用我使用的所有工具链重现此错误:arm-linux-androideabi-gcc-4.9i686-linux-android-gcc-4.9mipsel-linux-android-gcc-4.9。它们都是使用类似的脚本生成的。

如果我将 libogg.so.0libogg.so.0.8.2 重命名为 libogg.so 并使用它,错误仍然存​​在而不是原来的。正如我所说,这三个文件都具有相同的内容。

虽然我可以制作一个 sed 脚本来在必要时自动修复 .so 文件中的库名称,但我想知道是否有更好的解决方案来解决这个问题.

也许我必须在 configure 中添加一些标志?

最佳答案

我稍微不那么老套的解决方法是从 libogg 的构建系统中删除版本信息。

在您拥有 libogg 源代码的目录中,打开文件 src/Makefile.am 并更改此行:

libogg_la_LDFLAGS = -no-undefined -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@

libogg_la_LDFLAGS = -avoid-version

如果您没有安装 automake,那么您可以在运行 ./configure 后更改生成的 Makefile。找到 libogg_la_LDFLAGS 并对上面详述的内容进行类似的更改。在 Linux 上,像这样的 sed 一行就可以完成这项工作:

sed -i 's/^libogg_la_LDFLAGS.*/libogg_la_LDFLAGS = -avoid-version/g' src/Makefile

关于android - 使用独立工具链编译的 Libogg(由 NDK 脚本生成)尝试从不正确的文件加载自身 - libogg.so.0 而不是 libogg.so,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35039189/

相关文章:

android - 如何找到我的 sqlite 在 Android 中泄漏的位置

c - 当我试图用 C 读取文件时,为什么 fscanf 会随机更改字符串中的字符?

c - 需要帮助解决奇怪的 fscanf 问题

java - JNI 构建 gradle 无法找到 ndk 目录

opencv - 这种时差的原因是什么?

android - 使用Android NDK实现EDSDK

android - 找不到参数 [] 的方法 getCompileConfiguration()

在 android Kitkat 中找不到 android.support.v4.content.FileProvider 类

c - 未能在 C 中实现一个非常简单的堆栈数组

android - 将 Realm android 添加到 flutter 项目中不起作用