Optimization -gcc的静态选项?

Optimization -gcc的静态选项?,optimization,gcc,compiler-construction,static,options,Optimization,Gcc,Compiler Construction,Static,Options,我想知道gcc上的-static选项做了什么。在编译某个应用程序时,我需要此选项,但是当我这样做时,会出现以下错误: gcc -static -O3 -o prog prog.c /usr/bin/ld: cannot find -lc collect2: ld returned 1 exit status 什么需要安装 GCC版本: [user@localhost dir]$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_W

我想知道gcc上的-static选项做了什么。在编译某个应用程序时,我需要此选项,但是当我这样做时,会出现以下错误:

gcc -static -O3 -o prog prog.c
/usr/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
什么需要安装

GCC版本:

[user@localhost dir]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.6.1 20110908 (Red Hat 4.6.1-9) (GCC) 

-static
标志强制链接器仅接受静态库,而不接受任何共享库


如果要使用
-static
,必须确保安装了C库的静态版本,这可能很难找到(大多数系统不再有静态C库)。或者您必须取消
-static
的效果。然而,在本例中,这将破坏
-static
的目的,因为唯一链接的库是(隐式地)C库。

选项
-static
静态链接程序,换句话说,它不需要在运行时依赖于动态库才能运行

要实现静态链接,需要系统上存在库的存档(.a)版本。所以/usr/lib/libc.a/usr/lib/crt1.o等等

在现代linux系统上(正如您使用的red hat):当二进制文件链接在一起时,1)通过.o和.a文件将代码放入可执行文件,或2)插入动态库(.so)文件的引用,动态库(.so)文件由/lib/ld-linux.so(或/lib64/ld-linux=x86-64.so)解析,该文件始终位于一个众所周知的位置


对于您的特定系统,如果程序特别希望创建自身的静态版本,那么您需要安装devel工具的静态版本。您至少需要glibc静态包。您可能还需要libstdc++-static软件包。

是否有任何特殊原因导致不能简单地让链接器静态附加链接器可用库中的代码?即使代码中的引用被格式化为必须在运行时解析的格式,我认为应该可以将适当的例程附加到可执行文件,并修补引用,使其指向可执行文件中的代码。@supercat:在普通的存档库中,单个对象文件可以单独识别,并且可以轻松地从库中提取并链接到可执行文件中。我的印象是(半知情的)共享库不以同样的方式包含单独的对象文件,所以您要么得到全部,要么什么也得不到。我敢说,可以简单地将整个共享库链接到可执行文件中,但这也可能导致大量未使用的代码被内置。我知道一些大公司更喜欢使用静态链接来处理所有事情——减少意外更改的风险。即使代码最终必须动态加载,我建议安装的应用程序在默认情况下都应该接收它们自己的大多数库的副本。如果库需要升级,可以通过让操作系统为每个程序设置“升级设置”来处理[例如,如果使用傻瓜ib 1.7的程序注意到安装了“傻瓜ib 1.8”,则可以允许用户使用1.7或1.8运行它,并将选择保存为默认设置]。这样,如果一个程序有与傻瓜相关的问题,用户可以升级它,但事情不会自动改变。我想知道为什么系统没有在其程序执行基础设施中管理这样的功能?正如有人在另一篇评论中指出的那样,链接器在20世纪80年代令人讨厌,30多年后仍然令人讨厌。有什么理由应该这样做吗?如果你实现了它,也许它会被使用。共享库的优点是,您可以更改共享库,所有使用共享库的应用程序都会自动从新版本中的错误修复中获益。静态链接的优点是,您不必担心共享库管理,并且除非重新构建应用程序,否则应用程序不会更改。如果您选择静态链接路径,那么最终会导致更高的内存使用率(每个不同的可执行文件都有自己的共享代码副本),但您知道程序不会意外更改。