If we have our code split up into a bunch of different files, compiled separately, we can link them into a single executable as discussed in a previous post (here), which uses the
make
tool.It also useful to define libraries that may contain a number of different modules which are already pre-compiled and linked. A primary distinction is between static libraries, which are copied into the target application, and dynamic libraries which are not.
We'll start with the static version in this post. The example is adapted from Dalrymple & Hillegass (Advanced Mac OS X Programming) which is still a valuable resource even though it's a bit dated. It looks like there may be a new edition later this year. Here is a simple file
add1.c
with a nice function:A similar function f2 is defined in
add2.c
We do the following:(-g adds debugging symbols, -Wall shows all warnings). The result is familiar: two object files
add1.o
and add2.o
. These functions are used by your program, defined in
useadd.c
:Rather than referring to a header file for the definitions of f1 and f2, we make a declaration of
extern
. Now the book says to do:with the flags to ar:
and flags passed through gcc to ld are a search path and file description as described here.
It works:
The ar tool is Unix archive utility, which has for the most part been superseded by tar. Here is what the output file looks like for a run of
ar
on two simple text files. I think you can guess what they contain:Now, Apple suggests that you use
libtool
:[UPDATE: The docs (here) say that everything must be compiled as well as linked with
-static
for this to work]Also, for this example, you don't need the search paths, but could just do:
It's important to list the library after
useadd.c
, otherwise the linker will discard the library symbols as unneeded. We can explore the symbols defined in our library (or any object file for that matter):The function names are preceded by an underscore. The U means that printf is as yet undefined, and the T stands for (Text)---not sure what that refers to.
Here we see that in
useadd.o
the functions f1 and f2 are as yet undefined. Another very interesting thing is to set the environment variable:We can watch as the libraries are loaded. There are a bunch of other things here.