make
Make is a powerful build system with the simple concept of transforming files in other files based on a recipe
Special chars
The makefile syntax involves some character that expands to specific files when make is executed, such as:
$%the target member name$@expands to the target file$<expands to the first requisite$^expands to all requisites
makefile vars
A var in a makefile is defined as follows:
BUILDDIR = ./build
And is referred with the $() notations
mytarget:
some_long_command $(BUILDDIR)
✔️ ENVIRONMENT variables are automatic exposed with the same notation
$(), example$(HOME)
Also to notice that target indentation is independent from the Makefile one, for example:
do_something:
ifeq ($(app),)
$(error app is not set)
endif
./do_something.sh $(app)⚠️ Warning
The indentation of the command is mandatory and must be a tab character, while the indentation of the rest of the file is not relevant
PHONY targets
Phony targets are targets that doesn’t generate any file, they are a useful way to group other targets together
.PHONY: build cleanExamples
- makefile with build directory that generates png from mermaid graph files
BUILDDIR = ./build
%.png: %.mmd
mkdir -p $(BUILDDIR)
mmdc -i $< -o $(BUILDDIR)/$@
clean:
rm -rf $(BUILDDIR)
build: $(patsubst %.mmd,%.png,$(wildcard *.mmd))Defining dynamic make help messages
This target parses @# Help: comments and prints them side by side with target names
help:
@printf "%-40s %s\n" "Target" "Description"
@printf "%-40s %s\n" "------" "-----------"
@make -pqR : 2>/dev/null \
| awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
| sort \
| egrep -v -e '^[^[:alnum:]]' -e '^$@$$' \
| xargs -I _ sh -c 'printf "%-40s " _; make _ -nB | (grep -i "^# Help:" || echo "") | tail -1 | sed "s/^# Help: //g"'