---
tags: cheatsheet
---
# Makefile Cheatsheet
## Variables
- `$(foo)`: use the vairable *foo*.
- `${foo}`: same as `$(foo)`.
- `foo = bar`, `foo= bar`, `foo =bar`, `foo=bar`: set *foo* to `bar`.
- `foo = bar1 bar2`, <code>foo = bar1 bar2</code>: set `*foo* to string `bar1 bar2`.
```makefile
foo = fzhong lin lee
@echo $(foo) # "fzhong lin lee"
```
- `foo = $(bar)`: set *foo* to the value of varirable *bar*; when the value of variable *bar* changed, *foo* changes as well.
- `foo := $(bar)`: define the variable *foo* as *bar*. Variables defined with `:=` in GNU make are expanded when they are defined rather than when they are used.
```makefile
fzhong = good
foo := $(fzhong)
fzhong = bad
@echo $(foo) # "good"
```
```makefile
fzhong = good
foo = $(fzhong)
fzhong = bad
@echo $(foo) # "bad"
```
- `foo ?= bar`: if *foo* is set or is an empty string then make *foo* unchanged; otherwise set it to `bar`.
- `foo += bar`: append variable *foo* with `bar`; a space is appended before `bar`.
- `foo != echo bar`: execcute shell command and assign to *foo*.
```makefile
foo = fzhong
foo += ccy
@echo $(foo) # "fzhong ccy"
```
## Implicit Variables
- Compilers
- `CC`: Program for compiling C programs; default `cc`.
- `CXX` Program for compiling C++ programs; default `c++`. Noted that `c++` is often linked to `g++`.
- ~~`CPP`~~: C preprocesor; default `$(CC) -E`.
- `CFLAGS`: Extra flags to give to the C compiler; default empty. For example `CFLAGS = -Wall -Wextra -O2 -g -I./src/include`.
- `CXXFLAGS`: Extra flags to give to the C++ compiler; default empty. For example `CXXFLAGS = -Wall -Wextra -O2 -g -I./src/include`.
- ~~`CPPFLAGS`~~: Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
- Linkers
- `LD`: linker; default `ld`.
- `LDFLAGS`: Extra flags to give to compilers when they are supposed to invoke the linker, ld, such as `-L`. Libraries (`-lfoo`) should be added to the `LDLIBS` variable instead.
- For example `LDFLAGS = -L./src/libs`.
- `LDLIBS`: Library flags or names given to compilers when they are supposed to invoke the linker, ld. Non-library linker flags, such as `-L`, should go in the `LDFLAGS` variable.
- For example `LDLIBS = -lm -lpthread`
- Utilities
- `MAKE`: make command; default `make`.
- `RM`: remove command; defualt `rm -f`.
## Magic Variables
- `$@`: target name.
- `$<`: first prerequisite.
- `$^`: all prerequisites.
- `$*`: the 'stem' with which an implicit rule matches.
```makefile
out.o: src.c src.h
$@ # "out.o"
$< # "src.c"
$^ # "src.c src.h"
%.o: %.c
$* # "foo" in "foo.c"
```
## Substitutions
- `$(var,a=b)`: take the value of the variable *var*, replace every *a* at the **end** of a **word** with *b* in that value, and substitute the resulting string.
- `${var,a=b}`: same as above.
```makefile
foo := a.o b.o l.a c.o
bar := $(foo:.o=.c) # bar is "a.c b.c l.a c.c"
```
- `$(var,%.a=%.b)`: take the value of the variable *var*, replace every *a* with *b* in that value, and substitute the resulting string.
```makefile
foo := src/a.ts src/b.ts
bar := $(foo:src/%.ts=lib/%.js) # bar is "lib/a.js lib/b.js"
```
## Functions
- `$(wildcard ...)`: find files.
- `$(wildcard *.c)`: find all c files in current directories; exclusive of subdirectories.
- `$(wildcard */*.c)`: find all c files in subdirectories; exclusive of files that are directly under current directory.
- `$(wildcard *.c) $(wildcard */*.c)`: find all c files in curreny diretory; inclusive of subdirectories.
- `$(subst from,to,text)`: substitute text.
- `$(subst a,b,ccaa)`: get `ccbb`.
- `$(subst a, b, ccaa)`: get ` cc b b`; makefile is space-sensitive.
- `$(patsubst from,to,text)`: substitute **words** in text using pattern.
- `$(patsubst a,b,ccaa)`: still get `ccaa` since no word `a` appears in text `ccaa`.
- `$(patsubst a,b,cc aa a)`: get `cc a b`.
- `$(patsubst %.c,poo,fzhong.a fzhong.c)`: get `fzhong.a poo`.
- `$(patsubst %.c,%.poo,fzhong.a fzhong.c)`: get `fzhong.a fzhong.poo`.
- `$(shell ...)`: run shell commands.
- `$(shell find . -name "*")`: find all files.
## Implicit Rules
- foo.o: foo.c
```makefile
$(CC) -c $(CPPFLAGS) $(CFLAGS)
```
- foo.o: foo.​cc
- foo.o: foo.cpp
```makefile
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
```
- foo: foo.o
```makefile
$(CC) $(LDFLAGS) t.o $(LOADLIBES) $(LDLIBS)
```
## Command Prefixes
- `-`: ignore errors.
- `@`: don't print command.
```makefile
build:
@echo "compiling"
-gcc $< $@
```
## Magic
- `.PHONY`: target that is not a name of a file.
```makefile
# run the task even if there exists a file named "clean"
.PHONY: clean
clean:
$(RM) *.o
```
## Options
- `make -j 8`: run make with 8 threads.
- `make -j`: run make with *n* threads where *n* is the count of processors.
- `make -s`: silent mode.
- `make -e CC=/usr/bin/mycc -e CXX=/usr/bin/mycxx`: override environment vairables.
## Reference
- [A Short Introduction to GNU make](https://berrendorf.inf.h-brs.de/sonstiges/make.html)
- [GNU Make Cheatsheet](https://gist.github.com/rueycheng/42e355d1480fd7a33ee81c866c7fdf78)
- [Makefile cheatsheet](https://devhints.io/makefile)
- [Your Makefiles are wrong](https://tech.davis-hansson.com/p/make/)
- [GNU] [Function for file names](https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#File-Name-Functions)
- [GNU] [Functions for String Substitution and Analysis](https://www.gnu.org/software/make/manual/html_node/Wildcard-Function.html)
- [GNU] [Substitution References](https://www.gnu.org/software/make/manual/html_node/Substitution-Refs.html)
- [GNU] [Variables Used by Implicit Rules](https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html)