Makefile syntax
Makefile templates topic on GitHub - makefile-template
Targets (commands) will differ per project and environment but these can be applied where relevant.
Remember, the make command also supports tab autocomplete for targets.
For language specific examples, see my Code Cookbook project’s make section.
Phony
Phony is useful if your target matches an actual directory but you don’t want to make to run against it. Normally, you could run make DIR for compiling a C program or similar, but that isn’t helpful outside of compiled languages.
This can be done at the start, or just before each target.
Here we use PHONY where foo and docs are actual directories as well targets.
- `Makefile
.PHONY: foo docs foo: echo 'Foo' docs: echo 'Test' - `Makefile
.PHONY: foo foo: echo 'Foo' .PHONY: docs docs: echo 'Test'
Please don’t add PHONY to every target - since serves no purpose and just clutters the file.
Comments
You can put a comment anywhere.
The comment will be printed when the target runs. But you can use @# to prevent it from printing.
- `Makefile
# Comment. foo: # Another comment. # Yet another comment. @# This comment won't be printed. echo 'Foo'
Export
Use variables in commands.
Given file .env with variable set as FOO=bar and script_that_echoes_foo.sh which does echo $FOO.
Do this
The combination of export and source works well.
- `Makefile
export FOO='' test: source .env && echo $$FOO source .env && ./script_that_echoes_foo.sh
Don’t do this
The following will not work as expected ,due to make limitations on environment setting of child processes.
- `Makefile
test: source .env echo $$FOO
The following will not work either, with or without export set at the top.
- `Makefile
test: export $(<.env) && ./script_that_echoes_foo.sh
Control flow
Using conditionals and iteration, similar to shell.
Note that unlike in the shell, the \ is necessary in a Makefile so that the command is combined on one line at run at once.
For
- `Makefile
foo: for bar in my-dir/*; do \ export fizz=$$(echo $$bar) \ $(MAKE) plan; \ done
If
Note lack of indentation.
- `Makefile
TARGET: ifneq (CONDIITION, ) ACTION endif ACTION
Syntax in Make docs.
Example:
- `Makefile
libs_for_gcc = -lgnu normal_libs = foo: $(objects) ifeq ($(CC),gcc) $(CC) -o foo $(objects) $(libs_for_gcc) else $(CC) -o foo $(objects) $(normal_libs) endif
Alternate:
- `Makefile
TARGET: @if [ CONDITION ]; then \ ACTION ; \ fi
Get the current target name
Makefilea: echo $(@) b: echo $(@)
Shell usage:
$ make a b
echo a
a
echo b
b