Paul, Thanks for the explanation and alternate solution to what I want.
Your explanation was very helpful in helping me to better understand what is done and when things are done during the "second phase" of gmake. This also brings up a point which you may have heard. The gmake doc doesn't use examples in some cases to clarify it's functionality - this being a perfect example. I've read about 1st/2nd phase of gmake. But, I still wasn't sure when the $(shell function expansion would occur - when I thought or what you described. Anyway, I think my example below would be a great one to add to the "3.7 How make reads a Makefile" section. Thanks Again, Eric -----Original Message----- From: Paul D. Smith [mailto:[EMAIL PROTECTED]] Sent: Thursday, April 04, 2002 5:12 PM To: Asperheim, Eric Cc: '[EMAIL PROTECTED]' Subject: Re: clarification of deferred function expansion %% "Asperheim, Eric" <[EMAIL PROTECTED]> writes: ae> I've read the gmake v3.79.1 doc (p. 14) about deferred "Expansion ae> of deferred construct is not performed until either the construct ae> appears later in an immediate context, or until the second phase" ae> of gmake's operation. Given that the shell command ae> $(shell echo $$ENV_VAR) ae> expansion was deferred since it's part of a define directive, I ae> was expecting this to work. I'm setting an environment var ENV_VAR ae> (using bash shell) and then trying to use that env var in the next ae> command. But, this doesn't work. Note, I tried to use the gmake ae> var $(ENV_VAR). But, this doesn't work either since the value of ae> $(ENV_VAR) is the value of the env var at gmake invocation - which ae> is not what I want. ae> Initially - ENV_VAR is set to "0" ae> define cmd ae> ENV_VAR=1; \ ae> export ENV_VAR; \ ae> set TCL_VAR {$(shell echo $$ENV_VAR)}; ae> endef ae> default : ae> @ $(cmd) ae> fhc2349:easperhe gmake -n ae> ENV_VAR=1; export ENV_VAR; set TCL_VAR {0}; This is correct behavior. When working with make you always must, _must_ keep in mind the distinction between things that make does and things that the shell does. The shell is a subprocess, and as such any modification of its environment is completely its own; make cannot be impacted by it. Likewise, no environment change from one shell that is invoked by make (or elsewhere) can impact any sibling shell (shell also invoked by make, before or after it). Consider what happens above: make sees the define, and it stores the value as a string and does not expand it. So the value of $(cmd) is the string: ENV_VAR=1; \ export ENV_VAR; \ set TCL_VAR {$(shell echo $$ENV_VAR)}; (BTW there's no need to use define/endef here; you could use a simple variable assignment. Also, what is the syntax of the last line? It looks like C shell to me...?). Next, make reads the target and remembers that the command script to build it is the string "@ $(cmd)" (again, not expanded). Now it's done reading, so it proceeds to phase two and wants to build the default rule. Before it can build the rule, it has to expand all make variables and functions in the script of course, so it proceeds like this: $(cmd) => ENV_VAR=1; export ENV_VAR; set TCL_VAR {$(shell echo $$ENV_VAR)}; Now make sees that there is a function, shell, so it _invokes a shell and runs the commandline, in this case "echo $ENV_VAR" (after escaping). Note it is _not_ running the entire command script, only the shell function is being expanded here. Obviously, the value of is $ENV_VAR is 0 since we are running this directory from make, before any of the command script has been executed. Once that shell command is done its value is substituted into the command script, and a shell is invoked and given the command script: ENV_VAR=1; export ENV_VAR; set TCL_VAR {0} ae> Is this the expected behavior? Or, is there a bug in gmake. If ae> this is the intended behavior, is there anyway to do what I want ae> to do? Sure. You have to get the _shell_ to do it, as part of the command script, not ask make to do it, before the command script is invoked. This should do what you want: cmd = ENV_VAR=1; export ENV_VAR; set TCL_VAR {`echo $$ENV_VAR`} See how we use the shell's backtick commands to perform the echo, rather than having make do it which must happen before the command is invoked, and thus before ENV_VAR is set to 1. -- ---------------------------------------------------------------------------- --- Paul D. Smith <[EMAIL PROTECTED]> Find some GNU make tips at: http://www.gnu.org http://www.paulandlesley.org/gmake/ "Please remain calm...I may be mad, but I am a professional." --Mad Scientist _______________________________________________ Help-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/help-make
