====== Makefile ======
Quick reference [[https://www.gnu.org/software/make/manual/html_node/Quick-Reference.html]]
[[http://aegis.sourceforge.net/auug97.pdf|Recursive Make Considered Harmfull]]
[[http://make.mad-scientist.net/papers/rules-of-makefiles/]]
=== one shell ===
NOTE: read carefully issues introduced with "one shell":
[[https://www.gnu.org/software/make/manual/html_node/One-Shell.html|5.3.1 Using One Shell]]
.ONESHELL:
foo : bar/lose
cd $( ../$@
alternatives w/o ''.ONESHELL''
target:
$(Q)( \
set -eo pipefail ; \
if [ -x "/opt/SEGGER/JLink/JLinkExe" ]; then \
echo "Skipping JLINK intallation (reason: already installed)."; \
exit 0; \
fi; \
\
wget -c -P /tmp --post-data "accept_license_agreement=accepted" --progress=dot:giga \
"https://www.segger.com/downloads/jlink/$(JLINK_VERSION).deb"; \
\
$(SUDO) apt-get update; \
$(SUDO) apt-get -y --fix-broken install "/tmp/$(JLINK_VERSION).deb"; \
\
rm "/tmp/${JLINK_VERSION}.deb"; \
make .jlink-workaround; \
make jlink-notice; \
)
=== disable built-in rules ===
# Disable built-in rules and variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --no-builtin-variables
=== VPATH ===
[[https://www.gnu.org/software/make/manual/html_node/General-Search.html]]
VPATH tells makefile where to search for prerequisities:
''VPATH = .:$(OBJDIR):$(LIBDIR)''
=== order only prereq ===
Special pipe "|" character is used.
If any ''$(objects)'' has to be build, then ''obj'' has to be build first.
But if ''obj'' is out of date or missing, this doesn't force ''$(objects)'' to built.
$(objects): | obj
obj:
@mkdir -p $@
targets : normal-prerequisites | order-only-prerequisites
[[https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html]]
=== double colon rules ===
[[https://www.chemie.fu-berlin.de/chemnet/use/info/make/make_4.html#SEC40]]
It can be useful, when target needs to be updated and command to update target depends on which prerequisite file caused the update.
all::
Another scenario is to find source .c file in different dirs
build/%.o:: test/%.c
$(COMPILE) $(CFLAGS) $< -o $@
build/%.o:: src/%.c
$(COMPILE) $(CFLAGS) $< -o $@
build/%.o:: lib/src/%.c lib/src/%.h
$(COMPILE) $(CFLAGS) $< -o $@
* The same target can appear in more than one rule
* each rule is executed if target is older than any prerequisite of that rule
* if no prereq, command is always executed
* Order of execution is not guaranteed
====== Parallel make ======
===== Disabling parallel =====
For whole file: .NOTPARALLEL:
For single target:
.NOTPARALLEL: %.a
.NOTPARALLEL: foo.c bar.c
[[https://stackoverflow.com/questions/8496135/parallel-makefile-requires-dependency-ordering|Parallel makefile requires dependency ordering]]
===== Prevent one target from parallel run =====