Chinaunix首页 | 论坛 | 博客
  • 博客访问: 391733
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-10 08:38
文章分类
文章存档

2016年(32)

2015年(48)

我的朋友

分类: LINUX

2015-11-10 09:30:55

 

gcc链接静态库时对待.a文件和.o文件的不同

分类: C/C++ HomeworldSDL 571人阅读 评论(0)  举报

  很多人都知道,gcc在链接静态库时是从前往后找符号。因此如果一份文件foo引用了静态库bar.a,那么在链接命令中,bar.a必须放在foo的后面,也就是像gcc ... foo ... bar.a这样;否则链接时会报找不到定义的错误(即undefined reference to ...)。

 

  .a文件其实没什么特别的地方,它不过是将多个.o文件打包成一份文件。如果我们在链接命令中,直接用.o文件替换.a文件,那也需要遵循gcc的这种链接顺序吗?可以用gcc .. bar.o ... foo这样的链接命令吗?可以做个简单的试验。

 

  假设我们有两份源代码文件。一份是foo.c,定义了一个foo函数。

  1. void foo()  
  2. {  
  3. }  

  另一份是main.c,里面引用了foo函数:

  1. void foo();  
  2.   
  3. int main()  
  4. {  
  5.     foo();  
  6. }  

  我们将foo.c编译成foo.o,然后打包成foo.a:

$ gcc -c foo.c

$ ar rcs foo.a foo.o

  如果我们让main.c链接foo.a,并且将foo.a放在main.c的前面,那就会如期望的那样出现链接错误:

$ gcc -o test foo.a main.c
C:\Users\ADMINI~1\AppData\Local\Temp\ccan3qBI.o:main.c:(.text+0xc): undefined reference to `foo'
collect2.exe: error: ld returned 1 exit status

  但如果将foo.a换成foo.o,链接就不会报错了:

$ gcc -o test foo.o main.c

  所以结论是:.o文件在链接中并不遵循.a文件那样的链接顺序,看来链接器找符号时,一定会搜索命令中的.o文件。

 

  StackOverflow里的这篇帖子也提到了类似的事:

 

  试验用的gcc版本:

$ gcc -v
Using built-in specs.
COLLECT_GCC=e:\Zhixiang\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=e:/zhixiang/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)

阅读(3495) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~