【问题标题】:Android Static Linking vs Dynamic Linking against glibcAndroid静态链接与针对glibc的动态链接
【发布时间】:2012-05-09 23:02:40
【问题描述】:

我一直在将一些 Linux 工具(以及我自己的一些 C 代码)交叉编译到 Android,我面临的挑战之一是 Android 的 libc 有一些缺失/剥离的组件,我最终修补了我的代码以制作它适用于 Android 的 libc(例如像 http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html 这样的问题)

Q1:如何在与 arm 工具链(或 ndk-build)交叉编译时静态链接 glibc(和其他依赖项)?

Q2:静态链接 glibc 以获取适用于 Android 的二进制文件是个好主意吗?如果我开始静态链接,我是否应该期待任何事情发生?是否有任何性能/内存问题?

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

所以我想知道在交叉编译二进制文件时是否应该为 Android 静态链接 glibc。

【问题讨论】:

    标签: android android-ndk static-linking dynamic-linking libc


    【解决方案1】:

    首先是关于 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,并在成功/失败时更新答案。

    【讨论】:

    • 这不仅仅是磁盘上的使用 - 内存中的使用也增加了。当您将 Android 应用的 jni 库链接到 Bionic libc 时,您将继承对内存中已有副本的共享只读访问权限。
    • 您能否指出您在这方面的信息来源?我想知道更多,但在这方面找不到任何东西。我确实知道,如果库包含任何数据,则数据似乎不会在进程之间共享,但是如果库代码更改其内部数据变量,这可能只是内存页面的写时复制复制的情况。
    • 我相信 ChrisStratton 提到了 - 静态链接 libc 的情况。每个进程都会以自己的同一个库的所有部分的完整副本结束。使用动态链接,你是正确的@Samveen
    【解决方案2】:

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

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

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-12
    • 2010-10-01
    • 2010-12-31
    • 2012-12-29
    • 1970-01-01
    相关资源
    最近更新 更多