假设我有三个C静态库,比如libColor.a,它依赖于*libRGB.*a,而后者依赖于libPixel.a.据说库libColor.a依赖于库libRGB.a,因为libColor.a中有一些对libRGB.a中定义的符号的引用.如何将所有上述库组合到一个独立的新libNewColor.a中?
独立意味着新库应该定义所有符号.所以在链接时我只需要给出-lNewColor.新库的大小应该是最小的,即它不应该包含libRGB.a中的任何符号,libColor.a等不使用它.我在ar命令中使用了各种选项来试运气(用于创建和更新静态库/档案) ).
GNU归档程序的一个小功能是归档脚本,它是一个简单但功能强大的接口,它可以完全按照您的意愿执行,例如,如果以下脚本称为script.ar:
CREATE libNewColor.a ADDLIB libColor.a ADDLIB libRGB.a ADDLIB libPixel.a SAVE END
然后你可以调用ar如下:
ar -M < script.ar
你会得到包含来自libColor.a libRGB.a和libPixel.a的所有.o文件的libNewColor.a.
此外,您还可以使用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
1 /从每个库中提取所有目标文件(使用ar
)并尝试编译代码而不使用库或任何目标文件.您可能会得到一个未定义符号的绝对桶装载量.如果没有未定义的符号,请转到步骤5.
2 /抓住第一个并找出哪个目标文件满足该符号(使用nm
).
3 /记下该目标文件,然后编译您的代码,包括新的目标文件.您将获得一个未定义符号的新列表,如果没有,请转到步骤5.
4 /转到第2步.
5 /将列表中的所有目标文件(如果有)合并到一个库中(同样ar
).
砰! 你有它.尝试链接代码而不使用任何对象,但使用新库.
使用shell脚本可以相对轻松地自动执行整个操作.
静态库只不过是一些目标文件(.o)的存档.您可以做的是提取两个库中的所有对象(使用"ar x"),然后使用"ar"将它们链接在一个新库中.