help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: argument 'v=x' does not appear to work as in the manual ?


From: Paul Smith
Subject: RE: argument 'v=x' does not appear to work as in the manual ?
Date: Fri, 26 Nov 2010 14:48:44 -0500

Please try to avoid top-posting; cheers!

On Fri, 2010-11-26 at 00:27 -0800, Mark Galeck (CW) wrote:
> I quoted for you the exact wording from the manual, it says precisely,
> if there is a = in the option, then the left of the = is interpreted
> as the variable name, and the right of the = is the value.  There is
> no mention of any +=.  

Yes, the manual should be made clearer.  In fact, any assignment
operator available inside a makefile is also available on the command
line (so ?=, :=, +=, etc.)

> Currently in fact, this is not working as "assignment operator", as
> you seem to be saying, the following should yield "foo bar", it does
> not.  
>
> > C:\Temp>make  CFLAGS+=bar
> bar
> 
> It appears that in fact
> >make CFLAGS+=bar
> Behaves just like
> >make CFLAGS=bar

Yes, this is non-intuitive, but that's not technically a bug.  You have
to remember that in make, command-line arguments have a higher
precedence than variables assigned in the makefile.  Whenever a variable
is specified on the command line it is marked with this higher
precedence, and so all future attempts to modify it (using an operation
with lower precedence) will be ignored.

Also remember that assignments on the command line happen FIRST, before
any makefile is read.  So your method does not work, because the
assignment of CFLAGS+=bar is processed before any makefile and so the
original value of CFLAGS is empty, then "bar" is added, and in addition
the CFLAGS variable is set to have "command line precedence".

Then later when the makefile is read make sees "CFLAGS = foo" which
would normally override CFLAGS and set it to just "foo", but since
CFLAGS is marked at command-line precedence that assignment is ignored.

So first, in your makefile you'd want to use "CFLAGS += foo", not
"CFLAGS = foo", but that still won't work due to precedence.

You CAN make this work, if you really want to, by using the override
keyword (see the GNU make manual); putting this in your makefile:

        override CFLAGS += foo

then having "make CFLAGS=bar" will do what you want (CFLAGS will be "bar
foo").

However, this requires that ALL settings of CFLAGS be handled carefully
with override.  I consider this very fragile and, generally, to be
avoided.

> So, if I understand you correctly, then A) there should be a mention
> in the manual where it talks about command line assignments, that "+="
> may be used also, with the expected result, and B) the expected result
> is that the value of CFLAGS from the makefile, is appended with
> whatever we put on the command line.

Yes (kind of, depending on your definition of "expected result") to (A),
no to (B).

On Fri, 2010-11-26 at 14:01 +0200, Eli Zaretskii wrote:
> > Here's the WHOLE STORY
> > 
> > What users wanted me to do, is to give them the ability to type
> > 
> > >make CFLAGS+=-foo
> > 
> > and what that would do, is add the value specified, to the value of
> CFLAGS already in the makefile (I guess, speaking precisely, as it is
> at the end of the fist pass of the make).
> 
> The usual way of letting users do that is to have a separate variable,
> USER_CFLAGS, say, which users can set from the command line and which
> the Makefile then adds to the value of CFLAGS.  That's much more
> straightforward to implement, and you don't need any shell-level
> tricks for making it work.

In fact, I _STRONGLY_ encourage you (Mark) to adopt the GNU standard
methods here.  The GNU standards require that makefile authors reserve
all the standard variables for users via the command line, so that users
of any GNU-standard makefile can always run:

        make CFLAGS=-O2 CXXFLAGS=-O2 CPPFLAGS=-I/usr/local/include

etc.  To accomplish this, GNU-standard makefiles always use a DIFFERENT
variable internally to store flags that they want to provide, and then
add CFLAGS (which is normally set to a simple default like "-g -O2")
separately, as Eli suggests above:

        CFLAGS = -g -O2
        my_CFLAGS = -Werror
        my_CPPFLAGS = -I../include
        
        %.o : %.c
                $(CC) $(my_CFLAGS) $(my_CPPFLAGS) $(CFLAGS) $(CPPFLAGS) -o $@ 
-c $<

etc.

> By the way, when somebody disagrees with me on makefiles, I say "Paul
> Smith would do it this way".  I hope you don't mind :)  

Is that argumentum ad verecundiam?  :-)

I guess only if I'm wrong :-p :-)

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.mad-scientist.net
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]