--- 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&nbsp;&nbsp;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.&#8203;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)