mirror of
https://github.com/mirror/make.git
synced 2025-03-11 02:00:35 +08:00
[SV 61463] Don't export inherited private variables
If a parent target has an exported variable that is private, don't export it in child targets. * NEWS: Mention this change. * src/variable.c (target_environment): Ignore private inherited variables. * tests/thelp.pl: Add a new "env" operation to show env.var. values. * tests/scripts/variables/private: Verify this new behavior.
This commit is contained in:
parent
f91b8bbb34
commit
8791d2b38e
7
NEWS
7
NEWS
@ -17,13 +17,18 @@ A complete list of bugs fixed in this version is available here:
|
||||
https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=110&set=custom
|
||||
|
||||
* WARNING: Backward-incompatibility!
|
||||
In previous releases is was not well-defined when updates to MAKEFLAGS made
|
||||
In previous releases it was not well-defined when updates to MAKEFLAGS made
|
||||
inside a makefile would be visible. This release ensures they are visible
|
||||
immediately, even when invoking $(shell ...) functions. Also, command line
|
||||
variable assignments are now always present in MAKEFLAGS, even when parsing
|
||||
makefiles.
|
||||
Implementation provided by Dmitry Goncharov <dgoncharov@users.sf.net>
|
||||
|
||||
* Previously target-specific variables would inherit their "export" capability
|
||||
from parent target-specific variables even if they were marked private. Now
|
||||
private parent target-specific variables have no affect. For more details
|
||||
see https://savannah.gnu.org/bugs/index.php?61463
|
||||
|
||||
|
||||
Version 4.4 (31 Oct 2022)
|
||||
|
||||
|
@ -472,7 +472,7 @@ lookup_variable (const char *name, size_t length)
|
||||
const struct variable_set *set = setlist->set;
|
||||
struct variable *v;
|
||||
|
||||
v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
|
||||
v = hash_find_item ((struct hash_table *) &set->table, &var_key);
|
||||
if (v && (!is_parent || !v->private_var))
|
||||
return v->special ? lookup_special_var (v) : v;
|
||||
|
||||
@ -553,7 +553,7 @@ lookup_variable_in_set (const char *name, size_t length,
|
||||
var_key.name = (char *) name;
|
||||
var_key.length = (unsigned int) length;
|
||||
|
||||
return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
|
||||
return hash_find_item ((struct hash_table *) &set->table, &var_key);
|
||||
}
|
||||
|
||||
/* Initialize FILE's variable set list. If FILE already has a variable set
|
||||
@ -1065,7 +1065,8 @@ target_environment (struct file *file, int recursive)
|
||||
for (s = set_list; s != 0; s = s->next)
|
||||
{
|
||||
struct variable_set *set = s->set;
|
||||
int isglobal = set == &global_variable_set;
|
||||
const int islocal = s == set_list;
|
||||
const int isglobal = set == &global_variable_set;
|
||||
|
||||
v_slot = (struct variable **) set->table.ht_vec;
|
||||
v_end = v_slot + set->table.ht_size;
|
||||
@ -1075,11 +1076,17 @@ target_environment (struct file *file, int recursive)
|
||||
struct variable **evslot;
|
||||
struct variable *v = *v_slot;
|
||||
|
||||
if (!islocal && v->private_var)
|
||||
continue;
|
||||
|
||||
evslot = (struct variable **) hash_find_slot (&table, v);
|
||||
|
||||
if (HASH_VACANT (*evslot))
|
||||
{
|
||||
/* If we're not global, or we are and should export, add it. */
|
||||
/* We'll always add target-specific variables, since we may
|
||||
discover that they should be exported later: we'll check
|
||||
again below. For global variables only add them if they're
|
||||
exportable. */
|
||||
if (!isglobal || should_export (v))
|
||||
hash_insert_at (&table, v, evslot);
|
||||
}
|
||||
|
@ -47,6 +47,17 @@ a: b
|
||||
',
|
||||
'', "b: F=b / G=g\na: F= / G=g\n");
|
||||
|
||||
# Exported private global variables
|
||||
run_make_test('
|
||||
private export F = global
|
||||
$(info $(shell #HELPER# env F))
|
||||
a: b
|
||||
b: export F=b
|
||||
a b: ; @#HELPER# raw $@ env F
|
||||
',
|
||||
'', "F=global\nbF=b\naF=<unset>");
|
||||
|
||||
|
||||
# 5: Multiple conditions on the same variable. Test export.
|
||||
delete $ENV{'_X'};
|
||||
&run_make_test('
|
||||
@ -119,4 +130,48 @@ bar: IA=global b% bar
|
||||
bar: PA=global b% bar
|
||||
bar: PS=bar\n");
|
||||
|
||||
# SV 61463: Private parent variables should not be exported
|
||||
|
||||
run_make_test(q!
|
||||
a: private export FOO := a
|
||||
a: b
|
||||
b: ; @#HELPER# env FOO
|
||||
!,
|
||||
'', 'FOO=<unset>');
|
||||
|
||||
run_make_test(q!
|
||||
a: private export FOO := a
|
||||
a: b
|
||||
b: FOO := b
|
||||
b: ; @#HELPER# env FOO
|
||||
!,
|
||||
'', 'FOO=<unset>');
|
||||
|
||||
run_make_test(q!
|
||||
export FOO := g
|
||||
a: private export FOO := a
|
||||
a: b
|
||||
b:
|
||||
b: ; @#HELPER# env FOO
|
||||
!,
|
||||
'', 'FOO=g');
|
||||
|
||||
run_make_test(q!
|
||||
export FOO := g
|
||||
a: private export FOO := a
|
||||
a: b
|
||||
b: FOO := b
|
||||
b: ; @#HELPER# env FOO
|
||||
!,
|
||||
'', 'FOO=b');
|
||||
|
||||
run_make_test(q!
|
||||
private export FOO := g
|
||||
a: private export FOO := a
|
||||
a: b
|
||||
b: FOO := b
|
||||
b: ; @#HELPER# env FOO
|
||||
!,
|
||||
'', 'FOO=<unset>');
|
||||
|
||||
1;
|
||||
|
@ -10,6 +10,7 @@
|
||||
# It supports the following operators:
|
||||
# out <word> : echo <word> to stdout with a newline
|
||||
# raw <word> : echo <word> to stdout without adding anything
|
||||
# env <word> : echo the value of the env.var. <word>, or "<unset>"
|
||||
# file <word> : echo <word> to stdout AND create the file <word>
|
||||
# dir <word> : echo <word> to stdout AND create the directory <word>
|
||||
# rm <word> : echo <word> to stdout AND delete the file/directory <word>
|
||||
@ -19,7 +20,7 @@
|
||||
# term <pid> : send SIGTERM to PID <pid>
|
||||
# fail <err> : echo <err> to stdout then exit with error code err
|
||||
#
|
||||
# If given -q only the "out" command generates output.
|
||||
# If given -q only the "out", "raw", and "env" commands generate output.
|
||||
|
||||
# Force flush
|
||||
$| = 1;
|
||||
@ -41,6 +42,16 @@ sub op {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($op eq 'env') {
|
||||
print "$nm=" unless $quiet;
|
||||
if (exists $ENV{$nm}) {
|
||||
print "$ENV{$nm}\n";
|
||||
} else {
|
||||
print "<unset>\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Show the output before creating the file
|
||||
if ($op eq 'file') {
|
||||
print "file $nm\n" unless $quiet;
|
||||
|
Loading…
Reference in New Issue
Block a user