在某些情况下,是否有任何令人信服的性能原因选择静态链接而不是动态链接?我已经听过或读过以下内容,但我对这个问题的了解不足以保证它的真实性.
1)静态链接和动态链接之间的运行时性能差异通常可以忽略不计.
2)(1)如果使用使用配置文件数据优化程序热路径的配置文件编译器,则不成立,因为使用静态链接,编译器可以优化代码和库代码.通过动态链接,您的代码可以进行优化.如果大部分时间都花在运行库代码上,那么这可能会产生很大的不同.否则,(1)仍然适用.
我已经尝试了几天来编译一个本机ARM Android二进制文件,它将使用终端应用程序在我的手机上执行.我想生成与手机上安装的标准Posix二进制文件相同类型的二进制文件,如ls,mkdir等.我已经在Mac OS X下载了Android NDK,并且能够无错误地编译简单的ELF二进制文件.但是,当我将它们转移到手机时,它们总是会出现段错误.也就是说,在GCC中使用-static编译时会出现段错误.如果我不使用-static,他们会抱怨没有链接等等.简单来说,它们不起作用.
我的假设是它们没有正确链接到Android标准C库.即使我将我的二进制文件与NDK提供的libc链接,它们仍然无法正常工作.我读到Android使用Bionic C库,并尝试下载它的源代码,但我不知道如何从它构建一个库(它似乎是所有ARM程序集).
手机上的Android C库是否与Android NDK提供的库不同?包含在NDK中的那个不允许我编译我可以通过终端执行的本机二进制文件吗?非常感谢任何指导!
更新:
我终于在Mac OS X上使用GCC 4.7.0了解它.我下载了Bionic标头,然后使用Android NDK附带的C库编译了一个动态链接的二进制文件.我能够使用手机的C lib(二进制为33K)获得一个测试应用程序在手机上工作.我还尝试静态链接NDK的C库,这也很有用.
为了使这一切正常工作,我必须将-nostdlib传递给GCC,然后手动将crtbegin_dynamic.o和crtend_android.o添加到GCC的命令行.它的工作原理如下:
$CC \
$NDK_PATH/usr/lib/crtbegin_dynamic.o \
hello.c -o hello \
$CFLAGS \
$NDK_PATH/usr/lib/crtend_android.o
Run Code Online (Sandbox Code Playgroud)
对于静态二进制文件,请使用"crtbegin_static.o".这在crtbegin_dynamic.S/crtbegin_static.S源中进行了解释.
对于这个实验,我只使用普通的'ol GCC 4.7.0和Binutils 2.22.我还使用newlib编译了GCC,但我实际上并没有将我的ARM二进制文件与newlib链接起来.我强迫GCC/ld直接链接到随Android NDK提供的libc,或者在动态二进制文件的情况下,链接到手机上的libc.
我将开始一个新的C++项目,该项目将依赖于一系列库,包括部分Boost库,log4cxx或google日志库 - 并且随着项目的发展,其他项目(我还没有预料到) .
它必须在32位和64位系统上运行,很可能是在一个非常多样化的Linux环境中,我不希望所有必需的库都可用,也不需要su权限.
我的问题是,我应该通过动态或静态链接到所有这些库来构建我的应用程序吗?
笔记:
(1)我知道静态链接在开发过程中可能会很痛苦(编译时间较长,32位和64位交叉编译,依赖链包含所有库等),但在测试过程中更容易 - 只需移动文件即可运行.
(2)另一方面,动态链接接缝在开发阶段更容易 - 编译时间短(不知道如何处理来自我的32位开发环境的64位库的动态链接),没有依赖链的喧嚣.另一方面,新版本的部署可能很难看 - 特别是在需要新库时(参见上述条件,目标机器上没有su权限,也没有这些库可用).
(3)我已阅读有关此主题的相关问题,但无法确定哪种方法最适合我的方案.
结论: