Linux动态库与静态库制作及使用详解

发表于:2016-7-20 09:48

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:IBM/陈鲁    来源:51Testing软件测试网采编

  Linux 下静态库(archive)的制作方式:
  涉及命令:ar
  ar 简介:处理创建、修改、提取静态库的操作
  涉及选项:
  t – 显示静态库的内容
  r[ab][f][u] – 更新或增加新文件到静态库中
  [s] – 创建文档索引
  ar -M [<mri-script] – 使用 ar 脚本处理
  其他详细说明请参阅 man 说明。
  示例情景:
  假设现有如 图 7所示两个库文件
  
图 7. 示例静态库文件
  示例静态库文件
  从 图 7中可以得知,CdtLog.a 只包含 CdtLog.o 一个对象文件 , 而 xml.a 包含 TXmlParser.o 和 xmlparser.o 两个对象文件
  现将 CdtLog.o 提取出来,然后通过 图 8方式创建一个新的静态库 demo.a,可以看出,demo.a 包含的是 CdtLog.o 以及 xml.a,
  而不是我们所预期的 CdtLog.o,TXmlParser.o 和 xmlparser.o。这正是区别于 Windows 下静态库的制作。
  
图 8. 示例静态库制作方式 1
  示例静态库制作方式 1
  这样的 demo.a 当被链接入某个工程时,所有在 TXmlParser.o 和 xmlparser.o 定义的符号都不会被发现,从而会导致链接错误,
  提示无法找到对应的符号。显然,通过图 8 方式创建 Linux 静态库是不正确的。
  正确的方式有两种:
  将所有静态库中包含的对象文件提取出来然后重新打包成新的静态库文件。
  用一种更加灵活的方式创建新的静态库文件:ar 脚本。
  显然,方式 1 是比较麻烦的,因为涉及到太多的文件处理,可能还要通过不断创建临时目录用于保存中间文件。
  推荐使用如 清单 2 createlib.sh所示的 ar 脚本方式进行创建:
  清单 2 createlib.sh
  rm demo.a
  rm ar.mac
  echo CREATE demo.a > ar.mac
  echo SAVE >> ar.mac
  echo END >> ar.mac
  ar -M < ar.mac
  ar -q demo.a CdtLog.o
  echo OPEN demo.a > ar.mac
  echo ADDLIB xml.a >> ar.mac
  echo SAVE >> ar.mac
  echo END >> ar.mac
  ar -M < ar.mac
  rm ar.mac
  如果想在 Linux makefile 中使用 ar 脚本方式进行静态库的创建,可以编写如 清单 3 BUILD_LIBRARY所示的代码:
  清单 3 BUILD_LIBRARY
define BUILD_LIBRARY
$(if $(wildcard $@),@$(RM) $@)
$(if $(wildcard ar.mac),@$(RM) ar.mac)
$(if $(filter %.a, $^),
@ echo CREATE $@ > ar.mac
@ echo SAVE >> ar.mac
@ echo echo END >> ar.mac
@$(AR) -M < ar.mac
)
$(if $(filter %.o,$^),@$(AR) -q $@ $(filter %.o, $^))
$(if $(filter %.a, $^),
@ echo OPEN $@ > ar.mac
$(foreach LIB, $(filter %.a, $^),
@ echo ADDLIB $(LIB) >> ar.mac
)
@ echo SAVE >> ar.mac
@ echo END >> ar.mac
@$(AR) -M < ar.mac
@$(RM) ar.mac
)
endef
$(TargetDir)/$(TargetFileName):$(OBJS)
$(BUILD_LIBRARY)
  通过 图 9,我们可以看到,用这种方式产生的 demo.a 才是我们想要的结果。
 
 图 9. 巧妙创建的静态库文件结果
  巧妙创建的静态库文件结果
  Linux 静态库链接顺序问题及解决方法:
  正如 GCC 手册中提到的那样:
  It makes a difference where in the command you write this option; the linker
  searches and processes libraries and object files in the order they are specified.
  Thus, ‘ foo.o -lz bar.o ’ searches library ‘ z ’ after file ‘ foo.o ’ but before
  ‘ bar.o ’ . If ‘ bar.o ’ refers to functions in ‘ z ’ , those functions may not be loaded.
  为了解决这种库链接顺序问题,我们需要增加一些链接选项 :
  $(CXX) $(LINKFLAGS) $(OBJS) -Xlinker “-(” $(LIBS) -Xlinker “-)” -o $@
  通过将所有需要被链接的静态库放入 -Xlinker “-(” 与 -Xlinker “-)” 之间,可以是 g++ 链接过程中, 自动循环链接所有静态库,从而解决了原本的链接顺序问题。
  涉及链接选项:-Xlinker
  -Xlinker option
  Pass option as an option to the linker. You can use this to supply system-specific
  linker options which GCC does not know how to recognize.
  小结
  本文介绍了 Linux 下三种标准库链接的方式及各自利弊,同时还介绍了 Linux 下静态库的制作及使用方法,相信能够给 大多数需要部署 Linux 应用程序和编写 Linux Makefile 的工程师提供有用的帮助。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号