假设我有三个 C 静态库,说 libColor.a ,这取决于* libRGB。* a依次取决于 libPixel.a 。库 libColor.a 据说依赖于库 libRGB.a ,因为 libColor.a 中有一些引用定义了一些符号 libRGB.a 。如何将所有上述库组合成一个独立的新 libNewColor.a ?
独立意味着新库应该定义所有符号。所以在链接时我只需要提供 -lNewColor 。新库的大小应该是最小的,但它不应该包含 libRGB.a 中的任何符号, libColor.a 等不使用它们。 我尝试使用 ar 命令中的各种选项(用于创建和更新静态库/存档)。
答案 0 :(得分:16)
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 :(得分:12)
1 /从每个库中提取所有目标文件(使用ar
)并尝试编译代码而不使用库或任何目标文件。您可能会得到一个未定义符号的绝对桶装载量。如果没有未定义的符号,请转到步骤5.
2 /抓住第一个并找出哪个目标文件满足该符号(使用nm
)。
3 /记下该目标文件,然后编译您的代码,包括新的目标文件。您将获得一个未定义符号的新列表,如果没有,则转到步骤5.
4 /转到第2步。
5 /将列表中的所有目标文件(如果有)合并到一个库中(再次使用ar
)。
砰!你有它。尝试链接代码而不使用任何对象,但与新库。
使用shell脚本可以相对轻松地自动执行此操作。
答案 2 :(得分:5)
静态库只不过是一些目标文件(.o)的存档。您可以做的是提取两个库中的所有对象(使用“ar x”),然后使用“ar”将它们链接在一个新库中。