Setting environment variables in a makefile

25,843

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.)

Share:
25,843
Ari
Author by

Ari

Software and mobile app designer. My YouTube Channel: https://www.youtube.com/c/arisaif Check out my app for Bitcoin free trading alerts: http://bitcoincrazyness.com

Updated on June 08, 2020

Comments

  • Ari
    Ari almost 4 years

    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?