Saturday, November 26, 2011

Making Both Archives and Shared Objects

It's not uncommon to want to support both static linking, with a library archive, and dynamic linking, with a shared object. I almost always choose the latter, but it is not uncommon for small embedded applications to be statically linked. This can actually reduce the memory footprint of the entire system when not many object files are shared. Or sometimes it's necessary for esoteric reasons of shared memory or what not. Google Test, my favorite C++ unit testing framework, actually recommends static linking against its libgtest.a archive.

When supporting both static and dynamic linking, I always generate the library archive, for example libhayloft.a, then automate the generation of the shared object, libhayloft.so. Here's a Makefile snippet that does that. It simply unloads the entire archive into a temporary directory, creates a shared object, then removes the directory. (I've resolved all the make variable names to make this a little more comprehensible.)

libhayloft.so: libhayloft.a
HERE="`pwd`"; \
THERE="`mktemp -d /tmp/hayloft.XXXXXXXXXX`"; \
( cd $$THERE; ar xv $$HERE/libhayloft.a ); \
gcc -shared -Wl,-soname,libhayloft.so -o \
libhayloft.so $$THERE/*.o; \
rm -rf $$THERE

No comments: