Combining static libraries

核能气质少年 提交于 2019-11-28 17:39:11

1/ Extract ALL of the object files from each library (using ar) and try to compile your code without the libraries or any of the object files. You'll probably get an absolute bucket-load of undefined symbols. If you get no undefined symbols, go to step 5.

2/ Grab the first one and find out which object file satisfies that symbol (using nm).

3/ Write down that object file then compile your code, including the new object file. You'll get a new list of undefined symbols or, if there's none, go to step 5.

4/ Go to step 2.

5/ Combine all the object files in your list (if any) into a single library (again with ar).

Bang! There you have it. Try to link your code without any of the objects but with the new library.

This whole thing could be relatively easily automated with a shell script.

A little used feature of the GNU archiver is the archive script, it is a simple but powerful interface, and it can do exactly what you want, for example if the following script is called script.ar:

CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
SAVE
END

Then you could invoke ar as follows:

ar -M < script.ar

and you would get libNewColor.a that contains all of the .o files from libColor.a libRGB.a and libPixel.a.

Additionally you can also add regular .o files as well with the ADDMOD command:

CREATE libNewColor.a
ADDLIB libColor.a
ADDLIB libRGB.a
ADDLIB libPixel.a
ADDMOD someRandomCompiledFile.o
SAVE
END

Furthermore it is super easy to generate these scripts in Makefiles, so I typically create a somewhat generic makefile rule for creating archives which actually generates the script and invokes ar on the script. Something like this:

$(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)

Though now that I look at it I guess it doesn't work if $(OBJECTS) is empty (i.e. if you just want to combine archives without adding extra object files) but I will leave it as an exercise for the reader to fix that issue if needed... :D

Here are the docs for this feature:

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

A static library is not much more than an archive of some object files (.o). What you can do is extract all the objects in the two libraries (using "ar x") and then use "ar" to link them together in a new library.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!