我一直在将一些Linux工具(以及我自己的一些C代码)交叉编译到Android,我面临的挑战之一就是Android的libc有一些缺失/剥离的组件,我最终修补了我的代码它适用于Android的libc(例如像http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html这样的问题)
Q1:在使用arm工具链(或ndk-build)进行交叉编译时,如何静态链接glibc(以及其他依赖项)?
Q2:对于Android的二进制文件静态链接glibc是一个好主意吗?如果我开始静态链接,我是否应该期待任何事情?有任何性能/内存问题吗?
我从这里了解静态与动态链接的大部分优缺点 - C++ application - should I use static or dynamic linking for the libraries?和 Static linking vs dynamic linking
所以我想知道在交叉编译二进制文件时是否应该静态链接glibc for Android。
答案 0 :(得分: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构建为静态库,那么上面的整个问题就会被回避,因为您永远不需要安装静态库。
现在回答你的问题:
Q1:如果你使用NDK构建glibc,那么Android.mk使用变量BUILD_STATIC_LIBRARY来构建静态库。但是,如果你不使用NDK,那么你可能需要进入很多头痛(不知道多少)。我无法告诉你更多关于这一点,因为我还没有尝试构建glibc,无论是静态的还是动态的。此外,似乎非常不鼓励静态链接与glibc,至少对于非移动平台而言。
从破损的角度来看,静态和动态链接之间没有区别。从启动的角度来看,静态可执行文件启动速度更快,因为不需要动态库加载步骤。静态或动态链接可执行文件中没有内存或执行速度损失。静态可执行文件的磁盘存储要求更高。
对于仿生libc缺失功能的问题,您可以使用大多数GNU软件使用的方法,即在系统库中缺少函数时提供您自己的函数实现。我已经编译了文件-5.11,GNU make 3.82,diffutils-2.8 for Android将NDK工具链/ includes / libs传递给autotools(./configure ...)。似乎这些程序包含大多数非核心库函数的实现,以防标准库不提供它们(在本例中为Bionic)。
注意:我会尝试构建静态glibc并在成功/失败时更新答案。
答案 1 :(得分:2)
如果您打算使用glibc而不是仿生,那么使用(兼容的内核生成)arm-linux发行版而不是ndk的工具链可能是值得的。如果要生成命令行可执行文件,则尤其如此。 (人们已经在Android设备上实验性地推动了chroot debian环境一直回到G1)
对于jni sub(它仍然是本机应用程序代码的唯一正式认可的工具),它可能会对任何工具链都有点“有趣”,因为您将在已经映射并正在持续使用的过程中运行仿生libc支持Dalvik VM。据推测,如果你静态链接库自己的依赖关系,你就不会遇到名称冲突,但我希望你选择的任何路径都是关于内部工作的学习经验 - 而不是那些必然是坏事。
你必须有ncurses吗?我用ndk成功地为android构建了curses。还要考虑该程序是否正在认真利用它(即,您实际上是在进行实质性的文本格式化吗?),还是只是将它用于某些小事情,因为它被假定在目标系统上可用?