读书频道 > 系统 > linux > 深度探索Linux操作系统系统构建和原理解析
3. 链接静态库
2013-09-28 13:34:19     我来说两句 
收藏    我要投稿   
全书一共8章:第1章介绍了如何准备工作环境。在第2章中构建了编译工具链,这是后面构建操作系统各个组件的基础。在这一章中,不仅详细讲解了工具链的构建过程,而且还通过对编译链接过程的探讨,深入讨论了工具链  立即去当当网订购

如果在链接过程中有静态库,那么链接是如何进行的呢?静态库其实就是多个目标文件的打包,因此,与合并多个目标文件并无本质差别。但是有一点需要特别说明,在链接静态库时,并不是将整个静态库中包含的目标文件全部复制一份到最终的可执行文件中,而是仅仅链接库中使用的目标文件。如图2-6所示,在对可执行文件链接时,只使用了静态库中的“Object File 2”,所以链接器仅将“Object File 2”复制了一份到可执行文件中。

 

我们使用如下命令先将foo1.c和foo2.c编译为静态库libfoo.a。然后将静态库libfoo.a链接到可执行程序hello。

root@baisheng:~/demo# gcc -c foo1.c foo2.c
root@baisheng:~/demo# ar -r libfoo.a foo1.o foo2.o
root@baisheng:~/demo# gcc -o hello hello.c libfoo.a

我们来看一下静态库libfoo.a的符号表:
root@baisheng:~/demo# readelf -s libfoo.a
File: libfoo.a(foo1.o)
Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS foo1.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 00000000     4 OBJECT  GLOBAL DEFAULT    3 foo1
     9: 00000000    19 FUNC    GLOBAL DEFAULT    1 foo1_func
File: libfoo.a(foo2.o)
Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS foo2.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 00000000     4 OBJECT  GLOBAL DEFAULT    3 foo2
     9: 00000000    19 FUNC    GLOBAL DEFAULT    1 foo2_func

我们看到,与代码中完全吻合,libfoo.a的符号表中包含4个全局符号,分别是变量foo1和foo2、函数foo1_func和foo2_func。如果最终创建的可执行文件hello包含了整个libfoo.a的副本,那么hello的符号表中也应该包含这4个全局符号。但是,实际上hello.c中仅使用了目标文件foo2.o中的函数foo2_func,所以按照我们前面的理论,hello中应该仅仅包含foo2.o的副本,而不必包含没有使用的foo1.o。我们查看一下hello的符号表:
root@baisheng:~/demo# readelf -s hello | grep foo
    37: 00000000     0 FILE    LOCAL  DEFAULT  ABS foo2.c
    52: 0804a01c     4 OBJECT  GLOBAL DEFAULT   24 foo2
    65: 080483f0    19 FUNC    GLOBAL DEFAULT   13 foo2_func

以上hello的符号表仅包含了foo2和foo2_fiunc,显然,可执行文件hello中确实没有包含目标文件foo1.o。至于链接静态库中的目标文件的方法,与我们前面讨论的目标文件的合并完全相同。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:2. 符号重定位
下一篇:4. 链接动态库
相关文章
图文推荐
3.3.6 GNOME的软件管
3.3.5 GNOME的文件管
3.3.4 GNOME的窗口管
3.3.3 收藏夹和快捷
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站