# # somewhat elaborate makefile illustrating various ways of putting # code into a library and using it # # more info in comments preceding targets for executables # EXECUTABLES=\ main \ main-with-static \ main-with-shared main-with-shared-rpath \ main-dynamic main-dynamic-rpath CC = gcc CFLAGS = -Wall -std=c99 -pedantic OBJ_S=foo.o bar.o OBJ_L=foo-pic.o bar-pic.o LIB_S=test LIB_S_FILE=lib$(LIB_S).a LIB_L=test_s LIB_L_NAME=lib$(LIB_L).so LIB_L_SONAME=$(LIB_L_NAME).1 LIB_L_FILE=$(LIB_L_SONAME).0 all: $(EXECUTABLES) clean: rm -v *.o $(LIB_S_FILE) $(LIB_L_NAME)* $(EXECUTABLES) # # rules for creating libraries # # generate executable by compiling separately and linking # (uses makefile implicit rules) main: main.o foo.o bar.o # generate executable using static library main-with-static: main.o $(LIB_S_FILE) $(CC) -o $@ $< -L. -l$(LIB_S) # generate executable using shared library # must set LD_LIBRARY_PATH at runtime main-with-shared: main.o $(LIB_L_NAME) $(CC) -o $@ $< -L. -l$(LIB_L) # generate executable using shared library, in a way that includes # its location in executable main-with-shared-rpath: main.o $(LIB_L_NAME) $(CC) -Wl,-rpath=. -o $@ $< -L. -l$(LIB_L) # generate executable for example using runtime loading # must set LD_LIBRARY_PATH at runtime main-dynamic: main-dynamic.o $(LIB_L_NAME) gcc -rdynamic -o $@ $< -ldl # generate executable for example using runtime loading, in a way # that includes its location in executable main-dynamic-rpath: main-dynamic.o $(LIB_L_NAME) gcc -Wl,-rpath=. -rdynamic -o $@ $< -ldl # # rules for generating libraries # (also takes advantage of implicit rules for compiling C) %-pic.o : %.c $(CC) $(CFLAGS) -fPIC -c $< -o $@ $(LIB_S_FILE): $(OBJ_S) ar -cvq $@ $^ $(LIB_L_FILE): $(OBJ_L) $(CC) -shared -Wl,-soname=$(LIB_L_SONAME) -o $@ $^ $(LIB_L_SONAME): $(LIB_L_FILE) ln -s $< $@ $(LIB_L_NAME): $(LIB_L_SONAME) ln -s $< $@