How to Pass Environment Variables to Makefiles in Subdirectories


We all know how to access environment variables inside our Makefile.

Suppose this is our project structure.

📂 project
 ┣ 📜 Makefile
 ┣ 📜 .env
 ┗ 📂 client
    ┣ 📜 Dockerfile
    ┗ 📜 Makefile

In /Makefile, suppose we trigger a make command in the /client/Makefile.

# /Makefile
build-client:
	cd client && $(MAKE) build
# /client/Makefile
build:
	docker build -t client .

But let’s say /client/Makefile needs access to some environment variables inside .env.

# .env
HOSTNAME=localhost
PORT=3000

How can we pass the environment variables into the nested Makefile environment?

In this scenario, we will need to export the variable in the same command as $(MAKE).

From the GNU documentation:

Variables in make come from the environment in which make is run. Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value.

# /Makefile
include .env
build-client:
    export URI=$(HOSTNAME):$(PORT) && \
    cd client && $(MAKE) build

The \ will allow for a multi-line shell command.

Now, this URI variable exists in the environment of the /client/Makefile.

# /client/Makefile
build:
    docker build -t client --build-arg URI=$(URI) .