Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting environment variables in a makefile

I have a makefile like this:

setup:
  setenv var1 "$(var1)"; \
  setenv var2 "$(var2)";

task1: setup
  source task1.csh

task2: setup
  source task2.csh

I call the makefile using this command:

make var1=value1 var2=value2 task1

I would like environment variables var1 and var2 to be visible in task1.csh and task2.csh, but I haven't been able to do so unless I change the makefile to:

task1:
  setenv var1 "$(var1)"; \
  setenv var2 "$(var2)"; \
  source task1.csh

task2:
  setenv var1 "$(var1)"; \
  setenv var2 "$(var2)"; \
  source task2.csh

Why the first method doesn't work and how can I fix it?

like image 940
Ari Avatar asked Dec 03 '14 22:12

Ari


1 Answers

That doesn't work because every line in a makefile rule is run in its own shell instance.

From the GNU make manual:

When it is time to execute recipes to update a target, they are executed by invoking a new sub-shell for each line of the recipe, unless the .ONESHELL special target is in effect (see Using One Shell) (In practice, make may take shortcuts that do not affect the results.)

Please note: this implies that setting shell variables and invoking shell commands such as cd that set a context local to each process will not affect the following lines in the recipe.2 If you want to use cd to affect the next statement, put both statements in a single recipe line

So you can do it the way you listed or you can export the variables from make and they will be in the environment of the sub-shells already.

export var1 = value1
export var1 = value2

task1: source task1.csh

task2: source task2.csh

As a side note why are you sourcing those scripts instead of just running them directly (./task1.sh)?

(I'm assuming you set SHELL = csh or similar in your makefile to make this work at all already.)

like image 153
Etan Reisner Avatar answered Sep 18 '22 00:09

Etan Reisner