10

I have been cross-compiling some Linux tools (and some of my own C code) to Android and one of the challenges that I face is that Android's libc has some missing/stripped components and I end up patching my code to make it work with Android's libc (for e.g. a problem like this http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html)

Q1 : How do I go about statically linking against glibc (and other dependencies) while cross-compiling with the arm toolchain (or ndk-build)?

Q2 : Is it a good idea to statically link against glibc for binaries for Android? Should I expect anything to break if I start statically linking? Are there any performance/memory issues?

I understand most of the pros and cons of static vs dynamic linking from here - C++ application - should I use static or dynamic linking for the libraries? and Static linking vs dynamic linking

So I wish to know if I should be statically linking glibc for Android when cross-compiling binaries.

4

2 回答 2

5

首先是关于 libc 的一个小注释。Android libc 是 Bionic libc ( https://github.com/android/platform_bionic/ ) 而不是 GNU libc (glibc)。因此,NDK 中包含的 libc 是 Bionic,Android 设备上可用的 libc 也是如此。

就 glibc 而言,可以使用 NDK 构建它。但是,当它安装在 android 设备上时,它的名称会与系统 libc 冲突。请注意,这仅适用于构建动态库的情况。如果您将 GNU libc 构建为静态库,那么上面的整个问题都可以回避,因为您永远不需要安装静态库。

现在回答你的问题:

  1. Q1:如果您使用 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 工具链/includes/libs 传递给了 autotools (./configure ...)。这些程序似乎包含大多数非核心库函数的实现,以防标准库不提供它们(在这种情况下是仿生)。

注意:我将尝试构建一个静态 glibc,并在成功/失败时更新答案。

于 2012-05-01T09:32:38.043 回答
2

如果您打算使用 glibc 而不是仿生,则可能值得考虑使用(兼容内核生成)arm-linux 发行版的工具链而不是 ndk。如果您正在生成命令行可执行文件,则尤其如此。(人们一直在尝试将 chroot debian 环境推到 android 设备上,直到 G1)

对于 jni sub(它仍然是唯一官方认可的本地应用程序代码工具),它可以使用任一工具链变得有点“有趣”,因为您将在一个已经映射并正在持续使用仿生 libc 的进程中运行支持 Dalvik 虚拟机。据推测,如果您静态链接库自己的依赖项,您将不会遇到名称冲突,但我希望您选择的任何路径都将是关于内部工作的学习体验 - 这不一定是一件坏事。

你必须有ncurses吗?我曾经用 ndk 成功地为 android 构建了诅咒。还要考虑程序是否认真地利用了这一点(即,您实际上是否在进行大量文本格式化?),或者只是因为假设它在目标系统上可用而将其用于一些小事情?

于 2012-05-01T12:37:53.817 回答