结合静态库

假设我有三个C静态库libColor.a依赖于* libRGB。* a依次取决于libPixel.a 。 据说库libColor.a依赖库libRGB.a,因为在libColor.a中有一些对libRGB.a中定义的符号的引用 。 我如何将以上所有库合并为独立的新libNewColor.a

独立意味着新图书馆应该定义所有符号。 所以,当连接我只需要给-lNewColor 。 新库的大小应该是最小的,即它不应该在libRGB.a中包含libColor.a中没有使用的任何符号等等。我尝试使用ar命令中的各种选项(用于创build和更新静态库/档案)。

1 /从每个库中提取所有目标文件(使用ar ),并尝试编译没有库或任何目标文件的代码。 你可能会得到一个绝对桶装载未定义的符号。 如果没有未定义的符号,请转到步骤5。

2 /抓住第一个,找出哪个目标文件满足该符号(使用nm )。

3 /记下该目标文件,然后编译你的代码,包括新的目标文件。 您将得到一个新的未定义符号列表,如果没有,请转到步骤5。

4 /转到步骤2。

5 /将列表中的所有目标文件(如果有的话)合并到一个单独的库中(再次使用ar )。

砰! 你有它。 尝试链接你的代码,没有任何对象,但新的库。

这整个事情可以用一个shell脚本相对容易地自动化。

GNU归档器的一个小功能就是归档脚本,它是一个简单但功能强大的界面,它可以完全按照你的意思去做,例如,如果下面的脚本叫做script.ar:

 CREATE libNewColor.a ADDLIB libColor.a ADDLIB libRGB.a ADDLIB libPixel.a SAVE END 

那么你可以如下调用ar:

 ar -M < script.ar 

你会得到libNewColor.a,其中包含libColor.a libRGB.a和libPixel.a中的所有.o文件。

另外,您还可以使用ADDMOD命令添加常规的.o文件:

 CREATE libNewColor.a ADDLIB libColor.a ADDLIB libRGB.a ADDLIB libPixel.a ADDMOD someRandomCompiledFile.o SAVE END 

此外,在Makefile中生成这些脚本是非常容易的,所以我通常会创建一个通用的makefile规则来创建存档,这些规则实际上会生成脚本并在脚本上调用ar。 像这样的东西:

 $(OUTARC): $(OBJECTS) $(SILENT)echo "CREATE $@" > $(ODIR)/$(ARSCRIPT) $(SILENT)for a in $(ARCHIVES); do (echo "ADDLIB $$a" >> $(ODIR)/$(ARSCRIPT)); done $(SILENT)echo "ADDMOD $(OBJECTS)" >> $(ODIR)/$(ARSCRIPT) $(SILENT)echo "SAVE" >> $(ODIR)/$(ARSCRIPT) $(SILENT)echo "END" >> $(ODIR)/$(ARSCRIPT) $(SILENT)$(AR) -M < $(ODIR)/$(ARSCRIPT) 

虽然现在我看它,但是如果$(OBJECTS)是空的(即,如果你只是想合并档案而不添加额外的目标文件),我想这是行不通的,但是我将把它作为练习让读者解决问题,如果需要…:D

这里是这个功能的文档:

https://sourceware.org/binutils/docs/binutils/ar-scripts.html#ar-scripts

静态库不过是一些目标文件(.o)的存档。 你可以做的是提取两个库中的所有对象(使用“ar x”),然后使用“ar”将它们链接到一个新库中。