]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 58341] Add non-trivial options to $(MAKEFLAGS)
authorPaul Smith <psmith@gnu.org>
Mon, 19 Apr 2021 21:27:54 +0000 (17:27 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 30 May 2021 19:11:30 +0000 (15:11 -0400)
Previously only trivial (single-letter) options were available in
$(MAKEFLAGS) when it is examined from inside a makefile (the full
value was set before expanding recipes).

Ensure that all options (but, not command line variable overrides!)
are visible in the $(MAKEFLAGS) variable.  In order to do this
reset the default values of options, particularly options which are
lists, before re-reading MAKEFLAGS after makefiles have been read.
Otherwise we'll get duplicate values for options such as -I.

Unfortunately there are complications here as well: sometimes (for
jobserver options in particular) we modify the values of these
options while running: we must not reset these modifications.

* NEWS: Announce this change
* src/main.c (main): Call new reset_switches() before re-parsing
MAKEFLAGS.
(reset_switches): Reset the value of non-special options to their
defaults.
(define_makeflags): Add non-special options into MAKEFLAGS even
if 'all' is not set.

NEWS
src/main.c

diff --git a/NEWS b/NEWS
index 53562605a9706ee327166f30899f8644d4aea9e9..5efa8bad9bfc047b728a6bd302f78aa0c66bfa77 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=109&se
   rebuilt is the same order in which make processed them, and this is defined
   to be true in the GNU make manual.
 
+* WARNING: Backward-incompatibility!
+  Previously only simple (one-letter) options were added to the MAKEFLAGS
+  variable that was visible while parsing makefiles.  Now, all options
+  are available in MAKEFLAGS.
+
 * WARNING: New build requirement
   GNU make utilizes facilities from GNU Gnulib: Gnulib requires certain C99
   features in the C compiler and so these features are required by GNU make:
index d16d17a769c4fd06679973b80ee62e87cdd3b553..0f8a66dd0f3ae0358b4fdb63186ae03f3ef46e77 100644 (file)
@@ -104,6 +104,7 @@ double atof ();
 static void clean_jobserver (int status);
 static void print_data_base (void);
 static void print_version (void);
+static void reset_switches ();
 static void decode_switches (int argc, const char **argv, int env);
 static void decode_env_switches (const char *envar, size_t len);
 static struct variable *define_makeflags (int all, int makefile);
@@ -1690,10 +1691,8 @@ main (int argc, char **argv, char **envp)
         {
           /* There's no -j option on the command line: check authorization.  */
           if (jobserver_parse_auth (jobserver_auth))
-            {
-              /* Success!  Use the jobserver.  */
-              goto job_setup_complete;
-            }
+            /* Success!  Use the jobserver.  */
+            goto job_setup_complete;
 
           /* Oops: we have jobserver-auth but it's invalid :(.  */
           O (error, NILF, _("warning: jobserver unavailable: using -j1.  Add '+' to parent make rule."));
@@ -1993,6 +1992,9 @@ main (int argc, char **argv, char **envp)
     int old_builtin_variables_flag = no_builtin_variables_flag;
     int old_arg_job_slots = arg_job_slots;
 
+    /* Reset switches that are taken from MAKEFLAGS so we don't get dups.  */
+    reset_switches ();
+
     arg_job_slots = INVALID_JOB_SLOTS;
 
     /* Decode switches again, for variables set by the makefile.  */
@@ -2840,6 +2842,52 @@ print_usage (int bad)
   fprintf (usageto, _("Report bugs to <bug-make@gnu.org>\n"));
 }
 
+/* Reset switches that come from MAKEFLAGS and go to MAKEFLAGS.
+   Before re-parsing MAKEFLAGS after reading makefiles, start from scratch.  */
+
+static void
+reset_switches ()
+{
+  const struct command_switch *cs;
+
+  for (cs = switches; cs->c != '\0'; ++cs)
+    if (cs->value_ptr && cs->env && cs->toenv)
+      switch (cs->type)
+        {
+        case ignore:
+          break;
+
+        case flag:
+        case flag_off:
+          if (cs->default_value)
+            *(int *) cs->value_ptr = *(int *) cs->default_value;
+          break;
+
+        case positive_int:
+        case string:
+          /* These types are handled specially... leave them alone :(  */
+          break;
+
+        case floating:
+          if (cs->default_value)
+            *(double *) cs->value_ptr = *(double *) cs->default_value;
+          break;
+
+        case filename:
+        case strlist:
+          {
+            /* The strings are in the cache so don't free them.  */
+            struct stringlist *sl = *(struct stringlist **) cs->value_ptr;
+            if (sl)
+              sl->idx = 0;
+          }
+          break;
+
+        default:
+          abort ();
+        }
+}
+
 /* Decode switches from ARGC and ARGV.
    They came from the environment if ENV is nonzero.  */
 
@@ -3005,9 +3053,8 @@ decode_switches (int argc, const char **argv, int env)
                     coptarg = argv[optind++];
 
                   if (doit)
-                    *(double *) cs->value_ptr
-                      = (coptarg != 0 ? atof (coptarg)
-                         : *(double *) cs->noarg_value);
+                    *(double *) cs->value_ptr = (coptarg != 0 ? atof (coptarg)
+                                                 : *(double *) cs->noarg_value);
 
                   break;
                 }
@@ -3201,9 +3248,9 @@ define_makeflags (int all, int makefile)
                    && (*(unsigned int *) cs->value_ptr
                        == *(unsigned int *) cs->default_value)))
                 break;
-              else if (cs->noarg_value != 0
-                       && (*(unsigned int *) cs->value_ptr ==
-                           *(unsigned int *) cs->noarg_value))
+              if (cs->noarg_value != 0
+                  && (*(unsigned int *) cs->value_ptr ==
+                      *(unsigned int *) cs->noarg_value))
                 ADD_FLAG ("", 0); /* Optional value omitted; see below.  */
               else
                 {
@@ -3215,22 +3262,17 @@ define_makeflags (int all, int makefile)
           break;
 
         case floating:
-          if (all)
+          if (cs->default_value != 0
+              && (*(double *) cs->value_ptr == *(double *) cs->default_value))
+            break;
+          if (cs->noarg_value != 0
+              && (*(double *) cs->value_ptr == *(double *) cs->noarg_value))
+            ADD_FLAG ("", 0); /* Optional value omitted; see below.  */
+          else
             {
-              if (cs->default_value != 0
-                  && (*(double *) cs->value_ptr
-                      == *(double *) cs->default_value))
-                break;
-              else if (cs->noarg_value != 0
-                       && (*(double *) cs->value_ptr
-                           == *(double *) cs->noarg_value))
-                ADD_FLAG ("", 0); /* Optional value omitted; see below.  */
-              else
-                {
-                  char *buf = alloca (100);
-                  sprintf (buf, "%g", *(double *) cs->value_ptr);
-                  ADD_FLAG (buf, strlen (buf));
-                }
+              char *buf = alloca (100);
+              sprintf (buf, "%g", *(double *) cs->value_ptr);
+              ADD_FLAG (buf, strlen (buf));
             }
           break;
 
@@ -3245,16 +3287,15 @@ define_makeflags (int all, int makefile)
 
         case filename:
         case strlist:
-          if (all)
-            {
-              struct stringlist *sl = *(struct stringlist **) cs->value_ptr;
-              if (sl != 0)
-                {
-                  unsigned int i;
-                  for (i = 0; i < sl->idx; ++i)
-                    ADD_FLAG (sl->list[i], strlen (sl->list[i]));
-                }
-            }
+          {
+            struct stringlist *sl = *(struct stringlist **) cs->value_ptr;
+            if (sl != 0)
+              {
+                unsigned int i;
+                for (i = 0; i < sl->idx; ++i)
+                  ADD_FLAG (sl->list[i], strlen (sl->list[i]));
+              }
+          }
           break;
 
         default: