当前位置:  开发笔记 > 运维 > 正文

结合静态库

如何解决《结合静态库》经验,为你挑选了3个好方法。

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

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



1> Chris Desjar..:

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



2> paxdiablo..:

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

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

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

4 /转到第2步.

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

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

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


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

3> Mark Probst..:

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

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有