14

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

独立意味着新库应该定义所有符号。因此,在链接时,我只需要提供-lNewColor。新库的大小应该是最小的,即它不应该包含libColor.a等未使用的 libRGB.a 中的任何符号。我在ar命令中使用了各种选项(用于创建和更新静态库/档案) )。

4

3 回答 3

17

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

此外,在 Makefiles 中生成这些脚本非常容易,因此我通常创建一个通用的 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

于 2013-09-03T17:36:03.403 回答
12

1/ 从每个库中提取所有目标文件(使用ar)并尝试在没有库或任何目标文件的情况下编译您的代码。您可能会得到大量未定义的符号。如果您没有得到未定义的符号,请转到第 5 步。

2/ 获取第一个并找出哪个目标文件满足该符号(使用nm)。

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

4/ 转到第 2 步。

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

砰! 你有它。尝试在没有任何对象但使用新库的情况下链接您的代码。

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

于 2009-03-20T11:47:02.027 回答
5

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

于 2009-03-20T11:41:59.167 回答