Revenge of the Super-Makefile

May 5, 2009 at 8:35 pm | In coding | Leave a Comment
Tags: , ,

So today I found some more things that the old Makefile was lacking. An “install” target, a “.PHONY” target to prevent breakage down the line, and the ability to recursively build subprojects. A few hours later, I have this:

PROJECT=foo
VERSION=0.0.1
SOURCES=bar.c baz.c
SUBPROJECTS=xyzzy fnord
LIBRARY=-lm
INCPATHS=xyzzy fnord
LIBPATHS=fnord
PREFIX=/usr/local
LDFLAGS=
CFLAGS=-c -Wall -g
CC=gcc

# ------------ MAGIC BEGINS HERE -------------

# We want subprojects to use these variables
export CC
export PREFIX

# 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
else ifeq "$(LIBRARY)" "static"
    BINARY=lib$(PROJECT).a
else
    BINARY=$(PROJECT)
endif

all: $(SOURCES) $(SUBPROJECTS) $(BINARY)

$(BINARY): $(OBJECTS)
ifdef SOURCES
    # Assemble the object files into the right type of binary
    ifeq "$(LIBRARY)" "static"
        ar rcs $(BINARY) $(OBJECTS)
    else ifeq "$(LIBRARY)" "shared"
        $(CC) -shared $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@
    else
        $(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@
    endif
endif

$(SUBPROJECTS):
        make -e -C $@

.c.o:
        $(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@ 

install:
        @ for i in $(SUBPROJECTS); do make -e -C $${i} install; done
ifdef SOURCES
    ifeq "$(LIBRARY)" "static"
        install $(BINARY) $(PREFIX)/lib
    else ifeq "$(LIBRARY)" "shared"
        install $(BINARY) $(PREFIX)/lib
    else
        install $(BINARY) $(PREFIX)/bin
    endif
endif

distclean:
        rm -f $(BINARY) $(OBJECTS)
        @ for i in $(SUBPROJECTS); do make -C $${i} distclean; done

clean:
        rm -f $(OBJECTS)
        @ for i in $(SUBPROJECTS); do make -C $${i} clean; done

.PHONY: all clean distclean install $(SUBPROJECTS)

It’s longer, but not by too much, and now I can safely say it has everything I have ever needed in a fancy build system. It would be nice if I could get pretty colourized output, but this Makefile reliably builds, cleans, and installs the projects I have tested it on.

No Comments Yet »

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.