hEShaN
hEShaN

Reputation: 581

Including all the library statically instead of parts of the library upon linking/compilation

If I am to statically link a certain library to my application, As far as I know, the linker could optimize in a way to put only the parts that had been used from the library while generating the final executable. Is there a way to turn this off upon compilation, maybe using a compiler flag or any other particular method, if I want to generate an executable containing all the parts of the library instead of the portions that I had actually used?

Upvotes: 1

Views: 76

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754820

If you have to work with linkers other than the GNU linker, you may find it best to create one relinkable object file from the component object files in the library, and then build that (large) object file into a replacement library. It becomes an all-or-nothing proposition: if you need any of the symbols in the library, you get everything.

oldlib=/some/where/libwhatnot.a
newlib=libwhatnot1.a
bigobj=libwhatnot.o
tmpdir=libwhatnot.relink

mkdir "$tmpdir"
cd "$tmpdir"
ar x "$oldlib"
ld -r -o "../$bigobj" *
rm -f *
cd ..
rmdir "$tmpdir"
ar r "$newlib" "$bigobj"
rm -f "$bigobj"

You might need to review how to preserve debug information (likely a -g option to ld).

The script should deal with problems such as the directory already existing and failing to cd into it — the rm -f * could do grievous mischief if that is executed in a directory other than the one that was just created. But the basic idea — extract, build a single object file, archive that — means that the library is all or nothing, as desired.

You also have to arrange to replace the original static archive with your replacement, either by changing the name of the library used in linking, or by placing your replacement in a directory ahead of the original in the linker command line, or by renaming the original, moving the replacement into its place, and continuing as before. I recommend keeping the original until you're confident you won't need it again.

The -r option has existed on linkers since (at least) 7th Edition Unix in the late 70s; it is usually available and usually unused.

Upvotes: 0

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136495

There is a GNU linker option --whole-archive which does exactly that:

For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the link, rather than searching the archive for the required object files. This is normally used to turn an archive file into a shared library, forcing every object to be included in the resulting shared library.

See man ld for more details.

When you link with gcc or clang pass this option to linker as -Wl,--whole-archive.

Upvotes: 6

Related Questions