export does not work on makefiles

  • Follow


Hi,

If I have a Makefile like:

test: 
     export test=5


why does this not cause the environment variable test to be visible after
execution of make?

Thanks,
Uwe
0
Reply Uwe 12/6/2004 5:38:03 PM

Uwe Mayer <merkosh@hadiko.de> writes:

> Hi,
>
> If I have a Makefile like:
>
> test: 
>      export test=5
>
> why does this not cause the environment variable test to be visible after
> execution of make?

Because that would be evil, and is impossible to do.

-- 
M�ns Rullg�rd
mru@inprovide.com
0
Reply iso 12/6/2004 5:47:21 PM


In <cp25dr$323$1@news2.rz.uni-karlsruhe.de> Uwe Mayer <merkosh@hadiko.de> writes:

> If I have a Makefile like:

> test: 
>      export test=5

> why does this not cause the environment variable test to be visible after
> execution of make?

In general, whenever you run a command (such as make), that command runs
as a separate process with its own copy of the parent process' environment.

If that command makes any changes to the environment (such as exporting
variables), those changes apply only to its copy of the environment, NOT
to the environment of the parent shell which spawned that process.

And that's exactly what happened here.  You ran make, which starts up a
new child process.  That child process modified its environment and then
immediately exited.

It's a Very Good Thing that child processes cannot modify the environment
of parent processes.  Trust me.

-- 
John Gordon        "Between BST melee, their spells, their warders' melee,
gordon@panix.com    and their warders' procs, they put out enough damage
                    to make monks cry." -- Dark Tyger

0
Reply John 12/6/2004 8:20:31 PM

Uwe Mayer  <merkosh@hadiko.de> wrote:
>If I have a Makefile like:
>
>test: 
>     export test=5
>why does this not cause the environment variable test to be visible after
>execution of make?

Because you're already in a subshell when this is executed.
  1) shell variables (unexported) only exist for the shell in which they're
     set.
  2) environment variables (including exported shell variables) are available
     to every child process (mostly) and subshell.
  3) a child process has no way to change the variables of either type in a
     parent.
  4) the '.' or 'source' operation of most shells can be used to run a script
     in the same shell, rather than starting a new shell.

When using make, you have 3 (or more) important processes, each of which
have their own environment variable list.  The main shell, probably your
login shell is the outer one.  The next one is the make process, which
starts with an environment created by the parent shell, but can change it
before exec-ing the third.  The third is a new shell created to run each
recipe. 

The shell for a given recipe can change it's own variables, and can
set the initial environment for any process it creates by exporting or
changing exported variables.  Nothing it does, though, will change the
environment of it's parent (make) or grandparent (login shell) process.  Or
even it's sibling (other recipe shells) processes. 

The common way to work around this is to have the child process write a script
file, which the (grand)parent process can execute in-process to set variables.

For instance, if your makefile runs something that creates a setEnv.sh file,
and you do 'source setEnv.sh' after 'make', then you get the effects of
setEnv.sh in your current shell.
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>  
0
Reply dagon 12/7/2004 6:47:23 PM

Mark Rafn wrote:

> The common way to work around this is to have the child process write a script
> file, which the (grand)parent process can execute in-process to set variables.
> 
> For instance, if your makefile runs something that creates a setEnv.sh file,
> and you do 'source setEnv.sh' after 'make', then you get the effects of
> setEnv.sh in your current shell.

In fact I've played (successfully) with more automated approaches to 
this. E.g. (ksh syntax):

trap 'if [[ -r ~/.sigusr1 ]]; then . ~/.sigusr1 && /bin/rm ~/.sigusr1; 
fi' USR1

If the parent shell has registered to handle SIGUSR1 as above, the child 
can simply write a ~/.sigusr1 file and send the signal to its parent. 
This is not more than a toy and is not recommended for general use but 
it's an example of a way to push settings upstream.

-- 
Henry Townsend
0
Reply Heny 12/7/2004 8:10:28 PM

4 Replies
513 Views

(page loaded in 0.057 seconds)

Similiar Articles:













7/20/2012 7:10:45 AM


Reply: