Notes to Self

Alex Sokolsky's Notes on Computers and Programming

make and Makefile

My definition: make is a data-driven (data is in a Makefile) filter for building ‘targets’.

GNU man page, manual, quick reference.

Tutorial

Summary of automatic variables

Manual on automatic variables

Variable Description
$@ the target name
$% the target member name, when the target is an archive member
$< just the first prerequisite
$? all the prerequisites newer than the target
$^ all the prerequisites
.PHONY Adding .PHONY to a target will prevent make from confusing the phony target with a file name. manual, one of many special built-in targets

Examples

c-simple.mak:

#
# simple C program build
#
CC=gcc
CFLAGS=-g
RM=rm -f

default: all

all: build

build: hello.c
	$(CC) $(CFLAGS) -o hello hello.c

clean:
	$(RM) hello

c.mak:

# The name of the source files
SOURCES = main.c foo.c bar.c

# The name of the executable
EXE = main

# Flags for compilation (adding warnings are always good)
CFLAGS = -g -Wall

# Flags for linking, e.g. -L./lib
LDFLAGS =

# Libraries to link with, e.g.  -lcurl
LIBS = -lcurl

# Use the GCC frontend program when compiling
CC = gcc

# Use the GCC frontend program when linking
LD = gcc

# place to store auto-generated dependencies
DEPDIR = .d

#
# Nothing to change below
#

# This creates a list of object files from the source files
OBJECTS = $(SOURCES:%.c=%.o)

.PHONY: all
# Having an "all" target is customary, so one could write "make all"
# It depends on the executable program
all: $(EXE)

# The first target, this will be the default target if none is specified
# This target tells "make" to make the "all" target
default: all


# This will link the executable from the object files
$(EXE): $(OBJECTS)
	$(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(EXE)

# Target to clean up after us
.PHONY: clean
clean:
	# Remove the executable file
	rm -f $(EXE) $(OBJECTS)
	# Remove the dependencies and symbols
	rm -Rf $(DEPDIR) $(EXE).dSYM

# Advanced auto-dependency, from:
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/

$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td

COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d

%.o : %.c
%.o : %.c $(DEPDIR)/%.d
	$(COMPILE.c) $(OUTPUT_OPTION) $<
	$(POSTCOMPILE)

$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d

-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES)))

python.mak


# define the name of the virtual environment directory
VENV:=.venv

PYTHON=$(VENV)/bin/python3
PIP=$(VENV)/bin/pip

# targets which are NOT files
.PHONY: all venv run clean

# default target, when make executed without arguments
all: venv

# venv is a shortcut target
venv: $(VENV)/bin/activate

$(VENV)/bin/activate: requirements.txt
	python3 -m venv $(VENV)
	$(PIP) install -r requirements.txt

run: venv
	./$(VENV)/bin/python3 app.py

clean:
	rm -rf $(VENV) .mypy_cache
	find . -name __pycache__ | xargs rm -rf

#
# Usage: make VENV=my_venv run
#