* Many cleanups and bugfixes.
authorPaul Smith <psmith@gnu.org>
Wed, 17 Nov 1999 07:33:47 +0000 (07:33 +0000)
committerPaul Smith <psmith@gnu.org>
Wed, 17 Nov 1999 07:33:47 +0000 (07:33 +0000)
* New handling of += in target-specific variables.

18 files changed:
ChangeLog
Makefile.am
NEWS
configure.in
expand.c
file.c
function.c
job.c
main.c
make.h
make.texinfo
read.c
signame.c
tests/ChangeLog
tests/scripts/features/targetvars
tests/scripts/functions/if
variable.c
variable.h

index ad6f6e8..956009b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+1999-11-17  Paul D. Smith  <psmith@gnu.org>
+
+       * function.c (func_if): Find the end of the arg list by testing
+       the next item for NULL; any other test is not correct.
+       Reported by Graham Reed <grahamr@algorithmics.com> (PR/1429).
+
+       Fix += when used in a target-specific variable context.
+
+       * variable.h: New bitfield APPEND set if we have a +=
+       target-specific variable.
+
+       * variable.c (try_variable_definition): Add an argument to specify
+       if we're trying a target-specific variable.  If we are and it's an
+       append style, don't append it, record it as normal recursive, but
+       set the APPEND flag so it'll be expanded later.
+       * main.c (handle_non_switch_argument): Use new
+       try_variable_definition() signature.
+       * read.c (read_makefile,record_target_var): Ditto.
+
+       * expand.c (allocated_variable_append): New function: like
+       allocated_variable_expand(), but we expand the same variable name
+       in the context of the ``next'' variable set, then we append this
+       expanded value.
+       (recursively_expand): Invoke it, if the APPEND bit is set.
+
+1999-11-10  Paul D. Smith  <psmith@gnu.org>
+
+       * file.c (snap_deps): If the .NOTPARALLEL target is defined, turn
+       off parallel builds for this make only (still allow submakes to be
+       run in parallel).
+       * main.c: New variable, ``not_parallel''.
+       * make.h: Add an extern for it.
+       * job.c (new_job): Test NOT_PARALLEL as well as JOB_SLOTS.
+       * NEWS: Add info on .NOTPARALLEL.
+       * make.texinfo (Special Targets): Document it.
+
+       * configure.in (GLOBDIR): Set to "glob" if we need to build the
+       glob library.
+       * Makefile.am (SUBDIRS): Use the GLOBDIR variable instead of
+       "glob" so we don't try to build glob if we don't need to (if we
+       have GLIBC glob).  Reported by Lars Hecking <lhecking@nmrc.ucc.ie>.
+
+       * main.c (main): Don't put "***" in the clock skew warning
+       message.  Reported by karl@gnu.org.
+
+       * make.h: Remove unneeded signal setup.
+
+       * signame.c: Remove extraneous #includes; some versions of Ultrix
+       don't protect against multiple inclusions and it causes compile
+       errors.  Reported by Simon Burge <simonb@thistledown.com.au>.
+
 1999-10-15  Paul D. Smith  <psmith@gnu.org>
 
        * main.c (quote_for_env): Rename from quote_as_word().
index 483d012..df78820 100644 (file)
@@ -10,12 +10,12 @@ make_SOURCES =      main.c commands.c job.c dir.c file.c misc.c read.c remake.c \
                commands.h dep.h filedef.h job.h make.h rule.h variable.h \
                signame.c signame.h \
                getopt.c getopt1.c getopt.h
-make_LDADD =   @LIBOBJS@ @ALLOCA@ @GLOBLIB@
+make_LDADD =   $(LIBOBJS) @ALLOCA@ $(GLOBLIB)
 
 info_TEXINFOS =        make.texinfo
 man_MANS =     make.1
 
-INCLUDES =     @GLOBINC@ -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\"
+INCLUDES =     $(GLOBINC) -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\"
 
 EXTRA_DIST =   README build.sh.in $(man_MANS) README.customs remote-cstms.c\
                make-stds.texi texinfo.tex SCOPTIONS SMakefile\
@@ -25,12 +25,12 @@ EXTRA_DIST =        README build.sh.in $(man_MANS) README.customs remote-cstms.c\
                readme.vms makefile.vms makefile.com config.h-vms vmsdir.h\
                vmsfunctions.c vmsify.c
 
-SUBDIRS =      glob
+SUBDIRS =      $(GLOBDIR)
 
 MOSTLYCLEANFILES = loadavg.c
 CLEANFILES =   loadavg
 
-MAKE_HOST = @MAKE_HOST@
+MAKE_HOST =    @MAKE_HOST@
 
 
 # --------------- Local INSTALL Section
diff --git a/NEWS b/NEWS
index 77bf66f..b0dfe48 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
 GNU make NEWS                                               -*-indented-text-*-
   History of user-visible changes.
-  17 Sep 1999
+  10 Nov 1999
 
 Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
 See the end for copying conditions.
@@ -12,7 +12,7 @@ Please send GNU make bug reports to <bug-make@gnu.org>.
 See the README file and the GNU make manual for details on sending bug
 reports.
 \f
-Version 3.78.2
+Version 3.79
 
 * Previously, GNU make quoted variables such as MAKEFLAGS and
   MAKEOVERRIDES for proper parsing by the shell.  This allowed them to
@@ -28,6 +28,10 @@ Version 3.78.2
   explicitly within a make rule you may need to re-examine your use for
   correctness given this change.
 
+* A new psuedo-target, .NOTPARALLEL, is defined.  If set the current
+  makefile is always run serially regardless of the value of -j.  Any
+  submakes will still be run in parallel if -j was specified.
+\f
 Version 3.78
 
 * Two new functions, $(error ...) and $(warning ...) are available.  The
index 01e70dc..7a0aed4 100644 (file)
@@ -206,6 +206,7 @@ AC_CACHE_VAL(make_cv_sys_gnu_glob, [
 case "$make_cv_sys_gnu_glob" in
   yes) AC_MSG_RESULT(yes) ;;
   no)  AC_MSG_RESULT([no; using local copy])
+       AC_SUBST(GLOBDIR) GLOBDIR=glob
        AC_SUBST(GLOBINC) GLOBINC='-I$(srcdir)/glob'
        AC_SUBST(GLOBLIB) GLOBLIB=glob/libglob.a
        ;;
index edf6c9c..0387368 100644 (file)
--- a/expand.c
+++ b/expand.c
@@ -17,6 +17,8 @@ along with GNU Make; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
+
 #include "make.h"
 #include "filedef.h"
 #include "job.h"
@@ -89,6 +91,8 @@ initialize_variable_output ()
 \f
 /* Recursively expand V.  The returned string is malloc'd.  */
 
+static char *allocated_variable_append PARAMS ((struct variable *v));
+
 char *
 recursively_expand (v)
      register struct variable *v;
@@ -102,7 +106,10 @@ recursively_expand (v)
            v->name);
 
   v->expanding = 1;
-  value = allocated_variable_expand (v->value);
+  if (v->append)
+    value = allocated_variable_append (v);
+  else
+    value = allocated_variable_expand (v->value);
   v->expanding = 0;
 
   return value;
@@ -135,17 +142,20 @@ reference_variable (o, name, length)
      unsigned int length;
 {
   register struct variable *v = lookup_variable (name, length);
+  char *value;
 
   if (v == 0)
     warn_undefined (name, length);
 
-  if (v != 0 && *v->value != '\0')
-    {
-      char *value = (v->recursive ? recursively_expand (v) : v->value);
-      o = variable_buffer_output (o, value, strlen (value));
-      if (v->recursive)
-       free (value);
-    }
+  if (v == 0 || *v->value == '\0')
+    return o;
+
+  value = (v->recursive ? recursively_expand (v) : v->value);
+
+  o = variable_buffer_output (o, value, strlen (value));
+
+  if (v->recursive)
+    free (value);
 
   return o;
 }
@@ -466,6 +476,54 @@ variable_expand_for_file (line, file)
   return result;
 }
 \f
+/* Like allocated_variable_expand, but we first expand this variable in the
+    context of the next variable set, then we append the expanded value.  */
+
+static char *
+allocated_variable_append (v)
+     struct variable *v;
+{
+  struct variable_set_list *save;
+  int len = strlen (v->name);
+  char *var = alloca (len + 4);
+  char *value;
+
+  char *obuf = variable_buffer;
+  unsigned int olen = variable_buffer_length;
+
+  variable_buffer = 0;
+
+  assert(current_variable_set_list->next != 0);
+  save = current_variable_set_list;
+  current_variable_set_list = current_variable_set_list->next;
+
+  var[0] = '$';
+  var[1] = '(';
+  strcpy (&var[2], v->name);
+  var[len+2] = ')';
+  var[len+3] = '\0';
+
+  value = variable_expand_for_file (var, 0);
+
+  current_variable_set_list = save;
+
+  value += strlen (value);
+  value = variable_buffer_output (value, " ", 1);
+  value = variable_expand_string (value, v->value, (long)-1);
+
+  value = variable_buffer;
+
+#if 0
+  /* Waste a little memory and save time.  */
+  value = xrealloc (value, strlen (value))
+#endif
+
+  variable_buffer = obuf;
+  variable_buffer_length = olen;
+
+  return value;
+}
+
 /* Like variable_expand_for_file, but the returned string is malloc'd.
    This function is called a lot.  It wants to be efficient.  */
 
diff --git a/file.c b/file.c
index daf22a5..55ca7ee 100644 (file)
--- a/file.c
+++ b/file.c
@@ -540,6 +540,10 @@ snap_deps ()
   f = lookup_file (".POSIX");
   if (f != 0 && f->is_target)
     posix_pedantic = 1;
+
+  f = lookup_file (".NOTPARALLEL");
+  if (f != 0 && f->is_target)
+    not_parallel = 1;
 }
 \f
 /* Set the `command_state' member of FILE and all its `also_make's.  */
index 1a08845..237214e 100644 (file)
@@ -1115,15 +1115,15 @@ func_if (o, argv, funcname)
   if (argv[0] != NULL && argv[1] != NULL)
     {
       char *expansion;
-      char **endp = argv+1;
+      char **argend = argv+1;
 
       /* If we're doing the else-clause, make sure we concatenate any
          potential extra arguments into the last argument.  */
       if (!result)
-        while (*endp && **endp != '\0')
-          ++endp;
+        while (argend[1])
+          ++argend;
 
-      expansion = expand_argument (*argv, *endp-1);
+      expansion = expand_argument (*argv, *argend-1);
 
       o = variable_buffer_output (o, expansion, strlen (expansion));
       free (expansion);
diff --git a/job.c b/job.c
index 4213dec..ba79b30 100644 (file)
--- a/job.c
+++ b/job.c
@@ -1413,7 +1413,7 @@ new_job (file)
      (This will notice if there are in fact no commands.)  */
   (void) start_waiting_job (c);
 
-  if (job_slots == 1)
+  if (job_slots == 1 || not_parallel)
     /* Since there is only one job slot, make things run linearly.
        Wait for the child to die, setting the state to `cs_finished'.  */
     while (file->command_state == cs_running)
diff --git a/main.c b/main.c
index 4ea4f66..a1b3d74 100644 (file)
--- a/main.c
+++ b/main.c
@@ -419,6 +419,11 @@ struct file *default_file;
 
 int posix_pedantic;
 
+/* Nonzero if we have seen the `.NOTPARALLEL' target.
+   This turns off parallel builds for this invocation of make.  */
+
+int not_parallel;
+
 /* Nonzero if some rule detected clock skew; we keep track so (a) we only
    print one warning about it during the run, and (b) we can print a final
    warning at the end of the run. */
@@ -1776,7 +1781,8 @@ int main (int argc, char ** argv)
 
     /* If we detected some clock skew, generate one last warning */
     if (clock_skew_detected)
-      error (NILF, _("*** Warning:  Clock skew detected.  Your build may be incomplete."));
+      error (NILF,
+             _("warning:  Clock skew detected.  Your build may be incomplete."));
 
     /* Exit.  */
     die (status);
@@ -1860,7 +1866,7 @@ handle_non_switch_argument (arg, env)
   if (arg[0] == '-' && arg[1] == '\0')
     /* Ignore plain `-' for compatibility.  */
     return;
-  v = try_variable_definition (0, arg, o_command);
+  v = try_variable_definition (0, arg, o_command, 0);
   if (v != 0)
     {
       /* It is indeed a variable definition.  Record a pointer to
diff --git a/make.h b/make.h
index 67ded3e..7ecfcd2 100644 (file)
--- a/make.h
+++ b/make.h
@@ -107,23 +107,6 @@ extern int errno;
 # define POSIX 1
 #endif
 
-#if defined (HAVE_SYS_SIGLIST) && !defined (SYS_SIGLIST_DECLARED)
-extern char *sys_siglist[];
-#endif
-
-#if !defined (HAVE_SYS_SIGLIST) || !defined (HAVE_STRSIGNAL)
-# include "signame.h"
-#endif
-
-/* Some systems do not define NSIG in <signal.h>.  */
-#ifndef NSIG
-# ifdef _NSIG
-#  define NSIG  _NSIG
-# else
-#  define NSIG  32
-# endif
-#endif
-
 #ifndef RETSIGTYPE
 # define RETSIGTYPE     void
 #endif
@@ -485,7 +468,7 @@ extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
 extern int debug_flag, print_data_base_flag, question_flag, touch_flag;
 extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
 extern int print_version_flag, print_directory_flag;
-extern int warn_undefined_variables_flag, posix_pedantic;
+extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;
 extern int clock_skew_detected;
 
 /* can we run commands via 'sh -c xxx' or must we use batch files? */
index fb15117..175493a 100644 (file)
@@ -2471,6 +2471,16 @@ Simply by being mentioned as a target, this tells @code{make} to
 export all variables to child processes by default.
 @xref{Variables/Recursion, ,Communicating Variables to a
 Sub-@code{make}}.
+
+@findex .NOTPARALLEL
+@item .NOTPARALLEL
+@cindex parallel execution, overriding
+
+If @code{.NOTPARALLEL} is mentioned as a target, then this invocation of
+@code{make} will be run serially, even if the @samp{-j} option is
+given.  Any recursively invoked @code{make} command will still be run in
+parallel if its makefile doesn't contain this target.  Any prerequisites
+on this target are ignored.
 @end table
 
 Any defined implicit rule suffix also counts as a special target if it
diff --git a/read.c b/read.c
index e8dcee4..9d043ce 100644 (file)
--- a/read.c
+++ b/read.c
@@ -580,7 +580,7 @@ read_makefile (filename, flags)
                }
            }
          else if (!ignoring
-                  && !try_variable_definition (&fileinfo, p2, o_override))
+                  && !try_variable_definition (&fileinfo, p2, o_override, 0))
            error (&fileinfo, _("invalid `override' directive"));
 
          continue;
@@ -598,7 +598,7 @@ read_makefile (filename, flags)
          p2 = next_token (p + 6);
          if (*p2 == '\0')
            export_all_variables = 1;
-         v = try_variable_definition (&fileinfo, p2, o_file);
+         v = try_variable_definition (&fileinfo, p2, o_file, 0);
          if (v != 0)
            v->export = v_export;
          else
@@ -717,7 +717,7 @@ read_makefile (filename, flags)
          reading_file = &fileinfo;
        }
 #undef word1eq
-      else if (try_variable_definition (&fileinfo, p, o_file))
+      else if (try_variable_definition (&fileinfo, p, o_file, 0))
        /* This line has been dealt with.  */
        ;
       else if (lb.buffer[0] == '\t')
@@ -1422,6 +1422,9 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
 
   global = current_variable_set_list;
 
+  /* If the variable is an append version, store that but treat it as a
+     normal recursive variable.  */
+
   for (; filenames != 0; filenames = nextf)
     {
       struct variable *v;
@@ -1458,7 +1461,7 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
 
       /* Make the new variable context current and define the variable.  */
       current_variable_set_list = vlist;
-      v = try_variable_definition (flocp, defn, origin);
+      v = try_variable_definition (flocp, defn, origin, 1);
       if (!v)
         error (flocp, _("Malformed per-target variable definition"));
       v->per_target = 1;
index 8ddbb36..7d12f88 100644 (file)
--- a/signame.c
+++ b/signame.c
@@ -1,5 +1,5 @@
 /* Convert between signal names and numbers.
-   Copyright (C) 1990, 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1990,92,93,95,96,99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include "make.h"
-
-#include <stdio.h>
-#include <sys/types.h>         /* Some systems need this for <signal.h>.  */
-#include <signal.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
 
-/* Some systems declare `sys_siglist in <unistd.h>; if
-   configure defined SYS_SIGLIST_DECLARED, it may expect
-   to find the declaration there.  */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+/* In the GNU make version, all the headers we need are provided by make.h.  */
+#include "make.h"
 
 
 /* Some systems do not define NSIG in <signal.h>.  */
index 002b93c..f021491 100644 (file)
@@ -1,3 +1,11 @@
+1999-11-17  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/functions/if: Add a test for PR/1429: put some text
+       after an if-statement to make sure it works.
+
+       * scripts/features/targetvars: Add a test for PR/1380: handling +=
+       in target-specific variable definitions correctly.
+
 1999-10-15  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/variables/MAKEFILES: This was really broken: it didn't
index 83bf9ed..e4dc0b2 100644 (file)
@@ -124,5 +124,31 @@ close(MAKEFILE);
 $answer = "foo bar\n";
 &compare_output($answer, &get_logfile(1));
 
+# TEST #9
+# For PR/1380: Using += assignment in target-specific variables sometimes fails
+
+$makefile3 = &get_tmpfile;
+
+open(MAKEFILE,"> $makefile3");
+print MAKEFILE <<'EOF';
+.PHONY: all one
+all: FOO += baz
+all: one; @echo $(FOO)
+
+FOO = bar
+
+one: FOO += biz
+one: ; @echo $(FOO)
+EOF
+close(MAKEFILE);
+
+&run_make_with_options("$makefile3", "", &get_logfile);
+$answer = "bar baz biz\nbar baz\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options("$makefile3", "one", &get_logfile);
+$answer = "bar biz\n";
+&compare_output($answer, &get_logfile(1));
+
 
 1;
index cb1f5fc..fa2d0df 100644 (file)
@@ -18,14 +18,14 @@ all:
 \t\@echo \$(if ,\$(shell echo hi),false)
 \t\@echo \$(if \$(call NEQ,a,b),true,false)
 \t\@echo \$(if \$(call NEQ,a,a),true,false)
-\t\@echo \$(if z,true,fal,se)
-\t\@echo \$(if ,true,fal,se)
+\t\@echo \$(if z,true,fal,se) hi
+\t\@echo \$(if ,true,fal,se)there
 EOMAKE
 
 close(MAKEFILE);
 
 &run_make_with_options($makefile, "", &get_logfile);
-$answer = "false\n\n\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue\nfal,se\n";
+$answer = "false\n\n\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue hi\nfal,sethere\n";
 &compare_output($answer, &get_logfile(1));
 
 1;
index 47e9da8..7ffe94b 100644 (file)
@@ -678,10 +678,11 @@ target_environment (file)
    returned.  */
 
 struct variable *
-try_variable_definition (flocp, line, origin)
+try_variable_definition (flocp, line, origin, target_var)
      const struct floc *flocp;
      char *line;
      enum variable_origin origin;
+     int target_var;
 {
   register int c;
   register char *p = line;
@@ -691,6 +692,7 @@ try_variable_definition (flocp, line, origin)
          f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
   char *name, *expanded_name, *value, *alloc_value=NULL;
   struct variable *v;
+  int append = 0;
 
   while (1)
     {
@@ -800,6 +802,16 @@ try_variable_definition (flocp, line, origin)
       value = p;
       break;
     case f_append:
+      /* If we have += but we're in a target variable context, defer the
+         append until the context expansion.  */
+      if (target_var)
+        {
+          append = 1;
+          flavor = f_recursive;
+          value = p;
+          break;
+        }
+
       /* An appending variable definition "var += value".
         Extract the old value and append the new one.  */
       v = lookup_variable (expanded_name, strlen (expanded_name));
@@ -939,6 +951,8 @@ try_variable_definition (flocp, line, origin)
   v = define_variable (expanded_name, strlen (expanded_name),
                       value, origin, flavor == f_recursive);
 
+  v->append = append;
+
   if (alloc_value)
     free (alloc_value);
   free (expanded_name);
index 4826c76..19ec31e 100644 (file)
@@ -45,6 +45,8 @@ struct variable
     unsigned int recursive:1;  /* Gets recursively re-evaluated.  */
     unsigned int expanding:1;  /* Nonzero if currently being expanded.  */
     unsigned int per_target:1; /* Nonzero if a target-specific variable.  */
+    unsigned int append:1;     /* Nonzero if an appending target-specific
+                                   variable.  */
     enum variable_export
       {
        v_export,               /* Export this variable.  */
@@ -103,7 +105,7 @@ extern void initialize_file_variables PARAMS ((struct file *file));
 extern void print_file_variables PARAMS ((struct file *file));
 extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix));
 extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
-extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin));
+extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin, int target_var));
 
 extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length));
 extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value,