Ji Cha
Ji Cha

Reputation: 959

Command-line variables - in makefile - expand to weird values

From the docs:

Target-specific variables have the same priority as any other makefile variable. Variables provided on the command line (and in the environment if the '-e' option is in force) will take precedence. Specifying the 'override' directive will allow the target-specific variable value to be preferred.

So, a simple makefile, like:

# A pattern-specific variable assignment.
% : foo += file

all : x ;

# Target is a double-colon w/o dependencies, so Make will ALWAYS run its commands.
x ::
    @echo '$(foo)'

Running, we get:

# Override makefile-level variables, with a command-line assignment.
$ make foo=cmd
cmd cmd cmd

# Set the value in the environment, And tell Make to prefer it over any makefile-level definitions.
$ foo=env make --environment-overrides
env file file

Returning now, to the quote above, from the documentation:

Variables provided on the command line (and in the environment if the '-e' option is in force) will take precedence.

It seems, that using either:

  1. Command-line assignment.
  2. Environment-set variables, AND using -e (--environment-overrides).

Have both the same effect, i.e. overrides the file-level (makefile) variable.

But, the results differ greatly. Remember that the value given in the command-line was: cmd, and the value given in the environment was: env.

Now, compare the values, given for a command-line override vs. an environment override:

  1. cmd cmd cmd (for command-line override).
  2. env file file (for environment override).

So, whereas for command-line, Make repeats the same value, i.e. cmd, 3 times, for environment-override, the situation is different. That is, Make will "repeat" the environment-level value: env only 1 time, and then repeats - none other - than the overridden file-level value: file.

Now, not only is the situation completely different for an "override" from command-line vs. an "override" from the environment, which is strange by itself, the problem here is much bigger.

Since, Make rules to give "priority" for a command-line (or environment) value, why does it insist to append "other" values (as in the case of environment-override, where Make appends "file file"), or in the case of a command-line override (where Make repeats the same value ***3* times). Seriously?

How does it make sense at all? And what is the justification for these inconsistent and strange results?

Upvotes: 0

Views: 1289

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80931

I believe the answer here is related to the answer to this other question of yours. (And possibly a bug in the env override version.)

The global variables and the target-specific variables are distinct variables.

The cmd cmd cmd result is because when you write %: foo += file make stores that as an addition to the current value of variable foo of the target-specific value of the variable foo which is file.

However, when you set foo on the command line make overrides the value of the target-specific variable foo to be cmd instead of file. So when make concats the variable each time it gets cmd cmd cmd.

That explanation should, I think, get you env env env then and I'm not sure why it doesn't. This could be a bug or it could be some other detail about how env override variables and target-specific variable values work. I'm not sure.

(Check the output of make -p for both these cases to see what I mean about the target-specific variable's value.)

Upvotes: 2

Related Questions