views:

1460

answers:

4

Is it possible to update the environment from a makefile? I want to be able to create a target to set the client environment variables for them. Something like this:

AXIS2_HOME ?= /usr/local/axis2-1.4.1
JAVA_HOME  ?= /usr/java/latest
CLASSPATH  := foo foo

setenv:
    export AXIS2_HOME
    export JAVA_HOME
    export CLASSPATH

So that the client can simply do:

make setenv all
java MainClass

and have it work without them needing to set the classpath for the java execution themselves.

Or am I looking to do this the wrong way and there is a better way?

A: 

Not sure why you would like to do that. What tells you your user will have AXIS2 installed at /usr/local/axis2-1.4.1 ?

turbovince
+3  A: 

No, you can't update the environment in the calling process this way. In general, a subprocess cannot modify the environment of the parent process. One notable exception is batch files on Windows, when run from a cmd shell. Based on the example you show, I guess you are not running on Windows though.

Usually, what you're trying to accomplish is done with a shell script that sets up the environment and then invokes your intended process. For example, you might write a go.sh script like this:

!#/bin/sh
AXIS2_HOME=/usr/local/axix2-1.4.1
JAVA_HOME=/usr/java/latest
CLASSPATH=foo foo
export AXIS2_HOME
export JAVA_HOME
export CLASSPATH
java MainClass

Make go.sh executable and now you can run your app as ./go.sh. You can make your script more elaborate too, if you like -- for example, you may want to make "MainClass" a parameter to the script rather than hard coding it.

Eric Melski
Alternatively, you could omit the last line (`java MainClass`) and then tell your users to *source* the script, which is intended exactly for your situation of setting environment variables in the main shell process.
jhs
Trivia: .BAT and .CMD files on windows are processed within the same instance of CMD.EXE that is prompting and executing interactive commands. This is equivalent to the source command in csh or the . command in sh.
RBerteig
A: 

The quick answer is yes, however in your code, you would need to define the variables in the setenv: directive. Doing it at the beginning of the Makefile makes it a local variable to the Makefile. I would use LOCAL_... at the top of the file then set it in the setenv: directive with VAR=LOCAL_VAR etc... Also remember that you will need to call the makefile with make setenv only. I would really look into doing this in a bash script as the variable needs to be created outside of the Makefile. Once the variable has been generated in the environment, you should be able to assign and export from the Makefile.

Suroot
+3  A: 

From your question I am assuming you're using the bash shell.

You can place the variable definitions in a shell script, like so:

AXIS2_HOME=/usr/local/axis2-1.4.1
export AXIS2_HOME
#etc

And then source the script into the current environment, with

source <filename>

or just

. <filename>

That executes the script in the current shell (i.e. no child process), so any environment changes the script makes will persist.

Kieron
Thanks. I like this way. I'll add a target to the makefile to generate this file to set the classpath and add to the document that it should be sourced.
brofield