结合静态库

AIB*_*AIB 13 c linux static-libraries unix-ar static-linking

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

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

Chr*_*ins 17

GNU归档程序的一个小功能是归档脚本,它是一个简单但功能强大的接口,它可以完全按照您的意愿执行,例如,如果以下脚本称为script.ar:

CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
SAVE
END
Run Code Online (Sandbox Code Playgroud)

然后你可以调用ar如下:

ar -M < script.ar
Run Code Online (Sandbox Code Playgroud)

你会得到包含来自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
Run Code Online (Sandbox Code Playgroud)

此外,在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)
Run Code Online (Sandbox Code Playgroud)

虽然我现在看着它,但我认为如果$(OBJECTS)为空(即如果你只是想在没有添加额外目标文件的情况下组合档案)它就不起作用但是我会留下它作为练习让读者修复它如果需要问题......:D

以下是此功能的文档:

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


pax*_*blo 12

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

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

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

4 /转到第2步.

5 /将列表中的所有目标文件(如果有)合并到一个库中(同样ar).

砰! 你有它.尝试链接代码而不使用任何对象,但使用新库.

使用shell脚本可以相对轻松地自动执行整个操作.

  • 不必要的复杂,您可以将所有.o文件提取到一个大的.a文件中,因为当它最终链接到可执行文件时,链接器将丢弃任何未使用的文件 (2认同)
  • @MarkR,@ AIB希望*library*的大小最小,而不是可执行文件的大小. (2认同)

Mar*_*bst 5

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