Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I tell Make to ignore environment variables?

Tags:

bash

makefile

I came across some odd behavior when using Make recently (v3.81).

Suppose I have the following Makefile:

FOOBAR = $(shell find nonexistentdirectory -iname "foobar" | tr '\n' ' ')

all:
    @echo "Hi"

clean:
    @echo "Hi again"

Seems straightforward enough, right? Notably, FOOBAR is a "recursively-expanded variable", so it should not be evaluated until I refer to it. Note that I never refer to it. Also note that nonexistentdirectory does not exist as you might expect.

Now suppose I set FOOBAR in the shell before I invoke a Make target:

compy386$ FOOBAR="stuff" make clean
find: nonexistentdirectory: No such file or directory
Hi again

Why is FOOBAR being evaluated? Clearly it has something to do with the fact that the variable is defined in the shell. Am I supposed to anticipate that a user might have set variables in their shell? What am I doing wrong here?!

like image 371
Dan Barowy Avatar asked Dec 17 '13 23:12

Dan Barowy


People also ask

Is it necessary to set environment variable?

However, setting some environment variables makes some things easier. PATH If the jre/bin folder is on the path, you don't have to qualify to run the java command. If the jdk/bin folder is on the path, you don't have to qualify to run the java and javac commands. As well as some other commands provided by Java.

Is using environment variables safe?

The hidden danger of using environment variables for secrets management is that the architectural solution could allow users to unwillingly cross security boundaries even with only a single piece of information leaked.

How do I check if an environment variable is set in Makefile?

Check if variable is defined in a Makefilecheck_defined = \ $(strip $(foreach 1,$1, \ $(call __check_defined,$1,$(strip $(value 2))))) __check_defined = \ $(if $(value $1),, \ $(error Undefined $1$(if $2, ($2)))) install: $(call check_defined, var1) $(call check_defined, var2) # do stuff here..


1 Answers

FOOBAR is being evaluated because you are running a recipe (for clean) and FOOBAR existed in the environment on entry to make. Because FOOBAR existed in the environment on entry, it becomes an exported variable, which means that make will provide it as part of the environment to any program in the recipe. make doesn't special-case echo; it just uses the one found in your path. And it can't know whether or not that utility will reference a particular environment variable, so it has to export all exported variables, which means it has to evaluate FOOBAR.

(For the official word, see the third paragraph of Variables from the Environment in the make manual. Also see the recipe on recursive make invocation.)

To answer the direct question, you can tell make to ignore the fact that a variable came from the environment, so that it doesn't re-export it, by unexporting it:

unexport FOOBAR
like image 95
rici Avatar answered Sep 28 '22 19:09

rici