Here are some useful tips on using Makefile and how to optimize them:
Creating a Makefile
In order to work with Makefile
, we need to create one first:
Hello World
Let’s start with a basic command. Add this to your Makefile
:
Then run make greet
. Hurray, you ran your first Makefile command!
Chaining Commands
Makefile commands can be chained.
Running this will produce the following output:
This is especially useful when you have multiple steps involved, e.g. building and deploying a container:
Suppressing command output
To suppress the command being executed, add @
before the command:
Note the difference between @echo hello
command andecho bye
command when running $ make greet
:
Using Environment Variables
You can pass environment variables into Makefile
when running the command:
Let’s see what will happen when we run the command while passing in the environment variable:
This is useful if you need to use Makefile to configure builds for certain environment, e.g. ENV=prod make build
.
Loading environment variables from file
Makefile can also load environment variables from .env
file. We will touch more on how to load different .env
files ( .env.staging
, .env.production
) next.
If you want to make it optional, add the minus sign before include
. Otherwise, an error will occur if the .env
file does not exist:
The export
will export all available environment variables in the Makefile
.
You can include as many
.env
files as you want, the order matters though
Loading enviroment variables dynamically
You can also load environment variables dynamically based on the current environment. The example below assumes that you use the ENV
environment variable:
Run:
Environment guards
Say if we only want to ensure that certain command can only be run in certain environment:
Run:
You can make a CLI with your Makefile
Just run make
without any commands, it will print the command and the description.
Useful variables
Here are the common variables that might be useful when you are working with Makefiles. Note that to run the shell command, it has to be within the brackets and prefixed with shell, e.g. $(shell git rev-parse HEAD)
.
Using dynamic variables in command
Sometimes you just want to get dynamic values from your command:
Modular Makefiles
You can separate your Makefiles into smaller Makefiles. This promote reusability, while keeping your Makefile small. Say you have the following Makefiles:
In database/Makefile
:
In docker/Makefile
:
You can now include them in your main Makefile
at the root of your project directory:
And you can run all the commands that are available in docker/Makefile
and database/Makefile
:
The only disadvantage is that the naming of the command cannot be the same.
Hope you find this tips useful! You can also find the README for this article here in my Github Repo: https://github.com/alextanhongpin/.makefiles/