Consider my Makefile recipe
build:
export TAG=main; docker build my_dir -t my-image:$(TAG)
I expected $(TAG)
to be replaced with "main", but it's the blank string. I've also tried $$TAG
and $(shell echo $TAG)
, but none of them cause Make to inject "main" as I expected.
Your export TAG=main
sets (and unnecessarily exports) a shell variable. Your $(TAG)
attempts to expand a make
variable. These are not the same thing.
There are at least two possible solutions:
TAG
to a make
variable
TAG = main
# ...
build:
docker build my_dir -t my-image:'$(TAG)'
TAG
as a shell variable
build:
TAG=main; docker build my_dir -t my-image:"$${TAG}"
The former would be cleaner and more natural unless you have some need for TAG
to be an environment variable other than what is apparent in your example.
Notes:
To make
, both $(variable)
and ${variable}
expand to the value of variable variable
, including in recipes, but to the shell, those forms mean different things.
To pass a $
through to the shell -- to get the shell to perform a variable expansion, for example -- it needs to be escaped by doubling it.
make
allows whitespace around the =
in a variable assignment, but the shell does not.
You should quote shell variable expansions with double quotes. You can also quote make variable expansions in recipes with either single or double quotes, and often this is a good idea. The quotes are meaningless to make
, but appropriate for protecting the expansion from further interpretation by the shell.