When making a library on unix, is anything but “ar rcs” necessary?
Question
I have a number of source files I want to agglomerate into a .a
file. I make the library with the command
ar rcs libcathat.a thing1.o thing2.o fish.o
I then attempt to link to this library with the same compiler I used to make the .o
files (g++):
g++ -L/path/to/cathat -lcathat seuss.o -o seuss
But this produces errors when I try to use functions defined in thing1.cpp (and in theory represented in thing.o) of the form:
/path/seuss.cpp:46: undefined reference to `redFishBlueFish(int, char**)'
Is there something else I need to do to a .a
file to make it possible to link to it?
Solution
Try moving the linker statements to the end:
g++ seuss.o -o seuss -L/path/to/cathat -lcathat
If that doesn't work, make sure those symbols are actually in the archive:
nm libcathat.a
OTHER TIPS
Usually, you don't need to do anything else on most modern versions of Unix.
On some, mainly older, versions of Unix, it was necessary to use ranlib
on a library to add a lookup table that allowed the linker to find symbols quickly. Almost all modern versions of ar
do this automatically. Needing ranlib
is something of a hangover from the 'bad old days' of 7th Edition UNIX™.
For some reason which I can't now locate, I was building archives on Mac OS X 10.7.4 with ranlib
too. I must have had a reason for doing so, but that reason seems to be irrelevant now — archive libraries seem work OK without ranlib
on Mac OS X 10.7.4, at least for a single architecture. I did find a change I made in July 2004 that put ranlib
back into a make
program, but the check-in notes don't say why I made the change. I've updated the rule definition file so it no longer uses ranlib
.