Makefile Template for a Shared Library in C (with Explanations)

tl;dr: Save the following file as Makefile and change the source files to the ones that you intend.

# Makefile template for a shared library in C
# https://www.topbug.net/blog/2019/10/28/makefile-template-for-a-shared-library-in-c-with-explanations/

CC = gcc  # C compiler
CFLAGS = -fPIC -Wall -Wextra -O2 -g  # C flags
LDFLAGS = -shared   # linking flags
RM = rm -f   # rm command
TARGET_LIB = libtarget.so  # target lib

SRCS = main.c src1.c src2.c  # source files
OBJS = $(SRCS:.c=.o)

.PHONY: all
all: ${TARGET_LIB}

$(TARGET_LIB): $(OBJS)
	$(CC) ${LDFLAGS} -o $@ $^

$(SRCS:.c=.d):%.d:%.c
	$(CC) $(CFLAGS) -MM $< >$@

include $(SRCS:.c=.d)

.PHONY: clean
clean:
	-${RM} ${TARGET_LIB} ${OBJS} $(SRCS:.c=.d)

The above code snippet is also available on GitHub gist.

Explanation

Basic process: For every C source file (example.c), the C compiler, with the -MM switch, creates a rule file (example.d). The rule file describes the dependencies (e.g., header files) of the object file (example.o) corresponding the C source file. The C compiler then compiles each C source file to an object file. The linker links all object files into the shared library.

  1. Lines 4–8: The compiler command, compiler flags, linker flags, deletion command, and name of the target library, respectively.
  2. Line 10: The list of source files.
  3. Line 11: Object files, inferred from the list of source files by replacing the .c suffix with .o.
  4. Lines 13–14: The all target depends on the target library target. In other words, building the all target, which is the default when running make, will have the target library built.
  5. Line 16: The target library depends on the presence of all object files.
  6. Line 17: Build the target library ($@) by applying the specified compiler command ($(CC)) with the specified linker flags ($(LDFLAGS)) to all object files ($^).
  7. Line 19: There is a rule file (*.d) for every C source file. Its file name is determined by replacing the .c suffix with .d.
  8. Line 20: Create each rule file ($@) by applying to its corresponding C source file ($<) the specified compiler command ($(CC)) with the specified compiler flags ($(CFLAGS)) and the -MM flag.
  9. Line 22: Include the rule files as part of the Makefile.
  10. Lines 24–26: The clean target, which deletes all generated files (${TARGET_LIB}, ${OBJS}, $(SRCS:.c=.d)) using the deletion command (${RM}). This can be invoked by make clean.

Leave a Reply

Your email address will not be published.