Building Libraries

An almost identical makefile can be used to build a library instead of an executable. We need only replace the link command with a command that build a library archive. Also, none of the source files used to build a library should contain a main program.

LIB     = libmatrix.a
OBJS    = read.o write.o invert.o

CC      ?= cc
CFLAGS  ?= -Wall -O -g
AR      ?= ar           # Like tar, but for static libraries
RANLIB  ?= ranlib       # Generate an index for searching the library

# Let user or package manager control installation path
DESTDIR ?= ./stage
PREFIX  ?= /usr/local

# Build a static library
${LIB}: ${OBJS}
        ${AR} r ${LIB} ${OBJS}
        ${RANLIB} ${LIB}

read.o: read.c matlib.h
        ${CC} -c ${CFLAGS} read.c

write.o: write.c matlib.h
        ${CC} -c ${CFLAGS} write.c

invert.o: invert.c matlib.h
        ${CC} -c ${CFLAGS} invert.c

        ${MKDIR} -p ${DESTDIR}${PREFIX}/lib
        ${INSTALL} -c -m 0755 ${LIB} ${DESTDIR}${PREFIX}/lib

        ${RM} -f ${LIB} *.o

This library can then be used by any program by linking with -lmatrix:

BIN     = myprog
OBJS    = myprog.o
LIBS    = libmatrix.a

CC      ?= cc
CFLAGS  ?= -Wall -O -g
LD      ?= ${CC}
LDFLAGS ?= -L${PREFIX}/lib -lmatrix -lm

DESTDIR ?= ./stage
PREFIX  ?= /usr/local

${BIN}: ${OBJS} ${LIBS}
        ${LD} -o ${BIN} ${OBJS} ${LDFLAGS}

myprog.o: myprog.c Makefile
        ${CC} -c ${CFLAGS} myprog.f90

The example above uses a static library. Static libraries in Unix have a ".a" extension. When a program is linked to a static library, the object code in the library is copied to the executable file.

Most projects build shared libraries, where only a reference to the library file is added to the executable. This saves disk space and allows multiple processes to use the same library code after it is loaded separately into memory. Building shared libraries properly is a bit more complex, since they need to be versioned in order to prevent compatibility problems. If a shared library is upgraded without rebuilding the programs that use it, those programs may not function properly. Shared libraries in most Unix systems have a filename extension of ".so.<version>", where "<version>" starts with "1" and is incremented with major upgrades. We will leave the creation of shared libraries for a more advanced course on software development.



Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. Write a makefile that creates a static library called "functions.a" from the source file "functions.c".