[packages/make] upstream fix for MAKEFLAGS propagation to sub-make
atler
atler at pld-linux.org
Tue Nov 29 01:44:40 CET 2022
commit 18a7f12cdcad4aee914a925f2474b6375ca9f483
Author: Jan Palus <atler at pld-linux.org>
Date: Tue Nov 29 01:42:53 2022 +0100
upstream fix for MAKEFLAGS propagation to sub-make
see https://savannah.gnu.org/bugs/index.php?63347
make.spec | 2 +
sub-make-makeflags.patch | 865 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 867 insertions(+)
---
diff --git a/make.spec b/make.spec
index 4260fe2..6e6a6d9 100644
--- a/make.spec
+++ b/make.spec
@@ -22,6 +22,7 @@ Source0: http://ftp.gnu.org/gnu/make/%{name}-%{version}.tar.lz
Source1: http://www.mif.pg.gda.pl/homepages/ankry/man-PLD/%{name}-non-english-man-pages.tar.bz2
# Source1-md5: ab6da7a1ba3bcf9e86e4e3fdecca61a7
Patch0: %{name}-info.patch
+Patch1: sub-make-makeflags.patch
URL: http://www.gnu.org/software/make/
BuildRequires: autoconf >= 2.69
BuildRequires: automake >= 1:1.16.1
@@ -110,6 +111,7 @@ Plik nagłówkowy interfejsu modułów GNU Make'a.
%prep
%setup -q
%patch0 -p1
+%patch1 -p1
%build
%{__gettextize}
diff --git a/sub-make-makeflags.patch b/sub-make-makeflags.patch
new file mode 100644
index 0000000..5ad9599
--- /dev/null
+++ b/sub-make-makeflags.patch
@@ -0,0 +1,865 @@
+From dc2d963989b96161472b2cd38cef5d1f4851ea34 Mon Sep 17 00:00:00 2001
+From: Dmitry Goncharov <dgoncharov at users.sf.net>
+Date: Sun, 27 Nov 2022 14:09:17 -0500
+Subject: [SV 63347] Always add command line variable assignments to MAKEFLAGS
+
+This commit introduces two visible changes:
+1. Keep command line variable assignments in MAKEFLAGS at all times,
+ even while parsing makefiles.
+2. Define makeflags immediately when a makefile modifies MAKEFLAGS.
+
+The new MAKEFLAGS and MAKEOVERRIDES initialization procedure:
+1. decode_switches (argc, argv, o_command) is called to parse command
+ line variable assignments.
+2. Command line variable assignments go through quote_for_env.
+ Initialize -*-command-variables-*- to the quoted values.
+3. MAKEOVERRIDES is initialized to refer to -*-command-variables-*-
+ with origin o_env to keep the definitions in the database intact.
+4. define_makeflags() is called which adds MAKEOVERRIDES to MAKEFLAGS.
+5. Makefiles are parsed. If a makefile modifies MAKEFLAGS, the new
+ value of MAKEFLAGS is defined right away.
+6. Env switches are decoded again as o_env. The definitions set by
+ decode_switches at step 1 stay intact, as o_command beats o_env.
+
+We must preserve the original intact definitions in order to detect
+failure cases; for example:
+ $ cat makefile
+ all:; $(hello)
+ $ make hello='$(world'
+ makefile:1: *** unterminated variable reference. Stop.
+
+* src/makeint.h: Declare enum variable_origin, struct variable and
+define_makeflags(). Add parameter origin to decode_env_switches().
+* src/main.c (define_makeflags): Remove "all". If a variable is
+assigned on the command line then append MAKEOVERRIDES to MAKEFLAGS.
+(decode_env_switches): Replace parameter env with origin.
+(decode_switches): Replace parameter env with origin.
+Treat origin == o_command as env == 0.
+(handle_non_switch_argument): Replace parameter env with origin.
+Treat origin == o_command as env == 0.
+(main): Call decode_switches() with origin==o_command before parsing
+makefiles. Call decode_switches() with origin==o_env after parsing
+makefiles.
+* src/variable.c (set_special_var): Define makeflags at parse time,
+each time a makefile modifies MAKEFLAGS.
+(do_variable_definition): Strip command line variable assignments from
+MAKEFLAGS before appending extra flags. set_special_var() adds them
+back.
+* tests/scripts/variables/MAKEFLAGS: Add tests.
+---
+ src/main.c | 90 ++++++-------
+ src/makeint.h | 6 +-
+ src/variable.c | 72 ++++++----
+ tests/scripts/variables/MAKEFLAGS | 273 +++++++++++++++++++++++++++++++++-----
+ 4 files changed, 336 insertions(+), 105 deletions(-)
+
+diff --git a/src/main.c b/src/main.c
+index b31ddd4..d8a7372 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -105,8 +105,8 @@ double atof ();
+ static void clean_jobserver (int status);
+ static void print_data_base (void);
+ static void print_version (void);
+-static void decode_switches (int argc, const char **argv, int env);
+-static struct variable *define_makeflags (int all, int makefile);
++static void decode_switches (int argc, const char **argv,
++ enum variable_origin origin);
+ static char *quote_for_env (char *out, const char *in);
+ static void initialize_global_hash_tables (void);
+
+@@ -1572,13 +1572,13 @@ main (int argc, char **argv, char **envp)
+ /* Decode the switches. */
+ if (lookup_variable (STRING_SIZE_TUPLE (GNUMAKEFLAGS_NAME)))
+ {
+- decode_env_switches (STRING_SIZE_TUPLE (GNUMAKEFLAGS_NAME));
++ decode_env_switches (STRING_SIZE_TUPLE (GNUMAKEFLAGS_NAME), o_command);
+
+ /* Clear GNUMAKEFLAGS to avoid duplication. */
+ define_variable_cname (GNUMAKEFLAGS_NAME, "", o_env, 0);
+ }
+
+- decode_env_switches (STRING_SIZE_TUPLE (MAKEFLAGS_NAME));
++ decode_env_switches (STRING_SIZE_TUPLE (MAKEFLAGS_NAME), o_command);
+
+ #if 0
+ /* People write things like:
+@@ -1599,7 +1599,7 @@ main (int argc, char **argv, char **envp)
+ int env_slots = arg_job_slots;
+ arg_job_slots = INVALID_JOB_SLOTS;
+
+- decode_switches (argc, (const char **)argv, 0);
++ decode_switches (argc, (const char **)argv, o_command);
+ argv_slots = arg_job_slots;
+
+ if (arg_job_slots == INVALID_JOB_SLOTS)
+@@ -2022,7 +2022,7 @@ main (int argc, char **argv, char **envp)
+
+ /* Set up the MAKEFLAGS and MFLAGS variables for makefiles to see.
+ Initialize it to be exported but allow the makefile to reset it. */
+- define_makeflags (0, 0)->export = v_export;
++ define_makeflags (0)->export = v_export;
+
+ /* Define the default variables. */
+ define_default_variables ();
+@@ -2072,12 +2072,12 @@ main (int argc, char **argv, char **envp)
+ arg_job_slots = INVALID_JOB_SLOTS;
+
+ /* Decode switches again, for variables set by the makefile. */
+- decode_env_switches (STRING_SIZE_TUPLE (GNUMAKEFLAGS_NAME));
++ decode_env_switches (STRING_SIZE_TUPLE (GNUMAKEFLAGS_NAME), o_env);
+
+ /* Clear GNUMAKEFLAGS to avoid duplication. */
+ define_variable_cname (GNUMAKEFLAGS_NAME, "", o_override, 0);
+
+- decode_env_switches (STRING_SIZE_TUPLE (MAKEFLAGS_NAME));
++ decode_env_switches (STRING_SIZE_TUPLE (MAKEFLAGS_NAME), o_env);
+ #if 0
+ decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS"));
+ #endif
+@@ -2260,7 +2260,7 @@ main (int argc, char **argv, char **envp)
+
+ /* Set up MAKEFLAGS and MFLAGS again, so they will be right. */
+
+- define_makeflags (1, 0);
++ define_makeflags (0);
+
+ /* Make each 'struct goaldep' point at the 'struct file' for the file
+ depended on. Also do magic for special targets. */
+@@ -2420,7 +2420,7 @@ main (int argc, char **argv, char **envp)
+ }
+
+ /* Set up 'MAKEFLAGS' specially while remaking makefiles. */
+- define_makeflags (1, 1);
++ define_makeflags (1);
+
+ {
+ int orig_db_level = db_level;
+@@ -2812,7 +2812,7 @@ main (int argc, char **argv, char **envp)
+ }
+
+ /* Set up 'MAKEFLAGS' again for the normal targets. */
+- define_makeflags (1, 0);
++ define_makeflags (0);
+
+ /* Set always_make_flag if -B was given. */
+ always_make_flag = always_make_set;
+@@ -3000,7 +3000,7 @@ init_switches (void)
+
+ /* Non-option argument. It might be a variable definition. */
+ static void
+-handle_non_switch_argument (const char *arg, int env)
++handle_non_switch_argument (const char *arg, enum variable_origin origin)
+ {
+ struct variable *v;
+
+@@ -3033,7 +3033,7 @@ handle_non_switch_argument (const char *arg, int env)
+ }
+ }
+ #endif
+- v = try_variable_definition (0, arg, o_command, 0);
++ v = try_variable_definition (0, arg, origin, 0);
+ if (v != 0)
+ {
+ /* It is indeed a variable definition. If we don't already have this
+@@ -3053,11 +3053,12 @@ handle_non_switch_argument (const char *arg, int env)
+ command_variables = cv;
+ }
+ }
+- else if (! env)
++ else if (arg[0] != '\0' && origin == o_command)
+ {
+- /* Not an option or variable definition; it must be a goal
+- target! Enter it as a file and add it to the dep chain of
+- goals. */
++ /* Not an option or variable definition; it must be a goal target.
++ Enter it as a file and add it to the dep chain of goals.
++ Check ARG[0] because if the top makefile resets MAKEOVERRIDES
++ then ARG points to an empty string in the submake. */
+ struct file *f = enter_file (strcache_add (expand_command_line_file (arg)));
+ f->cmd_target = 1;
+
+@@ -3105,7 +3106,7 @@ handle_non_switch_argument (const char *arg, int env)
+ They came from the environment if ENV is nonzero. */
+
+ static void
+-decode_switches (int argc, const char **argv, int env)
++decode_switches (int argc, const char **argv, enum variable_origin origin)
+ {
+ int bad = 0;
+ const struct command_switch *cs;
+@@ -3119,7 +3120,7 @@ decode_switches (int argc, const char **argv, int env)
+
+ /* Let getopt produce error messages for the command line,
+ but not for options from the environment. */
+- opterr = !env;
++ opterr = origin == o_command;
+ /* Reset getopt's state. */
+ optind = 0;
+
+@@ -3135,7 +3136,7 @@ decode_switches (int argc, const char **argv, int env)
+ break;
+ else if (c == 1)
+ /* An argument not starting with a dash. */
+- handle_non_switch_argument (coptarg, env);
++ handle_non_switch_argument (coptarg, origin);
+ else if (c == '?')
+ /* Bad option. We will print a usage message and die later.
+ But continue to parse the other options so the user can
+@@ -3149,7 +3150,7 @@ decode_switches (int argc, const char **argv, int env)
+ this switch. We test this individually inside the
+ switch below rather than just once outside it, so that
+ options which are to be ignored still consume args. */
+- int doit = !env || cs->env;
++ int doit = origin == o_command || cs->env;
+
+ switch (cs->type)
+ {
+@@ -3299,9 +3300,9 @@ decode_switches (int argc, const char **argv, int env)
+ to be returned in order, this only happens when there is a "--"
+ argument to prevent later arguments from being options. */
+ while (optind < argc)
+- handle_non_switch_argument (argv[optind++], env);
++ handle_non_switch_argument (argv[optind++], origin);
+
+- if (bad && !env)
++ if (bad && origin == o_command)
+ print_usage (bad);
+
+ /* If there are any options that need to be decoded do it now. */
+@@ -3321,7 +3322,7 @@ decode_switches (int argc, const char **argv, int env)
+ decode_switches. */
+
+ void
+-decode_env_switches (const char *envar, size_t len)
++decode_env_switches (const char *envar, size_t len, enum variable_origin origin)
+ {
+ char *varref = alloca (2 + len + 2);
+ char *value, *p, *buf;
+@@ -3383,7 +3384,7 @@ decode_env_switches (const char *envar, size_t len)
+ argv[1] = buf;
+
+ /* Parse those words. */
+- decode_switches (argc, argv, 1);
++ decode_switches (argc, argv, origin);
+ }
+
+ /* Quote the string IN so that it will be interpreted as a single word with
+@@ -3408,11 +3409,11 @@ quote_for_env (char *out, const char *in)
+ }
+
+ /* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the
+- command switches. Include options with args if ALL is nonzero.
++ command switches. Always include options with args.
+ Don't include options with the 'no_makefile' flag set if MAKEFILE. */
+
+-static struct variable *
+-define_makeflags (int all, int makefile)
++struct variable *
++define_makeflags (int makefile)
+ {
+ const char ref[] = "MAKEOVERRIDES";
+ const char posixref[] = "-*-command-variables-*-";
+@@ -3597,25 +3598,24 @@ define_makeflags (int all, int makefile)
+ p = mempcpy (p, evalref, CSTRLEN (evalref));
+ }
+
+- if (all)
+- {
+- /* If there are any overrides to add, write a reference to
+- $(MAKEOVERRIDES), which contains command-line variable definitions.
+- Separate the variables from the switches with a "--" arg. */
++ {
++ /* If there are any overrides to add, write a reference to
++ $(MAKEOVERRIDES), which contains command-line variable definitions.
++ Separate the variables from the switches with a "--" arg. */
+
+- const char *r = posix_pedantic ? posixref : ref;
+- size_t l = strlen (r);
+- v = lookup_variable (r, l);
++ const char *r = posix_pedantic ? posixref : ref;
++ size_t l = strlen (r);
++ v = lookup_variable (r, l);
+
+- if (v && v->value && v->value[0] != '\0')
+- {
+- p = stpcpy (p, " -- ");
+- *(p++) = '$';
+- *(p++) = '(';
+- p = mempcpy (p, r, l);
+- *(p++) = ')';
+- }
+- }
++ if (v && v->value && v->value[0] != '\0')
++ {
++ p = stpcpy (p, " -- ");
++ *(p++) = '$';
++ *(p++) = '(';
++ p = mempcpy (p, r, l);
++ *(p++) = ')';
++ }
++ }
+
+ /* If there is a leading dash, omit it. */
+ if (flagstring[0] == '-')
+diff --git a/src/makeint.h b/src/makeint.h
+index c726abe..d6ac21b 100644
+--- a/src/makeint.h
++++ b/src/makeint.h
+@@ -558,7 +558,11 @@ void out_of_memory (void) NORETURN;
+ #define ONS(_t,_a,_f,_n,_s) _t((_a), INTSTR_LENGTH + strlen (_s), \
+ (_f), (_n), (_s))
+
+-void decode_env_switches (const char*, size_t line);
++enum variable_origin;
++void decode_env_switches (const char*, size_t line,
++ enum variable_origin origin);
++struct variable;
++struct variable *define_makeflags (int makefile);
+ void temp_stdin_unlink (void);
+ void die (int) NORETURN;
+ void pfatal_with_name (const char *) NORETURN;
+diff --git a/src/variable.c b/src/variable.c
+index 0bd9963..d8bf428 100644
+--- a/src/variable.c
++++ b/src/variable.c
+@@ -1215,7 +1215,7 @@ target_environment (struct file *file, int recursive)
+ }
+
+ static struct variable *
+-set_special_var (struct variable *var)
++set_special_var (struct variable *var, enum variable_origin origin)
+ {
+ if (streq (var->name, RECIPEPREFIX_NAME))
+ {
+@@ -1225,7 +1225,10 @@ set_special_var (struct variable *var)
+ cmd_prefix = var->value[0]=='\0' ? RECIPEPREFIX_DEFAULT : var->value[0];
+ }
+ else if (streq (var->name, MAKEFLAGS_NAME))
+- decode_env_switches (STRING_SIZE_TUPLE(MAKEFLAGS_NAME));
++ {
++ decode_env_switches (STRING_SIZE_TUPLE(MAKEFLAGS_NAME), origin);
++ define_makeflags (rebuilding_makefiles);
++ }
+
+ return var;
+ }
+@@ -1261,7 +1264,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+ const char *value, enum variable_origin origin,
+ enum variable_flavor flavor, int target_var)
+ {
+- const char *p;
++ const char *newval;
+ char *alloc_value = NULL;
+ struct variable *v;
+ int append = 0;
+@@ -1276,7 +1279,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+ We have to allocate memory since otherwise it'll clobber the
+ variable buffer, and we may still need that if we're looking at a
+ target-specific variable. */
+- p = alloc_value = allocated_variable_expand (value);
++ newval = alloc_value = allocated_variable_expand (value);
+ break;
+ case f_expand:
+ {
+@@ -1285,16 +1288,16 @@ do_variable_definition (const floc *flocp, const char *varname,
+ tokens to '$$' to resolve to '$' when recursively expanded. */
+ char *t = allocated_variable_expand (value);
+ char *np = alloc_value = xmalloc (strlen (t) * 2 + 1);
+- p = t;
+- while (p[0] != '\0')
++ char *op = t;
++ while (op[0] != '\0')
+ {
+- if (p[0] == '$')
++ if (op[0] == '$')
+ *(np++) = '$';
+- *(np++) = *(p++);
++ *(np++) = *(op++);
+ }
+ *np = '\0';
+- p = alloc_value;
+ free (t);
++ newval = alloc_value;
+ break;
+ }
+ case f_shell:
+@@ -1302,9 +1305,10 @@ do_variable_definition (const floc *flocp, const char *varname,
+ /* A shell definition "var != value". Expand value, pass it to
+ the shell, and store the result in recursively-expanded var. */
+ char *q = allocated_variable_expand (value);
+- p = alloc_value = shell_result (q);
++ alloc_value = shell_result (q);
+ free (q);
+ flavor = f_recursive;
++ newval = alloc_value;
+ break;
+ }
+ case f_conditional:
+@@ -1320,7 +1324,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+ case f_recursive:
+ /* A recursive variable definition "var = value".
+ The value is used verbatim. */
+- p = value;
++ newval = value;
+ break;
+ case f_append:
+ case f_append_value:
+@@ -1345,15 +1349,16 @@ do_variable_definition (const floc *flocp, const char *varname,
+ {
+ /* There was no old value.
+ This becomes a normal recursive definition. */
+- p = value;
++ newval = value;
+ flavor = f_recursive;
+ }
+ else
+ {
+ /* Paste the old and new values together in VALUE. */
+
+- size_t oldlen, vallen;
++ size_t oldlen, vallen, alloclen;
+ const char *val;
++ char *cp;
+ char *tp = NULL;
+
+ val = value;
+@@ -1378,18 +1383,25 @@ do_variable_definition (const floc *flocp, const char *varname,
+ }
+
+ oldlen = strlen (v->value);
+- p = alloc_value = xmalloc (oldlen + 1 + vallen + 1);
++ alloclen = oldlen + 1 + vallen + 1;
++ cp = alloc_value = xmalloc (alloclen);
+
+ if (oldlen)
+ {
+- memcpy (alloc_value, v->value, oldlen);
+- alloc_value[oldlen] = ' ';
+- ++oldlen;
++ char *s;
++ if (streq (varname, MAKEFLAGS_NAME)
++ && (s = strstr (v->value, " -- ")))
++ /* We found a separator in MAKEFLAGS. Ignore variable
++ assignments: set_special_var() will reconstruct things. */
++ cp = mempcpy (cp, v->value, s - v->value);
++ else
++ cp = mempcpy (cp, v->value, oldlen);
++ *(cp++) = ' ';
+ }
+
+- memcpy (&alloc_value[oldlen], val, vallen + 1);
+-
++ memcpy (cp, val, vallen + 1);
+ free (tp);
++ newval = alloc_value;
+ }
+ }
+ break;
+@@ -1399,6 +1411,8 @@ do_variable_definition (const floc *flocp, const char *varname,
+ abort ();
+ }
+
++ assert (newval);
++
+ #ifdef __MSDOS__
+ /* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but
+ non-Unix systems don't conform to this default configuration (in
+@@ -1440,16 +1454,16 @@ do_variable_definition (const floc *flocp, const char *varname,
+ char *fake_env[2];
+ size_t pathlen = 0;
+
+- shellbase = strrchr (p, '/');
+- bslash = strrchr (p, '\\');
++ shellbase = strrchr (newval, '/');
++ bslash = strrchr (newval, '\\');
+ if (!shellbase || bslash > shellbase)
+ shellbase = bslash;
+- if (!shellbase && p[1] == ':')
+- shellbase = p + 1;
++ if (!shellbase && newval[1] == ':')
++ shellbase = newval + 1;
+ if (shellbase)
+ shellbase++;
+ else
+- shellbase = p;
++ shellbase = newval;
+
+ /* Search for the basename of the shell (with standard
+ executable extensions) along the $PATH. */
+@@ -1490,7 +1504,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+ set no_default_sh_exe to indicate sh was found and
+ set new value for SHELL variable. */
+
+- if (find_and_set_default_shell (p))
++ if (find_and_set_default_shell (newval))
+ {
+ v = define_variable_in_set (varname, strlen (varname), default_shell,
+ origin, flavor == f_recursive,
+@@ -1504,11 +1518,11 @@ do_variable_definition (const floc *flocp, const char *varname,
+ {
+ char *tp = alloc_value;
+
+- alloc_value = allocated_variable_expand (p);
++ alloc_value = allocated_variable_expand (newval);
+
+ if (find_and_set_default_shell (alloc_value))
+ {
+- v = define_variable_in_set (varname, strlen (varname), p,
++ v = define_variable_in_set (varname, strlen (varname), newval,
+ origin, flavor == f_recursive,
+ (target_var
+ ? current_variable_set_list->set
+@@ -1536,7 +1550,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+ invoked in places where we want to define globally visible variables,
+ make sure we define this variable in the global set. */
+
+- v = define_variable_in_set (varname, strlen (varname), p, origin,
++ v = define_variable_in_set (varname, strlen (varname), newval, origin,
+ flavor == f_recursive || flavor == f_expand,
+ (target_var
+ ? current_variable_set_list->set : NULL),
+@@ -1546,7 +1560,7 @@ do_variable_definition (const floc *flocp, const char *varname,
+
+ done:
+ free (alloc_value);
+- return v->special ? set_special_var (v) : v;
++ return v->special ? set_special_var (v, origin) : v;
+ }
+
+ /* Parse P (a null-terminated string) as a variable definition.
+diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS
+index a41f1cf..e81c327 100644
+--- a/tests/scripts/variables/MAKEFLAGS
++++ b/tests/scripts/variables/MAKEFLAGS
+@@ -65,79 +65,113 @@ rmdir('bar');
+ # Test that command line switches are all present in MAKEFLAGS.
+ # sv 62514.
+ my @opts;
++my @flavors;
+
+ # Simple flags.
+ @opts = ('i', 'k', 'n', 'q', 'r', 's', 'w', 'd');
+ exists $FEATURES{'check-symlink'} and push @opts, 'L';
++ at flavors = ('=', ':=', ':::=', '+=-');
+
++for my $fl (@flavors) {
+ for my $opt (@opts) {
+- run_make_test(q!
+-MAKEFLAGS:=B
+-all:; $(info makeflags='$(MAKEFLAGS)')
+-!, "-$opt", "/makeflags='B$opt'/");
++ run_make_test("
++MAKEFLAGS${fl}B
++all:; \$(info makeflags='\$(MAKEFLAGS)')
++", "-$opt", "/makeflags='B$opt'/");
++}
+ }
+
+ # Switches which carry arguments.
+ @opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
++for my $fl (@flavors) {
+ for my $opt (@opts) {
+- run_make_test(q!
+-MAKEFLAGS:=B
+-all:; $(info makeflags='$(MAKEFLAGS)')
+-!, "$opt", "/makeflags='B$opt'/");
++ run_make_test("
++MAKEFLAGS${fl}B
++all:; \$(info makeflags='\$(MAKEFLAGS)')
++", "$opt", "/makeflags='B$opt'/");
++}
+ }
+
+ # Long options which take no arguments.
+ # sv 62514.
+ @opts = (' --no-print-directory', ' --warn-undefined-variables', ' --trace');
++for my $fl (@flavors) {
+ for my $opt (@opts) {
+-run_make_test(q!
+-MAKEFLAGS:=B
+-all:; $(info makeflags='$(MAKEFLAGS)')
+-!, "$opt", "/makeflags='B$opt'/");
++run_make_test("
++MAKEFLAGS${fl}B
++all:; \$(info makeflags='\$(MAKEFLAGS)')
++", "$opt", "/makeflags='B$opt'/");
++}
+ }
+
+ # Test that make filters out duplicates.
+ # Each option is specified in the makefile, env and on the command line.
+ @opts = (' -I/tmp', ' -Onone', ' --debug=b', ' -l2.5');
+-$ENV{'MAKEFLAGS'} = $opt;
++for my $fl (@flavors) {
+ for my $opt (@opts) {
++$ENV{'MAKEFLAGS'} = $opt;
+ run_make_test("
+-MAKEFLAGS:=B $opt
++MAKEFLAGS${fl}B $opt
+ all:; \$(info makeflags='\$(MAKEFLAGS)')
+ ", "$opt", "/makeflags='B$opt'/");
+ }
++}
+
+ # Test that make filters out duplicates.
+ # Each option is specified in the makefile, env and on the command line.
+ # decode_switches reallocates when the number of parameters in sl->list exceeds 5.
+ # This test exercises the realloc branch.
++for my $fl (@flavors) {
+ $ENV{'MAKEFLAGS'} = '-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2';
+-run_make_test(q!
+-MAKEFLAGS:=B -I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2
+-all:; $(info makeflags='$(MAKEFLAGS)')
+-!,
++run_make_test("
++MAKEFLAGS${fl}B -I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6 -I2 -I2
++all:; \$(info makeflags='\$(MAKEFLAGS)')
++",
+ '-I1 -Onone --debug=b -l2.5 -I2 -I3 -I4 -I5 -I6',
+ "/makeflags='B -I1 -I2 -I3 -I4 -I5 -I6 -l2.5 -Onone --debug=b'/");
++}
+
+ # A mix of multiple flags from env, the makefile and command line.
+ # Skip -L since it's not available everywhere
++for my $fl (@flavors) {
+ $ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables --trace';
+-run_make_test(q!
+-MAKEFLAGS:=iknqrswd -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5
+-all:; $(info makeflags='$(MAKEFLAGS)')
+-!,
++run_make_test("
++MAKEFLAGS${fl}iknqrswd -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5
++all:; \$(info makeflags='\$(MAKEFLAGS)')
++",
+ '-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrswd -i -n -s -k -I/tmp',
+ "/makeflags='Bdiknqrsw -I/tmp -l2.5 -Onone --trace --warn-undefined-variables'/");
++}
+
+-# Verify MAKEFLAGS are all available to shell functions
++# Verify MAKEFLAGS are all available to shell function at parse time.
++for my $fl (@flavors) {
++my $answer = 'Biknqrs -I/tmp -l2.5 -Onone --no-print-directory --warn-undefined-variables';
+ $ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables';
+-run_make_test(q!
+-MAKEFLAGS := iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory
+-XX := $(shell echo "$$MAKEFLAGS")
+-all:; $(info makeflags='$(XX)')
+-!,
+- '-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrs -i -n -s -k -I/tmp',
+- "makeflags='iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory'");
++run_make_test("
++MAKEFLAGS${fl}iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory
++\$(info at parse time '\$(MAKEFLAGS)')
++XX := \$(shell echo \"\$\$MAKEFLAGS\")
++all:; \$(info at build time makeflags='\$(XX)')
++",
++'-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrs -i -n -s -k -I/tmp',
++"at parse time '$answer'
++at build time makeflags='$answer'");
++}
++
++# Verify MAKEFLAGS and command line definitions are all available to shell function at parse time.
++for my $fl (@flavors) {
++$ENV{'MAKEFLAGS'} = 'ikB --no-print-directory --warn-undefined-variables';
++my $answer = 'Biknqrs -I/tmp -l2.5 -Onone --no-print-directory --warn-undefined-variables -- hello=world';
++run_make_test("
++MAKEFLAGS${fl}iknqrsw -I/tmp -I/tmp -Onone -Onone -l2.5 -l2.5 --no-print-directory
++\$(info at parse time '\$(MAKEFLAGS)')
++XX := \$(shell echo \"\$\$MAKEFLAGS\")
++all:; \$(info at build time makeflags='\$(XX)')
++",
++'-Onone -l2.5 -l2.5 -Onone -I/tmp -iknqrs -i -n -s -k -I/tmp hello=world',
++"at parse time '$answer'
++at build time makeflags='$answer'");
++}
+
+ # Verify that command line arguments are included in MAKEFLAGS
+ run_make_test(q!
+@@ -155,4 +189,183 @@ echo /erR --trace --no-print-directory -- FOO=bar/
+ /erR --trace --no-print-directory -- FOO=bar/");
+
+
++# sv 63347.
++# Verify that command line arguments are included in MAKEFLAGS
++# when makefiles are parsed.
++my $answer = 'erR -- hello:=world FOO=bar';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, '-e FOO=bar -r -R hello:=world',
++"$answer
++$answer
++#MAKE#: 'all' is up to date.\n");
++
++# sv 63347.
++# Same as above, with makefile setting the value of the same variables as
++# defined on the cli.
++my $answer = 'erR -- hello:=world FOO=bar';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++FOO=moon
++hello:=moon
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, '-e FOO=bar -r -R hello:=world',
++"$answer
++$answer
++$answer
++#MAKE#: 'all' is up to date.\n");
++
++# sv 63347.
++# Same as above, with makefile overriding the value of cli definition.
++my $answer = 'erR -- hello:=world FOO=bar';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++override FOO=moon
++override hello:=moon
++export hello
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, '-e FOO=bar -r -R hello:=world',
++"$answer
++$answer
++$answer
++#MAKE#: 'all' is up to date.\n");
++
++# Same as above, and makefile overrides the value of cli definition.
++# resets MAKEOVERRIDES.
++my $answer = 'rR -- hello:=world FOO=bar';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++override FOO=moon
++override hello:=moon
++export hello
++$(info $(MAKEFLAGS))
++MAKEOVERRIDES=
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, 'FOO=bar -r -R hello:=world',
++"$answer
++$answer
++rR -- \nrR
++#MAKE#: 'all' is up to date.\n");
++
++# sv 63347.
++# MAKEFLAGS set is env and makefile sets MAKEFLAGS and there is a command
++# line definition.
++my $answer = ' -- bye=moon hello=world';
++$ENV{'MAKEFLAGS'} = 'hello=world';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, 'bye=moon',
++" -- bye=moon hello=world
++ -- bye=moon hello=world
++#MAKE#: 'all' is up to date.\n");
++
++# sv 63347.
++# Conditional assignment and MAKEFLAGS.
++my $answer = 'B -- bye=moon hello=world';
++$ENV{'MAKEFLAGS'} = 'hello=world';
++run_make_test(q!
++$(info $(MAKEFLAGS))
++MAKEFLAGS?=-k
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, '-B bye=moon',
++"$answer
++$answer
++$answer
++#MAKE#: 'all' is up to date.\n");
++
++# sv 63347.
++# MAKEFLAGS set is env and makefile sets MAKEFLAGS and there is a command
++# line definition.
++for my $fl (@flavors) {
++my $answer = ' -- bye=moon hello=world';
++$ENV{'MAKEFLAGS'} = 'hello=world';
++run_make_test("
++\$(info \$(MAKEFLAGS))
++MAKEFLAGS${fl}R
++\$(info \$(MAKEFLAGS))
++all:; \$(info \$(MAKEFLAGS))
++", 'bye=moon',
++"$answer
++R$answer
++rR$answer
++#MAKE#: 'all' is up to date.\n");
++}
++
++# sv 63347.
++# Test changes introduced by makefiles to MAKEFLAGS.
++for my $fl (@flavors) {
++my $answer = 'rR --no-print-directory -- hello:=world FOO=bar';
++run_make_test(q!
++MAKEFLAGS+=--no-print-directory
++$(info $(MAKEFLAGS))
++MAKEFLAGS+=-k
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, 'FOO=bar -r -R hello:=world',
++"$answer
++k$answer
++k$answer
++#MAKE#: 'all' is up to date.\n");
++}
++
++# sv 63347.
++# Test changes introduced by makefiles to MAKEFLAGS.
++# Same as above, but with -e.
++for my $fl (@flavors) {
++my $answer = 'erR -- hello:=world FOO=bar';
++run_make_test(q!
++MAKEFLAGS+=--no-print-directory
++$(info $(MAKEFLAGS))
++MAKEFLAGS+=-k
++$(info $(MAKEFLAGS))
++all:; $(info $(MAKEFLAGS))
++!, '-e FOO=bar -r -R hello:=world',
++"$answer
++$answer
++$answer
++#MAKE#: 'all' is up to date.\n");
++}
++
++mkdir('bye', 0777);
++
++create_file('bye/makefile',
++'hello=moon
++all:; $(info $(hello))');
++
++# sv 63347.
++# Test that a cli definition takes precendence over a definition set in
++# submake.
++run_make_test(q!
++v:=$(shell $(MAKE) -C bye --no-print-directory)
++all: ; $(info $(v))
++!, 'hello=world', "world #MAKE#[1]: 'all' is up to date.\n#MAKE#: 'all' is up to date.");
++
++# Same as above with the shell assignment operator.
++run_make_test(q!
++v \!= $(MAKE) -C bye --no-print-directory
++all: ; $(info $(v))
++!, 'hello=world', "world #MAKE#[1]: 'all' is up to date.\n#MAKE#: 'all' is up to date.");
++
++unlink('bye/makefile');
++rmdir('bye');
++
++# sv 63347
++# Invalid command line variable definition.
++run_make_test(q!
++all:; $(info $(hello))
++!, 'hello=\'$(world\'', "#MAKEFILE#:2: *** unterminated variable reference. Stop.\n", 512);
++
++# sv 63347
++# An unused invalid command line variable definition is ignored.
++run_make_test(q!
++all:; $(info good)
++!, 'hello=\'$(world\'', "good\n#MAKE#: 'all' is up to date.\n");
++
++
+ 1;
+--
+cgit v1.1
+
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/make.git/commitdiff/18a7f12cdcad4aee914a925f2474b6375ca9f483
More information about the pld-cvs-commit
mailing list