Make is a build automation tool that uses a file called a Makefile to define how to build, test, or manage dependencies in a project.
It's commonly used to:
- Compile and link code.
- Automate repetitive tasks (e.g., testing, deploying).
- Track changes in files and only rebuild what’s necessary.
target: prerequisites
recipe
- target: is expected to be a filename.
- prerequisites: is a list of files the target depends on
- recipe: is the command(s) you run to create the target
The entire block of code (target, prerequisite, recipe) is called a 'rule'.
Note
Not all 'targets' will be a filename because you don't always want to use Make
to create files. You often want to use Make to just run some code without the
side-effect of creating a new file. In these cases you annotate your rule with
.PHONY: target
.
Note
You can have multiple prerequisites, and they can either be a filename or they can be the name of another target.
Make's Automatic Variables are special variables that represent parts of a rule, making Makefiles more concise and flexible. They get their values automatically based on the target, prerequisites, or commands.
You'll see a few different automatic variables used:
%
: pattern rule$@
: target name$<
: first prerequisite$^
: list of prerequisites$?
: list of prerequisites that have changed$*
: the stem of a target
Important
Any time you need to use a shell variable (i.e. $foo
) it must be prefixed
with $
.
This is because $
already has a special meaning in Make.
So, the variable would be referenced like $$foo
(see also Make's shell
function).
Let's look at an example rule:
%.mock.pid: %.mock
./%.mock -addr=127.0.0.1:8446 > .$<.log & echo $$! > $@
Then it could be invoked (as an example) like so:
make mustang.mock.pid
The %
wildcard would match the above Makefile target %.mock.pid
.
Next it would ensure the prerequisite mustang.mock
existed (i.e. %.mock
).
Next it would run the ./mustang.mock
binary (i.e. ./%.mock
).
The stdout (>
) would be written to .mustang.mock.log
(i.e. .$<.log
).
Finally, the process ID ($$!
) is written to mustang.mock.pid
(i.e. $@
).