Some helpful hints: http://make.mad-scientist.net/papers/rules-of-makefiles/
How to do a multi-line bash script, including here-doc, in a Makefile:
define BASHSCRIPT
echo "Running a bash script"
cat > tmp-generated-heredoc.txt <<EOF
contents of the here-doc
line two
line three
EOF
ls -lha tmp-generated-heredoc.txt
rm tmp-generated-heredoc.txt
endef
export BASHSCRIPT
runscript:
bash -c "$$BASHSCRIPT"
Compile target that saves the output of the compile command to a file while preserving error status (piping through tee doesn't preserve error status). The compile command (-x flag to bash) and warnings/errors (cat command) are echoed. After build, you can use a command like "find . -name "*.err" -exec ls {} \; -exec cat {} \;" to see all the warnings/errors. The " || exit 1" at the end is needed only if .ONESHELL: is defined.
%.o: %.c
bash -xc 'gcc -c -o $@ $(CFLAGS) $< > $(@:.o=.err) 2>&1; RV=$$?; cat $(@:.o=.err); exit $$RV' || exit 1
Stew's Makefile template (make sure to put tabs instead of spaces)
CC=gcc
CXX=g++
SRC:=main.c \
file1.c
BUILDDIR:=build
EXENAME:=helloworld
vpath %.c $(dir $(SRC))
vpath %.cpp $(dir $(SRC))
OBJS:=$(patsubst %.c,$(BUILDDIR)/%.o,$(patsubst %.cpp,$(BUILDDIR)/%.o,$(notdir $(SRC))))
GCOVGCNO:=$(patsubst %.o,$(BUILDDIR)/%.gcno,$(notdir $(OBJS)))
GCOVGCDA:=$(patsubst %.o,$(BUILDDIR)/%.gcda,$(notdir $(OBJS)))
CFLAGS+=-Wall -Wextra -Wpedantic -Werror \
-Wlogical-op -Waggregate-return -Wfloat-equal -Wcast-align \
-Wparentheses -Wmissing-braces -Wconversion -Wsign-conversion \
-Wwrite-strings -Wunknown-pragmas -Wunused-macros \
-Wnested-externs -Wpointer-arith -Wswitch -Wredundant-decls \
-Wreturn-type -Wshadow -Wstrict-prototypes -Wunused -Wuninitialized \
-Wdeclaration-after-statement -Wmissing-prototypes \
-Wmissing-declarations -Wundef -fstrict-aliasing -Wstrict-aliasing=3 \
-Wformat=2 \
-O0 -ggdb3 \
-std=c99 -D_POSIX_C_SOURCE=200112L
LDFLAGS+=
.PHONY: all
all:
$(MAKE) $(EXENAME) -j $(shell nproc)
.PHONY: coverage
coverage:
CFLAGS=--coverage $(MAKE) $(EXENAME) -j $(shell nproc)
./$(EXENAME)
lcov -c -d . -o $(BUILDDIR)/$(EXENAME).info
genhtml --legend -o $(BUILDDIR)/coveragereport $(BUILDDIR)/$(EXENAME).info
$(EXENAME): $(OBJS)
$(CXX) -o $@ $(CFLAGS) $^ $(LDFLAGS)
$(BUILDDIR)/%.o: %.c
$(CC) -c -o $@ $(CFLAGS) $< $(LDFLAGS)
$(BUILDDIR)/%.o: %.cpp
$(CXX) -c -o $@ $(CFLAGS) $< $(LDFLAGS)
$(OBJS): | $(BUILDDIR)
$(BUILDDIR):
mkdir $(BUILDDIR)
.PHONY: clean
clean:
$(RM) $(EXENAME) $(OBJS) $(GCOVGCNO) $(GCOVGCDA) $(BUILDDIR)/$(EXENAME).info
$(RM) -r $(BUILDDIR)/coveragereport