Subject: RE: Cygwin make thinks a statement can be neither true nor false....
From: "Paul D. Smith" <[email-masked]>
To: "Dave Korn" <[email-masked]>
Cc: <[email-masked]>, [email-masked]
Date: Tue, 20 Apr 2004 11:44:07 -0400

%% "Dave Korn" <[email-masked]> writes:

  >> I would've expected it to complain about a bad substition reference,
  >> ie. it's missing an "=".

  dk>   Or at least do anything, rather than nothing!

If you enable --warn-undefined-variables then you'll get a warning.

  dk> Great.  So for the benefit of providing a feature that is
  dk> virtually impossible to safely and correctly use (chars in
  dk> variable names that aren't allowed in shell variables) the authors
  dk> of make have created a syntax that is so ambiguous it defies error
  dk> detection and reporting.  Wahey.

Well, this has been true of every version of make since make was
invented 30+ years ago, not to mention required by the POSIX standard,
so... a little late to worry about it now :).

  dk> Considering the close conceptual relationship between shell
  dk> variables and make variables, and the way they get exported and
  dk> imported to each other, it just seems like a mistake to try and
  dk> pretend they're decoupled to such an extent they could be
  dk> incompatibly named.

I don't agree that there is a close conceptual relationship.  In fact, I
think it's very important to not view make variables that way.

Make does _NOT_ export every variable into the environment.  Make treats
the environment variable space and its internal variable space as two
distinct entities, and makefile writers are well advised to consider
them that way as well.

When make starts up it "imports" all of the environment variables as
make variables, yes.  And, the user can request that certain variables
be exported from the make variable space into sub-processes' environment
variable space, through "export".

But no variable which is not so treated will be sent to subprocesses.

For my part I _OFTEN_ use characters which are invalid in shell
variables (such as ".", etc.) when I create make variables, for exactly
this reason: they are then unique to make and I don't have to worry
about any interaction with the shell.

However, I do agree that allowing whitespace, in particular, in variable
names is a bad idea and I've considered removing that capability, or
anyway only allowing it when .POSIX is set.  This would give GNU make
much more flexibility to catch problematic function invocations, and it
would even allow me to create some syntactic sugar for the $(call ...)
function: a construct like $(<word> <words...>) could be recognized as
shorthand for $(call <word>,<words>), which would be nice (obviously
this would fail if the variable <word> was not defined).

  dk> -------> snip!<-------
  dk>    Likewise variables defined on the command line are passed to the
  dk> sub-`make' through `MAKEFLAGS'.  Words in the value of `MAKEFLAGS' that
  dk> contain `=', `make' treats as variable definitions just as if they
  dk> appeared on the command line.  *Note Overriding Variables: Overriding.
  dk> -------> snip!<-------

  dk> Oh no it doesn't: neither for variables defined on the initial
  dk> make command line, nor for variables passed to a recursive
  dk> submake.  Here's my sample makefile:

Your test doesn't test the behavior the manual is discussing.

All this portion of the manual says is that if you do this:

  $ MAKEFLAGS='FOO=bar' make

or if you have this:

    submake: ; $(MAKE) MAKEFLAGS='FOO=bar'

that the variable FOO will be set to "bar" in the make that gets
invoked.

How make does this is not discussed here; in fact make _DOES_ split this
into multiple variables and they are passed down to submakes that way,
but this is not necessarily visible to the user.

Here is a test that shows the behavior documented by that excerpt from
the manual, and shows that it does work as documented:

  .PHONY: all showfoo
  all: showfoo
	$(MAKE) showfoo MAKEFLAGS='FOO=1'

  showfoo: ; @echo 'FOO=$(FOO)'

  $ make
  FOO=
  make[1]: Entering directory `/home/psmith'
  FOO=1
  make[1]: Leaving directory `/home/psmith'

  $ MAKEFLAGS='FOO=5' make -f /tmp/3.mk
  FOO=5
  make -f /tmp/3.mk showfoo MAKEFLAGS='FOO=1'
  make[1]: Entering directory `/home/psmith'
  FOO=1
  make[1]: Leaving directory `/home/psmith'

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <[email-masked]>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.paulandlesley.org
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/