- First, look through all of the
- Compile each of the
.c files to
.o file. You can either do this by hand
or you can use
make(1)’s built-in rule.
$ make CC=clang a.o b.o foo.o bar.o
nm(1) to print out the symbols for each of the
This shows you the symbol name and, if it’s defined, the value. Undefined symbols show up as
U. Defined global function symbols show up as
T (for text). There are other possibilities listed in the man page for
Create an archive
ar(1). Either check the man page or look at the slides.
nm(1) works with archives too. Try running it on
libex.a. It should list the symbols for both
You might notice that one symbol in
a.o and one in
b.o have value 0. That’s because the archive just contains the two object files (and a symbol table assuming you used the
s option to
ar(1) or ran
$ ranlib libex.a). Each object file is independent and the 0 is an offset into the
.text segment of the corresponding file.
You can use
$ readelf -SW to print out the list of sections in object files (including those in archives) (or any other sort of ELF file).
You can also get more information about the symbols by using
$ readelf -s.
- Create an archive
- Now run
$ clang -o prog1 foo.o libbar.a libex.a
Look at the included symbol using
--defined-only options that together are close to what you get from the
grep, but they also include other data).
Can you tell which object files got included? If not, try running
$ clang -o prog2 foo.o libex.a libbar.a
and look at its defined symbols. Can you tell which object files got included? Are they they same ones from step 7?
$ ./prog2 and compare the output with that of
Makefile with targets
libbar.a that build
prog2 as specified above.
.PHONY targets and that all of the object files depend on
Don’t forget to
$(RM) $@ before building an archive.