# make(1) ## Anatomy of `make` rules ```make target .. : prerequisite .. recipe .. ``` - `target`: an output generated by the rule - `prerequisite`: an input that is used to generate the target - `recipe`: list of actions to generate the output from the input > Use `make -p` to print all rules and variables (implicitly + explicitly defined). ## Pattern rules & Automatic variables ### Pattern rules A pattern rule contains the `%` char (exactly one of them) and look like this example: ```make %.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ ``` The target matches files of the pattern `%.o`, where `%` matches any none-empty substring and other character match just them self. The substring matched by `%` is called the `stem`. `%` in the prerequisite stands for the matched `stem` in the target. ### Automatic variables As targets and prerequisites in pattern rules can't be spelled explicitly in the recipe, make provides a set of automatic variables to work with: - `$@`: Name of the target that triggered the rule. - `$<`: Name of the first prerequisite. - `$^`: Names of all prerequisites (without duplicates). - `$+`: Names of all prerequisites (with duplicates). - `$*`: Stem of the pattern rule. ```make # file: Makefile all: foobar blabla foo% bla%: aaa bbb bbb @echo "@ = $@" @echo "< = $<" @echo "^ = $^" @echo "+ = $+" @echo "* = $*" @echo "----" aaa: bbb: ``` Running above `Makefile` gives: ```test @ = foobar < = aaa ^ = aaa bbb + = aaa bbb bbb * = bar ---- @ = blabla < = aaa ^ = aaa bbb + = aaa bbb bbb * = bla ---- ``` Variables related to filesystem paths: - `$(CURDIR)`: Path of current working dir after using `make -C path` ## Useful functions ### Substitution references Substitute strings matching pattern in a list. ```make in := a.o l.a c.o out := $(in:.o=.c) # => out = a.c l.a c.c ``` ### `filter` Keep strings matching a pattern in a list. ```make in := a.a b.b c.c d.d out := $(filter %.b %.c, $(in)) # => out = b.b c.c ``` ### `filter-out` Remove strings matching a pattern from a list. ```make in := a.a b.b c.c d.d out := $(filter-out %.b %.c, $(in)) # => out = a.a d.d ``` ### `abspath` Resolve each file name as absolute path (don't resolve symlinks). ```make $(abspath fname1 fname2 ..) ### `realpath` Resolve each file name as canonical path. ```make $(realpath fname1 fname2 ..) ```