Last active
July 31, 2016 21:39
-
-
Save r10r/9362957 to your computer and use it in GitHub Desktop.
Generic Makefile honoring 'Why recursive make is harmful' http://aegis.sourceforge.net/auug97.pdf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh --posix | |
SRC="$1" | |
DIR=`dirname $SRC` | |
SUFFIX=o.mk | |
shift 1 | |
# append dependency information | |
RULE=`cc -MM -MG "$@"` | |
#OBJ=`echo "$RULE" | cut -d':' -f 1` | |
SRC=`echo "$RULE" | cut -d':' -f 2` | |
cat <<EOF | |
${DIR}/${RULE} | |
SRC += ${SRC} | |
EOF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-include Settings.mk | |
# [ project ] | |
# =========== | |
default: all | |
# [ settings ] | |
# ============ | |
BASE_DIR := $(realpath $(PWD)) | |
BUILD_DIR := $(BASE_DIR)/build | |
OS := $(shell uname -s) | |
GCOV_TOOL ?= gcov | |
CFLAGS += -I$(INCLUDE_DIR) | |
# use this in modules to reference to the included modules.mk | |
DIR = $(realpath $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))) | |
# each module may append to this | |
OBJS := | |
SRC := | |
PROGRAMS := | |
TESTS := | |
# include the description for each module | |
-include module.mk | |
include $(patsubst %,%/module.mk,$(MODULES)) | |
# look for include files in each of the modules | |
# use -isystem ? | |
CFLAGS += $(patsubst %,-I%,$(MODULES)) | |
all: $(OBJS) $(PROGRAMS) $(TESTS) | |
# [ os ] | |
# ====== | |
ifeq ($(DEBUG), true) | |
ifeq ($(OS),Darwin) | |
CFLAGS += -gdwarf-2 -g -O0 -fno-inline | |
endif | |
ifeq ($(OS),Linux) | |
CFLAGS += -g -O0 -fno-inline | |
endif | |
endif | |
# [ build ] | |
# ========= | |
define PROGRAM_template | |
$(1): $$($(2)_OBJS) $(1).c | |
$$(CC) $$(CFLAGS) $$($(2)_CFLAGS) $$(LDFLAGS) $$($(2)_LDFLAGS) \ | |
-o $(1) $$($(2)_OBJS) | |
OBJS += $$($(2)_OBJS) | |
endef | |
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(notdir $(prog))))) | |
define TEST_template | |
$(1): $$($(2)_OBJS) $(1).c | |
$$(CC) $$(CFLAGS) $$($(2)_CFLAGS) $$(LDFLAGS) $$($(2)_LDFLAGS) \ | |
-o $(1) $$($(2)_OBJS) && $(1) | |
OBJS += $$($(2)_OBJS) | |
endef | |
$(foreach prog,$(TESTS),$(eval $(call TEST_template,$(prog),$(notdir $(prog))))) | |
# [ headers ] | |
# =========== | |
# calculate C include dependencies | |
%.o.mk: %.c | |
$(BASE_DIR)/depend.sh $*.c $(CFLAGS) $*.c > $@ | |
# include the C include dependencies | |
include $(OBJS:=.mk) | |
# [ uncrustify ] | |
# ============== | |
.uncrustify: $(SRC) | |
uncrustify --mtime -c $(BASE_DIR)/uncrustify.cfg --replace $? &&\ | |
touch .uncrustify | |
uncrustify: .uncrustify; | |
# [ ragel ] | |
# =========== | |
# object generation rules | |
.PRECIOUS: %.c | |
%.c: %.rl | |
ragel -L -G2 -o $@ $< | |
%.dot: %.rl | |
ragel -V -p -o $@ $< | |
%.png: %.dot | |
dot -Tpng $< -o $@ | |
# [ gcov/lcov ] | |
# ============= | |
LCOV_INFO_FILE := coverage.info | |
LCOV_DIR := coverage | |
$(LCOV_DIR)/index.html: $(LCOV_INFO_FILE) | |
genhtml --ignore-errors source $(LCOV_INFO_FILE) \ | |
--output-directory $(LCOV_DIR) | |
$(LCOV_INFO_FILE): $(TESTS) | |
lcov --capture --directory $(BASE_DIR) \ | |
--no-external --output-file $(LCOV_INFO_FILE) \ | |
--gcov-tool $(GCOV_TOOL) | |
coverage: $(LCOV_DIR)/index.html; | |
# [ clean ] | |
# ========= | |
# contains only existing artifacts | |
ARTIFACTS := $(OBJS) $(OBJS:=.mk) \ | |
$(OBJS:.o=.gcda) $(OBJS:.o=.gcno) \ | |
$(LCOV_DIR) $(LCOV_INFO_FILE) | |
clean: | |
rm -rf $(ARTIFACTS) | |
-include Rules.mk |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment