Table of Contents

Makefile

Quick reference https://www.gnu.org/software/make/manual/html_node/Quick-Reference.html

Recursive Make Considered Harmfull

http://make.mad-scientist.net/papers/rules-of-makefiles/

one shell

NOTE: read carefully issues introduced with “one shell”: 5.3.1 Using One Shell

.ONESHELL:
foo : bar/lose
        cd $(<D)
        gobble $(<F) > ../$@

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 $@

Parallel make

Disabling parallel

For whole file:

.NOTPARALLEL:

For single target:

.NOTPARALLEL: %.a 
.NOTPARALLEL: foo.c bar.c 

Parallel makefile requires dependency ordering

Prevent one target from parallel run