Chinaunix首页 | 论坛 | 博客
  • 博客访问: 189780
  • 博文数量: 31
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 981
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-20 09:18
文章分类
文章存档

2011年(3)

2010年(8)

2009年(1)

2008年(19)

我的朋友

分类: LINUX

2011-05-16 18:44:48

automake & libtool

一直搞不清automakelibtool啥关系,以为后者是前者一部分,今天总算搞清楚它俩可完全独立使用。

libtool的官方手册说它的作用是为创建不同平台下的库文件(包括动态和静态)提供统一使用接口。我现在写的库还没考虑到不同平台移植,不过发现在处理一个静态库依赖许多其它静态库,而后者又嵌套地依赖别的库时,特别轻松。设想如下需求:

libtop.a依赖libsub1.alibsub2.a,而libsub1.alibsub2.a同时依赖libcom.a。我们希望libsub1.alibsub2.a的人不需要知道libcom.a,也就是在链接时不需要给出libcom.alibtop.a的使用者无需知道libsub1.alibsub2.a,更无需知道libcom.a

对于libsub[12].a的使用者,我们得将libcom.a中的.o文件也打包到libsub[12].a中,也就是“合并静态库”。对于此需求无论百度或google都给出先用ar x解出libcom.a中的.o,然后ar aru加入libsub[12].a中。这个过程手工做还好,问题是如何让makefile自动做?我想出一个丑陋的hack办法,在libsub[12].aMakefile.am中新加一个target

DEP_LIBS=libcom.a

sub1dist: libsub1.a

       mkdir -p .tmp.o && cd .tmp.o &&    \

       for alib in $(DEP_LIBS); do \

           rm -f *.o; ar x ../$$alib; \

        ar q ../libsub1.a *.o; done

       rm -rf .tmp.o; ranlib libsub1.a

         然后make之后还得make sub1dist,这样生成的libsub1.a在使用才无需链接libcom.a

这个办法相当丑陋,让人不爽。后者仔细地google之,发现有人说libtool可以帮助合并依赖的静态库,办法是先将libcom.a使用libtool编译成convenience library。通常编译一个libtool静态库语法是:

         lib_LTLIBRARIES = libcom.la

         libcom_la_SOURCES = xx.cpp

为了编译成convenience library,需要将第一行的lib_LTLIBRARIES改成noinst _LTLIBRARIES。然后在生成libsub1.a时加上一行

         libsub1_la_LIBADD = libcom.la

这样生成的libsub1.a(默认在.libs/下)就包含了libcom.a里的.o文件。可以从生成过程打印的信息看出libtool也是先将libcom.aar x解到特定目录下,然后添加到libsub1.a中,在添加时如果有重名的.o文件,它会重命名一个,例如加上lt1-前缀。

         好了,libsub[12].a的使用者无需知道libcom.a了。那是否同样可以将libsub[12].a也编译成convenience library,并生成libtop.a时加上:libtop_la_LIBADD = libsub1.la libsub2.la,从而libtop.a的使用者也无需知道libsub[12].a呢?一路编译下来确实没什么问题。但最后使用libtop.a时,问题来了:

         所有关于libcom.a中定义的符号,通通报出multiple definition of XXX的错误来!

显然libtop.a中包括了多份libcom.a的内容。原因应该是很明显的,解决办法是什么?Google之,一篇02年文章说这是libtool的一个bug,当时的解决办法是修改libtool脚本。但我现在是用的最新版本,在libtool中也没发现所要修改的代码。

         痛苦的寻索过程说出来总是一句话:不要用LIBADD,而是用LDFLAGS,例如生成libsub1.a

         libsub1_la_LDFLAGS=-I$(com_dir) -lcom

    同样的方法生成libsub2.alibtop.a之后,libtop.a的使用者就真的不需知道其依赖关系了。

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