Given a makefile, with a target-specific
defintion:
# A target-specific definition for both: 'all' and 'x'.
all : foo += target
x : foo += target
all : x ;
x ::
@echo '$(foo)'
Running, I get:
# override Makefile-level variables, with a command-line definition.
$ make foo=cmd
cmd
Now, the same makefile, as above, but with a pattern-specific
defintion:
# A pattern-specific definition that matches both targets: 'all' and 'x'.
% : foo += target
all : x ;
x ::
@echo '$(foo)'
Running, I get:
# override Makefile-level variables, with a command-line definition.
$ make foo=cmd
cmd cmd cmd
Now, both makefiles are almost identical, except that:
- For version 1 of Makefile: (With target-specific definition), we had:
all : foo += target
x : foo += target
- For version 2 of Makefile (With pattern-specific definition), we had:
% : foo += target
In both cases, we had basically the same configuration:
- A pattern/target definition that appends to a previous value.
- The pattern/target definition applies both to
all
andx
targets. - We had a command-line definition that is suppose to override the makefile-level definition.
Now, interpreting or implementing that override, Make uses a very different methodology, for version 1 (target definition) than version 2 (pattern definition).
Let's see:
- For target definition, Make completely ignores ANY value defined in the makefile. Hence, the final value is:
cmd
. - For pattern definition, however, Make comes up with "conciliatory" approach, trying to satisfy both, the makefile-level definition and the command-line defintion, so it:
- Accepts that the final value is
cmd
, per the command-line that overrides the makefile definition. - But, because the makefile implies that the "patterns" are supposed to "append" additional values - never mind that those same values had been overridden - Make will still "obey" those appends, but it will done with different values (i.e. the "winning" command-line value), thereby reaching a "compromise" where nor does the makefile, or the command-line have sole control over the final value of the variable.
- Accepts that the final value is
Well, these different approaches that Make takes to implement a command-line override, (per pattern vs target specific variables), is even more obvious when we expect the very different final results we get for them, respectively:
cmd
(for target-specific).cmd cmd cmd
(for pattern-specific).
Is this justified? And how so?