Android静态链接与动态链接对抗glibc

10

我一直在将一些Linux工具(和我自己的C代码)交叉编译到Android上,其中一个挑战是Android的libc缺少/剥离了一些组件,导致我不得不修补我的代码以让它与Android的libc配合使用(例如像这样的问题:http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html

问题1:在使用arm工具链(或ndk-build)进行交叉编译时,如何进行静态链接glibc(和其他依赖项)?

问题2:对于Android的二进制文件来说,静态链接glibc是一个好主意吗?如果我开始静态链接,是否应该期望出现任何问题?是否存在性能/内存问题?

我从这里了解了大部分静态链接与动态链接的优缺点: C++ application - should I use static or dynamic linking for the libraries?Static linking vs dynamic linking

因此,我希望知道当我交叉编译二进制文件时,是否应该静态链接glibc。

2个回答

5
首先,关于libc的一个小注释。Android libc是Bionic libc(https://github.com/android/platform_bionic/),而不是GNU libc(glibc)。因此,在NDK中包含的libc是Bionic,同样可在android设备上使用。
至于glibc,可以使用NDK构建它。但是,如果安装在android设备上,它的名称将与系统libc冲突。请注意,这仅适用于构建动态库的情况。如果将GNU libc构建为静态库,则可以避开上述整个问题,因为您永远不需要安装静态库。
现在来回答你的问题:
  1. 问题1: 如果你正在使用NDK构建glibc,则Android.mk使用变量BUILD_STATIC_LIBRARY来构建静态库。然而,如果你不使用NDK,则可能需要遇到很多麻烦(我不知道有多少)。我无法告诉你更多信息,因为我没有尝试过构建glibc,无论是静态还是动态的。此外,似乎强烈不建议在非移动平台上使用glibc进行静态链接。

  2. 从破坏的角度来看,静态链接和动态链接之间没有区别。从启动的角度来看,静态可执行文件启动更快,因为不需要加载动态库。静态链接和动态链接的可执行文件在内存或执行速度上都没有惩罚。静态可执行文件的磁盘存储需求更大。

就缺失功能的生化libc问题而言,您可以使用大多数GNU软件使用的方法,即在系统库中缺失某个函数时提供自己的实现。我已经为Android编译了file-5.11、GNU make 3.82和diffutils-2.8,将NDK工具链/包含/库传递给autotools(./configure…)。看起来这些程序包含大多数非核心库函数的实现,以防标准库不提供它们(在这种情况下是Bionic)。
注意:我将尝试构建静态glibc,并根据成功或失败更新答案。

1
不仅是磁盘上的使用量增加,还有内存中的使用量增加。当您将Android应用程序的jni库与Bionic libc链接时,您会继承对已经存在于内存中的共享只读访问的副本的访问权限。 - Chris Stratton
你能告诉我这方面的信息来源吗?我想了解更多,但是找不到相关信息。我知道如果库包含任何数据,该数据似乎不会在进程之间共享,但如果库代码更改其内部数据变量,则可能只是写时复制复制内存页面的情况。 - Samveen
我相信ChrisStratton提到了静态链接libc的情况。每个进程最终都会拥有同一库的所有部分的自己的完整副本。使用动态链接,你是正确的@Samveen。 - Tuxdude

2
如果你使用glibc而不是bionic,那么使用兼容内核版本的arm-linux发行版工具链可能值得考虑,而不是使用ndk。如果生成命令行可执行文件,尤其是如此。(人们实验性地将chroot debian环境推到了从G1开始的Android设备上)

对于jni子目录(仍然是唯一被官方认可的本地应用程序代码载体),无论使用哪种工具链,都可能会有一些“有趣”的事情发生,因为你将在已经映射并正在持续使用bionic libc来支持Dalvik VM的进程中运行。假设你静态链接库自己的依赖项,就不会遇到名称冲突,但我预计,无论你选择哪条路径,这都将是一个关于内部工作方式的学习经历-不一定是件坏事。

你必须要使用ncurses吗?我曾经成功地用ndk为Android构建过curses。还要考虑程序是否真正利用了它(即,你实际上是否在做大量的文本格式化?),或者只是因为在目标系统上假定它是可用的而使用它进行一些小事情?


你可能想过来回答这个问题:https://dev59.com/X2gv5IYBdhLWcg3wKtvj - Prof. Falken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接