things like "ifeq ((foo,bar),)" are now syntax errors. Use a variable to
hide the comma if needed: "COMMA = ," / "ifeq ((foo$(COMMA)bar),)".
+* WARNING: Backward-incompatibility!
+ If -e is given all environment variables will now have an origin of
+ "environment override" even if they are not otherwise set in the makefile.
+ See https://savannah.gnu.org/bugs/index.php?64803
+
* NOTE: Deprecated behavior.
The check in GNU Make 4.3 for suffix rules with prerequisites didn't check
single-suffix rules, only double-suffix rules. Add the missing check.
#endif
/* Initialize the special variables. */
+ define_variable_cname ("MAKEFLAGS", "", o_default, 0)->special = 1;
define_variable_cname (".VARIABLES", "", o_default, 0)->special = 1;
/* define_variable_cname (".TARGETS", "", o_default, 0)->special = 1; */
define_variable_cname (".RECIPEPREFIX", "", o_default, 0)->special = 1;
void
reset_makeflags (enum variable_origin origin)
{
+ /* Reset to default values. */
+ env_overrides = 0;
decode_env_switches (STRING_SIZE_TUPLE(MAKEFLAGS_NAME), origin);
construct_include_path (include_dirs ? include_dirs->list : NULL);
disable_builtins ();
/* Perform any special switch handling. */
run_silent = silent_flag;
+
+ /* Check variable priorities. */
+ reset_env_override ();
}
/* Decode switches from environment variable ENVAR (which is LEN chars long).
}
/* Disable builtin variables and rules, if -R or -r is specified.
- * This function is called at parse time whenever MAKEFLAGS is modified and
- * also when the parsing phase is over. */
+ This function is called at parse time whenever MAKEFLAGS is modified and
+ also when the parsing phase is over. */
static
void disable_builtins ()
verify_file_data_base ();
/* Unload plugins before jobserver integrity check in case a plugin
- * participates in jobserver. */
+ participates in jobserver. */
unload_all ();
clean_jobserver (status);
*nptr++ = '$';
}
else
- {
- *nptr++ = *sptr;
- }
+ *nptr++ = *sptr;
sptr++;
}
v->flavor = f_simple;
}
else
- {
- v = do_variable_definition (
- &p->variable.fileinfo, p->variable.name, p->variable.value,
- p->variable.origin, p->variable.flavor,
- p->variable.conditional, s_pattern);
- }
+ v = do_variable_definition (
+ &p->variable.fileinfo, p->variable.name, p->variable.value,
+ p->variable.origin, p->variable.flavor,
+ p->variable.conditional, s_pattern);
/* Also mark it as a per-target and copy export status. */
v->per_target = p->variable.per_target;
(int)len, name));
}
}
+
+static void
+set_env_override (const void *item, void *arg UNUSED)
+{
+ struct variable *v = (struct variable *)item;
+ enum variable_origin old = env_overrides ? o_env : o_env_override;
+ enum variable_origin new = env_overrides ? o_env_override : o_env;
+
+ if (v->origin == old)
+ v->origin = new;
+}
+
+void
+reset_env_override ()
+{
+ hash_map_arg (&global_variable_set.table, set_env_override, NULL);
+}
\f
/* Print information for variable V, prefixing it with PREFIX. */
}
}
-
static void
print_auto_variable (const void *item, void *arg)
{
print_variable (item, arg);
}
-
static void
print_noauto_variable (const void *item, void *arg)
{
print_variable (item, arg);
}
-
/* Print all the variables in SET. PREFIX is printed before
the actual variable definitions (everything else is comments). */
struct variable_set *set,
const floc *flocp);
void warn_undefined (const char* name, size_t length);
+void reset_env_override (void);
/* Define a variable in the current variable set. */
auto : ; @echo $(av)
for2: ; @echo $(fe)',
'-e WHITE=WHITE CFLAGS=',
- "undefined file default file environment default file command line override automatic automatic
-foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o");
+ "undefined file default file environment override default file command line override automatic automatic
+foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o override.o default.o file.o command.o line.o override.o automatic.o automatic.o");
# TEST 1: Test that foreach variables take precedence over global
# variables in a global scope (like inside an eval). Tests bug #11913
auto: ; @echo $(let $(auto_var),,$(av)) $(av)
$(let AR foo,bar foo ,$(eval $(value mktarget)))',
'-e WHITE=WHITE CFLAGS=',
- "automatic automatic automatic automatic automatic automatic automatic automatic automatic undefined default environment default file command line override automatic automatic
+ "automatic automatic automatic automatic automatic automatic automatic automatic automatic undefined default environment override default file command line override automatic automatic
ar_foo _
");
auto :
> @echo $(av)',
'-e WHITE=WHITE CFLAGS=',
- 'undefined default environment default file command line override automatic
+ 'undefined default environment override default file command line override automatic
undefined
default
-environment
+environment override
default
file
command line
'-e --no-print-directory FOO=1 recurse',
"FOO [command line]: 1\nFOO [command line]: 1\n#MAKE#[1]: 'all' is up to date.");
+# SV 64803.
+# Test that the origin of an env variable is 'enviroment override' when -e
+# is set and the makefile does not modify the variable.
+# First run the test without -e and then with -e.
+
+mkdir('lib', 0777);
+
+create_file('lib/makefile',
+'$(info in submake value=$(hello), origin=$(origin hello))
+all:; @echo "value=$(hello), origin=$(origin hello)"'."\n");
+
+# No -e.
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib
+.PHONY: lib all
+!,
+ '-s',
+ "value=world, origin=environment\nvalue=world, origin=environment\n".
+ "in submake value=world, origin=environment\nvalue=world, origin=environment");
+
+# -e is specified on the command line.
+my @opts = ('-e', '--environment-overrides');
+for my $opt (@opts) {
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib
+.PHONY: lib all
+!,
+ "-s $opt",
+ "value=world, origin=environment override\nvalue=world, origin=environment override\n".
+ "in submake value=world, origin=environment override\nvalue=world, origin=environment override");
+}
+
+# MAKEFLAGS from env affects top level make.
+$ENV{hello} = 'world';
+$ENV{MAKEFLAGS} = 'e';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib
+.PHONY: lib all
+!,
+ "-s",
+ "value=world, origin=environment override\nvalue=world, origin=environment override\n".
+ "in submake value=world, origin=environment override\nvalue=world, origin=environment override");
+
+# -e is passed to submake on the command line.
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -e -C lib
+.PHONY: lib all
+!,
+ "-s",
+ "value=world, origin=environment\nvalue=world, origin=environment\n".
+ "in submake value=world, origin=environment override\nvalue=world, origin=environment override");
+
+# MAKEFLAGS is reset for submake.
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib MAKEFLAGS=
+.PHONY: lib all
+!,
+ "-se",
+ "value=world, origin=environment override\nvalue=world, origin=environment override\n".
+ "in submake value=world, origin=environment\nvalue=world, origin=environment");
+
+# Some MAKEFLAGS in top make env.
+# This MAKEFLAGS does not conform to the format that make itself produces for
+# submake. However, make still parses and honors this MAKEFLAGS.
+# This test checks that make does not confuse 'e' in 'extramk' with '-e'.
+$ENV{MAKEFLAGS} = 'r -Iextramk -k bye=moon';
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib
+.PHONY: lib all
+!,
+ "-s",
+ "value=world, origin=environment\nvalue=world, origin=environment\n".
+ "in submake value=world, origin=environment\nvalue=world, origin=environment");
+
+# Some MAKEFLAGS in top make env.
+# This MAKEFLAGS does not conform to the format that make itself produces for
+# submake. However, make still parses and honors this MAKEFLAGS.
+# This test checks that make detects '-e' in this MAKEFLAGS.
+$ENV{MAKEFLAGS} = 'r -Iextramk -ke bye=moon';
+$ENV{hello} = 'world';
+run_make_test(q!
+.RECIPEPREFIX = >
+$(info value=$(hello), origin=$(origin hello))
+all:
+> @echo "value=$(hello), origin=$(origin hello)"
+> @$(MAKE) -C lib
+.PHONY: lib all
+!,
+ "-s",
+ "value=world, origin=environment override\nvalue=world, origin=environment override\n".
+ "in submake value=world, origin=environment override\nvalue=world, origin=environment override");
+
1;