The Super-Makefile
After toying with build systems off and on for months, I concluded today that make is about as advanced as I ever need to get for my projects. In the past, I recall using this gem of a Makefile. But my needs in a build process have grown a little. First of all, I now prefer C to C++, so that had to be changed. Then I had to go about adding static and shared library abilities to it. Then I added "clean" and "distclean" build targets, and include and library search paths got introduced somewhere along the way.
After good half hour of modification, I had the following Makefile, posted here mainly so I can find it easily from any computer. By modifying the first six variables defined in the Makefile, it can be adapted to almost any C project of reasonable complexity. It has no support for cross-platform library identification, out-of-source builds, or debug and release build toggles. But on the other hand, I can never get those things to work right any way.
Toggling between static library, shared library, and executable build modes is performed by setting the LIBRARY variable to "static", "shared", or anything that isn't those two values.
SOURCES=bar.c baz.c
LIBRARY=nope
INCPATHS=../some_other_project/
LIBPATHS=../yet_another_project/
LDFLAGS=-ldosomething
CFLAGS=-c -Wall
CC=gcc
# ------------ MAGIC BEGINS HERE -------------
# Automatic generation of some important lists
OBJECTS=$(SOURCES:.c=.o)
INCFLAGS=$(foreach TMP,$(INCPATHS),-I$(TMP))
LIBFLAGS=$(foreach TMP,$(LIBPATHS),-L$(TMP))
# Set up the output file names for the different output types
ifeq "$(LIBRARY)" "shared"
BINARY=lib$(PROJECT).so
LDFLAGS += -shared
else ifeq "$(LIBRARY)" "static"
BINARY=lib$(PROJECT).a
else
BINARY=$(PROJECT)
endif
all: $(SOURCES) $(BINARY)
$(BINARY): $(OBJECTS)
# Link the object files, or archive into a static library
ifeq "$(LIBRARY)" "static"
ar rcs $(BINARY) $(OBJECTS)
else
$(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@
endif
.c.o:
$(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@
distclean: clean
rm -f $(BINARY)
clean:
rm -f $(OBJECTS)












