]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Incorporate some VMS fixes.
authorPaul Smith <psmith@gnu.org>
Thu, 8 Aug 2002 00:11:19 +0000 (00:11 +0000)
committerPaul Smith <psmith@gnu.org>
Thu, 8 Aug 2002 00:11:19 +0000 (00:11 +0000)
Add -B option docs.
Add .VARIABLES variable.
Add a few new tests.
Add a new translation: Swedish

19 files changed:
ChangeLog
NEWS
config.h-vms.template
dir.c
doc/make.texi
hash.h
main.c
make.h
makefile.com
po/ChangeLog
po/LINGUAS
read.c
remake.c
tests/ChangeLog
tests/scripts/misc/general3
tests/scripts/options/dash-B [new file with mode: 0644]
tests/scripts/variables/special [new file with mode: 0644]
variable.c
variable.h

index 0567746c8015a712a6a5b668c055bfff7b30840b..fe043a04463ffa315bba3040524d091ecadbfb11 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,26 @@
+2002-08-02  Paul D. Smith  <psmith@gnu.org>
+
+       * NEWS: Remove the mention of .TARGETS; we aren't going to publish
+       this one because it's too hard to get right.  We'll look at it for
+       a future release.
+
 2002-08-01  Paul D. Smith  <psmith@gnu.org>
 
-       Add new introspection variables .VARIABLES and .TARGETS.
+       * main.c (switches): Add a new option, -B (--always-make).  If
+       specified, make will rebuild all targets that it encounters even
+       if they don't appear to be out of date.
+       (always_make_flag): New flag.
+       * make.h: Extern always_make_flag.
+       * remake.c (update_file_1): Check always_make_flag; if it's set we
+       will always rebuild any target we can, even if none of its
+       prerequisites are newer.
+       * NEWS: Mention it.
+
+       * doc/make.texi (Shell Function): Make it clear that make
+       variables marked as "export" are not passed to instances of the
+       shell function.
+
+       Add new introspection variable .VARIABLES and .TARGETS.
 
        * variable.c (handle_special_var): New function.  If the variable
        reference passed in is "special" (.VARIABLES or .TARGETS),
        (target_environment): Use the "exportable" flag instead of
        re-checking the name here... an efficiency improvement.
 
+2002-07-31  Paul D. Smith  <psmith@gnu.org>
+
+       * config.h-vms.template: Updates to build on VMS.  Thanks to
+       Brian_Benning@aksteel.com for helping verify the build.
+       * makefile.com: Build the new hash.c file.
+       * hash.h: Use strcpmi(), not stricmp(), in the
+       HAVE_CASE_INSENSITIVE_FS case.
+
+2002-07-30  Paul D. Smith  <psmith@gnu.org>
+
+       * hash.h (ISTRING_COMPARE, return_ISTRING_COMPARE): Add missing
+       backslashes to the HAVE_CASE_INSENSITIVE_FS case.
+       Reported by <Brian_Benning@aksteel.com>.
+
 2002-07-10  Paul D. Smith  <psmith@gnu.org>
 
        * variable.c (pop_variable_scope): Remove variable made unused by
diff --git a/NEWS b/NEWS
index bd4af15018c9649248343e0b0c95ecf48346e86e..d8706c53febf4f390d9801b538085d13e04de17b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -44,10 +44,13 @@ Version 3.80
   list when a makefile is just being read (before any includes) is the
   name of the current makefile.
 
-* GNU make now supports some simple introspection capability: two new
-  built-in variables are defined: $(.VARIABLES) and $(.TARGETS).  These
-  expand to a complete list of variables and targets, respectively,
-  defined by all makefiles at the time the variables are expanded.
+* A new built-in variable is defined: $(.VARIABLES).  When it is
+  expanded it returns a complete list of variable names defined by all
+  makefiles at that moment.
+
+* A new command-line option is defined, -B or --always-make.  If
+  specified GNU make will consider all targets out-of-date even if they
+  would otherwise not be.
 
 * The arguments to $(call ...) functions were being stored in $1, $2,
   etc. as recursive variables, even though they are fully expanded
index 1dbf04ce011cec376d6403e56243b715935dfe7a..7d7d9b0c8632090c82914303d9f5a5505817d69a 100644 (file)
@@ -9,13 +9,6 @@
 /* #undef _ALL_SOURCE */
 #endif
 
-/* Define if using alloca.c.  */
-/* #undef C_ALLOCA */
-/* maybe this should be placed into make.h */
-#if    defined(__VAX) && defined(__DECC)
-#define alloca(n)      __ALLOCA(n)
-#endif
-
 /* Define to 1 if NLS is requested.  */
 /* #undef ENABLE_NLS */
 
 /* Define if you have the sun library (-lsun).  */
 /* #undef HAVE_LIBSUN */
 
+/* Use high resolution file timestamps if nonzero. */
+#define FILE_TIMESTAMP_HI_RES 0
+
 /* Define for case insensitve filenames */
 #define HAVE_CASE_INSENSITIVE_FS 1
 
 #define PARAMS(protos)  ()
 #endif /* C++ or ANSI C.  */
 
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+/* maybe this should be placed into make.h */
+#if    defined(__VAX) && defined(__DECC)
+#define alloca(n)      __ALLOCA(n)
+#endif
+
 /* Build host information. */
 #define MAKE_HOST "VMS"
diff --git a/dir.c b/dir.c
index a84402fe51ca9b1bbe0a1e39cf193d993a25acfa..088f751cb2be3df25b2da21b1bcea24622b78fef 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -546,7 +546,7 @@ find_directory (name)
              if (dc->dirstream == 0)
                 /* Couldn't open the directory.  Mark this by
                    setting the `files' member to a nil pointer.  */
-               hash_free (&dc->dirfiles, 0);
+                dc->dirfiles.ht_vec = 0;
              else
                {
                  hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
index 291a2949a9f1b46fbfcbe75a9a0b41c010828b97..b36383a55baf6106e7dcf72f431c98b1d3ac3c5a 100644 (file)
@@ -68,14 +68,21 @@ Published by the Free Software Foundation @*
 Boston, MA 02111-1307 USA @*
 ISBN @value{ISBN} @*
 
-Maintenance and updates since Version 3.76 by Paul D. Smith.
-
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts.  A copy of the license is included in the section entitled
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+Texts being ``A GNU Manual'', and with the Back-Cover Texts being as in
+(a) below.  A copy of the license is included in the section entitled
 ``GNU Free Documentation License''.
+
+(a) The FSF's Back-Cover Text is:
+
+@quotation
+      You have freedom to copy and modify this GNU Manual, like GNU
+      software.  Copies published by the Free Software Foundation raise
+      funds for GNU development.
+@end quotation
 @sp 2
 Cover art by Etienne Suvasa.
 @end titlepage
@@ -1240,9 +1247,9 @@ variable definitions.
 @cindex makefiles, and special variables
 @cindex special variables
 
-GNU @code{make} also supports two other special variables.  Note that
-any value you assign to these variables will be ignored; they will
-always return their special value.
+GNU @code{make} also supports a special variable.  Note that any value
+you assign to this variable will be ignored; it will always return its
+special value.
 
 @vindex $(.VARIABLES)
 @vindex .VARIABLES @r{(list of variables)}
@@ -1254,15 +1261,15 @@ variables which have empty values, as well as built-in variables
 does not include any variables which are only defined in a
 target-specific context.
 
-@vindex $(.TARGETS)
-@vindex .TARGETS @r{(list of targets)}
-The second special variable is @code{.TARGETS}.  When expanded, the
-value consists of a list of all targets defined in all makefiles read
-up until that point.  Note it's not enough for a file to be simply
-mentioned in the makefile to be listed in this variable, even if it
-would match an implicit rule and become an ``implicit target''.  The
-file must appear as a target, on the left-hand side of a ``:'', to be
-considered a target for the purposes of this variable.
+@c @vindex $(.TARGETS)
+@c @vindex .TARGETS @r{(list of targets)}
+@c The second special variable is @code{.TARGETS}.  When expanded, the
+@c value consists of a list of all targets defined in all makefiles read
+@c up until that point.  Note it's not enough for a file to be simply
+@c mentioned in the makefile to be listed in this variable, even if it
+@c would match an implicit rule and become an ``implicit target''.  The
+@c file must appear as a target, on the left-hand side of a ``:'', to be
+@c considered a target for the purposes of this variable.
 
 @node Remaking Makefiles, Overriding Makefiles, Special Variables, Makefiles
 @section How Makefiles Are Remade
@@ -6542,10 +6549,12 @@ removes the trailing (carriage-return and) newline, if it's the last
 thing in the result.@refill
 
 The commands run by calls to the @code{shell} function are run when the
-function calls are expanded.  In most cases, this is when the makefile is
-read in.  The exception is that function calls in the commands of the rules
-are expanded when the commands are run, and this applies to @code{shell}
-function calls like all others.
+function calls are expanded (@pxref{Reading Makefiles, , How
+@code{make} Reads a Makefile}).  Because this function involves
+spawning a new shell, you should carefully consider the performance
+implications of using the @code{shell} function within recursively
+expanded variables vs. simply expanded variables (@pxref{Flavors, ,The
+Two Flavors of Variables}).
 
 Here are some examples of the use of the @code{shell} function:
 
@@ -7093,6 +7102,15 @@ Here is a table of all the options @code{make} understands:
 @cindex @code{-m}
 These options are ignored for compatibility with other versions of @code{make}.
 
+@item -B
+@cindex @code{-B}
+@itemx --always-make
+@cindex @code{--always-make}
+Consider all targets out-of-date.  GNU @code{make} proceeds to
+consider targets and their prerequisites using the normal algorithms;
+however, all these targets are remade, regardless of the status of
+their prerequisites.
+
 @item -C @var{dir}
 @cindex @code{-C}
 @itemx --directory=@var{dir}
diff --git a/hash.h b/hash.h
index 60193b062532bd6b4c0fe95d435b247e24acabef..c1b3ea46d2674d813933c339e168e5898a128bd5 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -173,10 +173,10 @@ extern void *hash_deleted_item;
 } while (0)
 
 #define ISTRING_COMPARE(X, Y, RESULT) do { \
-  _RESULT_ = stricmp ((X), (Y));
+  _RESULT_ = strcmpi ((X), (Y)); \
 } while (0)
 #define return_ISTRING_COMPARE(X, Y) do { \
-  return stricmp ((X), (Y));
+  return strcmpi ((X), (Y)); \
 } while (0)
 
 #else
diff --git a/main.c b/main.c
index 10d6124406e8bc2a829d8e81c18da5fc47a92585..03d6f40bbafc4aaa30a156c531d37cfbf4abfe81 100644 (file)
--- a/main.c
+++ b/main.c
@@ -252,6 +252,11 @@ static int print_usage_flag = 0;
    for each reference to an undefined variable.  */
 
 int warn_undefined_variables_flag;
+
+/* If nonzero, always build all targets, regardless of whether
+   they appear out of date or not.  */
+
+int always_make_flag = 0;
 \f
 /* The table of command switches.  */
 
@@ -260,6 +265,9 @@ static const struct command_switch switches[] =
     { 'b', ignore, 0, 0, 0, 0, 0, 0,
        0, 0,
        N_("Ignored for compatibility") },
+    { 'B', flag, (char *) &always_make_flag, 1, 1, 0, 0, 0,
+       "always-make", 0,
+       N_("Unconditionally make all targets") },
     { 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
        "directory", N_("DIRECTORY"),
        N_("Change to DIRECTORY before doing anything") },
@@ -989,8 +997,8 @@ int main (int argc, char ** argv)
 #endif
 
   /* Initialize the special variables.  */
-  define_variable (".VARIABLES", 10, "", o_default, 0);
-  define_variable (".TARGETS", 8, "", o_default, 0);
+  define_variable (".VARIABLES", 10, "", o_default, 0)->special = 1;
+  /* define_variable (".TARGETS", 8, "", o_default, 0); */
 
   /* Read in variables from the environment.  It is important that this be
      done before $(MAKE) is figured out so its definitions will not be
diff --git a/make.h b/make.h
index 44d7b3974a5318593985f611dc3ce7f61d8ed7c0..32f233f4392fadbd60f311fa11e77d184d433dfe 100644 (file)
--- a/make.h
+++ b/make.h
@@ -194,6 +194,8 @@ extern unsigned int get_path_max PARAMS ((void));
 # include <unixlib.h>
 # include <unixio.h>
 # include <perror.h>
+/* Needed to use alloca on VMS.  */
+# include <builtins.h>
 #endif
 
 #ifndef __attribute__
@@ -485,7 +487,7 @@ extern const struct floc *reading_file;
 extern char **environ;
 
 extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
-extern int print_data_base_flag, question_flag, touch_flag;
+extern int print_data_base_flag, question_flag, touch_flag, always_make_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, not_parallel;
index 5a0f884c9b470ad9d18fc4ed193bb27f31e687d8..4d55923d095ffcc8d4e90bfc810b6ca655394bf5 100644 (file)
@@ -49,7 +49,7 @@ $   lopt = "/debug"
 $ else
 $   lopt = ""
 $ endif
-$ filelist = "alloca ar arscan commands default dir expand file function implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt1 getopt"
+$ filelist = "alloca ar arscan commands default dir expand file function hash implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt1 getopt"
 $ copy config.h-vms config.h
 $ n=0
 $ open/write optf make.opt
index 6c53a006b4dbbe096265c8893e50a03d9d9588c0..6c5321a7b90b71f7e51e8ff6347762f11950b223 100644 (file)
@@ -1,3 +1,7 @@
+2002-08-02  Paul D. Smith  <psmith@gnu.org>
+
+       * LINGUAS: Add a new translation for Swedish (sv).
+
 2002-04-21  Paul D. Smith  <psmith@gnu.org>
 
        * LINGUAS, hr.po: Added new translation: Croatian.
@@ -7,15 +11,3 @@
        * .cvsignore: Moved from i18n to here.
 
        * POTFILES.in, LINGUAS, Makevars: Created.
-
-2002-04-21  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: New file, from gettext-0.11.1.
-       * Rules-quot: New file, from gettext-0.11.1.
-       * boldquot.sed: New file, from gettext-0.11.1.
-       * en@boldquot.header: New file, from gettext-0.11.1.
-       * en@quot.header: New file, from gettext-0.11.1.
-       * insert-header.sin: New file, from gettext-0.11.1.
-       * quot.sed: New file, from gettext-0.11.1.
-       * remove-potcdate.sin: New file, from gettext-0.11.1.
-
index cce36011e160050cba6c6dcc6fbdc38591149d38..55618e452f71f5738078b607c5f4c2ed37bdcee1 100644 (file)
@@ -1,5 +1,5 @@
 # Set of available languages: 14 languages
 
-da de es fr gl he hr ja ko nl pl pt_BR ru tr
+da de es fr gl he hr ja ko nl pl pt_BR sv ru tr
 
 # Can't seem to get en@quot and en@boldquot to build properly?
diff --git a/read.c b/read.c
index ec5465059657836c6f6433ad0d8706d8f08a5042..6d2de07da456c5fef69c28a30929f0389277d46c 100644 (file)
--- a/read.c
+++ b/read.c
@@ -380,7 +380,9 @@ eval_makefile (filename, flags)
 
   reading_file = curfile;
 
-  free(ebuf.bufstart);
+  fclose (ebuf.fp);
+
+  free (ebuf.bufstart);
   return r;
 }
 
@@ -2564,7 +2566,12 @@ readline (ebuf)
   if (ferror (ebuf->fp))
     pfatal_with_name (ebuf->floc.filenm);
 
-  return nlines ? nlines : -1;
+  /* If we found some lines, return how many.
+     If we didn't, but we did find _something_, that indicates we read the last
+     line of a file with no final newline; return 1.
+     If we read nothing, we're at EOF; return -1.  */
+
+  return nlines ? nlines : p == ebuf->bufstart ? -1 : 1;
 }
 \f
 /* Parse the next "makefile word" from the input buffer, and return info
index 66c6d311d140cf119b4c427fead9b0e432578e1b..72c4d78a4447be79219343cc364a0bdaf456c5d3 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -350,7 +350,6 @@ update_file_1 (file, depth)
   int dep_status = 0;
   register struct dep *d, *lastd;
   int running = 0;
-  int maybe_make;
 
   DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
 
@@ -437,6 +436,7 @@ update_file_1 (file, depth)
   while (d != 0)
     {
       FILE_TIMESTAMP mtime;
+      int maybe_make;
 
       check_renamed (d->file);
 
@@ -492,7 +492,7 @@ update_file_1 (file, depth)
   /* Now we know whether this target needs updating.
      If it does, update all the intermediate files we depend on.  */
 
-  if (must_make)
+  if (must_make || always_make_flag)
     {
       for (d = file->deps; d != 0; d = d->next)
        if (d->file->intermediate)
@@ -544,7 +544,7 @@ update_file_1 (file, depth)
       file->update_status = dep_status;
       notice_finished_file (file);
 
-      depth--;
+      --depth;
 
       DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n"));
 
@@ -567,7 +567,7 @@ update_file_1 (file, depth)
        file's bookkeeping (updated, but not_started is bogus state).  */
     set_command_state (file, cs_not_started);
 
-  /* Now record which dependencies are more
+  /* Now record which prerequisites are more
      recent than this file, so we can define $?.  */
 
   deps_changed = 0;
@@ -636,12 +636,18 @@ update_file_1 (file, depth)
       DBF (DB_BASIC,
            _("Target `%s' is double-colon and has no prerequisites.\n"));
     }
-  else if (!noexist && file->is_target && !deps_changed && file->cmds == 0)
+  else if (!noexist && file->is_target && !deps_changed && file->cmds == 0
+           && !always_make_flag)
     {
       must_make = 0;
       DBF (DB_VERBOSE,
            _("No commands for `%s' and no prerequisites actually changed.\n"));
     }
+  else if (!must_make && file->cmds != 0 && always_make_flag)
+    {
+      must_make = 1;
+      DBF (DB_VERBOSE, _("Making `%s' due to always-make flag.\n"));
+    }
 
   if (!must_make)
     {
@@ -839,7 +845,6 @@ check_dep (file, depth, this_mtime, must_make_ptr)
 {
   struct dep *d;
   int dep_status = 0;
-  int maybe_make;
 
   ++depth;
   start_updating (file);
@@ -888,12 +893,14 @@ check_dep (file, depth, this_mtime, must_make_ptr)
             recent than the file on whose behalf we are checking.  */
       else
        {
-         register struct dep *lastd;
+         struct dep *lastd;
 
          lastd = 0;
          d = file->deps;
          while (d != 0)
            {
+              int maybe_make;
+
              if (is_updating (d->file))
                {
                  error (NILF, _("Circular %s <- %s dependency dropped."),
index 2dc997f05b1d06ea0745be1a38764c39d17a953f..387c08f128efef3e56916b4bb73bc41beacd8fe5 100644 (file)
@@ -1,3 +1,16 @@
+2002-08-07  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/misc/general3: Add a test for makefiles that don't end
+       in newlines.
+
+       * scripts/variables/special: Create tests for the special
+       variables (.VARIABLES and .TARGETS).  Comment out .TARGETS test
+       for now as it's not yet supported.
+
+2002-08-01  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/options/dash-B: Add a test for the new -B option.
+
 2002-07-11  Paul D. Smith  <psmith@gnu.org>
 
        * run_make_tests.pl (valid_option): Add support for Valgrind
index a265f71e149241c11997c8c60b2faf6f9e7c60d5..2421ed4e862f6b217b1b9fb89372c1b71393e801 100644 (file)
@@ -5,12 +5,14 @@ This tests random features of the parser that need to be supported, and
 which have either broken at some point in the past or seem likely to
 break.";
 
+$makefile2 = &get_tmpfile;
+
 open(MAKEFILE,"> $makefile");
 
 # The contents of the Makefile ...
 
 print MAKEFILE <<EOF;
-\# We want to allow both empty commands _and_ commands that resolve to empty.
+# We want to allow both empty commands _and_ commands that resolve to empty.
 EMPTY =
 
 .PHONY: all a1 a2 a3 a4
@@ -36,10 +38,21 @@ EOF
 close(MAKEFILE);
 
 &run_make_with_options($makefile,"",&get_logfile);
-
-# Create the answer to what should be produced by this Makefile
 $answer = "$make_name: Nothing to be done for `all'.\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST 2
 
+# Make sure files without trailing newlines are handled properly.
+
+open(MAKEFILE, "> $makefile2");
+print MAKEFILE "all:;\@echo FOO = \$(FOO)\nFOO = foo";
+close(MAKEFILE);
+
+&run_make_with_options($makefile2,"",&get_logfile);
+$answer = "FOO = foo\n";
 &compare_output($answer,&get_logfile(1));
 
+
 1;
diff --git a/tests/scripts/options/dash-B b/tests/scripts/options/dash-B
new file mode 100644 (file)
index 0000000..94932e5
--- /dev/null
@@ -0,0 +1,43 @@
+#                                                                    -*-perl-*-
+
+$description = "Test make -B (always remake) option.\n";
+
+$details = "\
+Construct a simple makefile that builds a target.
+Invoke make once, so it builds everything.  Invoke it again and verify
+that nothing is built.  Then invoke it with -B and verify that everything
+is built again.";
+
+open(MAKEFILE,"> $makefile");
+
+print MAKEFILE <<'EOF';
+.SUFFIXES:
+
+.PHONY: all
+all: foo
+
+foo: bar.x
+       @echo cp $< $@
+       @touch $@
+EOF
+
+close(MAKEFILE);
+
+
+&touch('bar.x');
+
+&run_make_with_options($makefile, '', &get_logfile);
+$answer = "cp bar.x foo\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile, '', &get_logfile);
+$answer = "$make_name: Nothing to be done for `all'.\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile, '-B', &get_logfile);
+$answer = "cp bar.x foo\n";
+&compare_output($answer, &get_logfile(1));
+
+unlink('bar.x', 'foo') unless $keep;
+
+1;
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
new file mode 100644 (file)
index 0000000..58c8655
--- /dev/null
@@ -0,0 +1,68 @@
+#                                                                    -*-perl-*-
+
+$description = "Test special GNU make variables.";
+
+$details = "";
+
+$makefile2 = &get_tmpfile;
+
+
+open(MAKEFILE, "> $makefile");
+
+print MAKEFILE <<'EOF';
+
+X1 := $(sort $(filter FOO BAR,$(.VARIABLES)))
+
+FOO := foo
+
+X2 := $(sort $(filter FOO BAR,$(.VARIABLES)))
+
+BAR := bar
+
+all:
+       @echo X1 = $(X1)
+       @echo X2 = $(X2)
+       @echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES)))
+
+EOF
+
+close(MAKEFILE);
+
+# TEST #1
+# -------
+
+&run_make_with_options($makefile, "", &get_logfile);
+$answer = "X1 =\nX2 = FOO\nLAST = BAR FOO\n";
+&compare_output($answer, &get_logfile(1));
+
+
+
+
+# open(MAKEFILE, "> $makefile2");
+
+# print MAKEFILE <<'EOF';
+
+# X1 := $(sort $(.TARGETS))
+
+# all: foo
+#      @echo X1 = $(X1)
+#      @echo X2 = $(X2)
+#      @echo LAST = $(sort $(.TARGETS))
+
+# X2 := $(sort $(.TARGETS))
+
+# foo:
+
+# EOF
+
+# close(MAKEFILE);
+
+# # TEST #2
+# # -------
+
+# &run_make_with_options($makefile2, "", &get_logfile);
+# $answer = "X1 =\nX2 = all\nLAST = all foo\n";
+# &compare_output($answer, &get_logfile(1));
+
+
+1;
index 7f55f8feae6841f5e94893497fcc30c9b627e645..0d296f525ff80715026991623e8ed0081f90a601 100644 (file)
@@ -177,9 +177,9 @@ define_variable_in_set (name, length, value, origin, recursive, set, flocp)
 \f
 /* If the variable passed in is "special", handle its special nature.
    Currently there are two such variables, both used for introspection:
-   .MAKE_VARS expands to a list of all the variables defined in this instance
+   .VARIABLES expands to a list of all the variables defined in this instance
    of make.
-   .MAKE_TARGETS expands to a list of all the targets defined in this
+   .TARGETS expands to a list of all the targets defined in this
    instance of make.
    Returns the variable reference passed in.  */
 
@@ -192,10 +192,33 @@ handle_special_var (var)
   static unsigned long last_var_count = 0;
 
 
-  if (streq (var->name, ".MAKE_TARGETS"))
+  /* This one actually turns out to be very hard, due to the way the parser
+     records targets.  The way it works is that target information is collected
+     internally until make knows the target is completely specified.  It unitl
+     it sees that some new construct (a new target or variable) is defined that
+     it knows the previous one is done.  In short, this means that if you do
+     this:
+
+       all:
+
+       TARGS := $(.TARGETS)
+
+     then $(TARGS) won't contain "all", because it's not until after the
+     variable is created that the previous target is completed.
+
+     Changing this would be a major pain.  I think a less complex way to do it
+     would be to pre-define the target files as soon as the first line is
+     parsed, then come back and do the rest of the definition as now.  That
+     would allow $(.TARGETS) to be correct without a major change to the way
+     the parser works.
+
+  if (streq (var->name, ".TARGETS"))
     var->value = build_target_list (var->value);
 
-  else if (streq (var->name, ".MAKE_VARS")
+  else
+  */
+
+  if (streq (var->name, ".VARIABLES")
       && global_variable_set.table.ht_fill != last_var_count)
     {
       unsigned long max = EXPANSION_INCREMENT (strlen (var->value));
@@ -207,6 +230,7 @@ handle_special_var (var)
       /* Make sure we have at least MAX bytes in the allocated buffer.  */
       var->value = xrealloc (var->value, max);
 
+      /* Walk through the hash of variables, constructing a list of names.  */
       p = var->value;
       len = 0;
       for (; vp < end; ++vp)
@@ -231,6 +255,10 @@ handle_special_var (var)
           }
       *(p-1) = '\0';
 
+      /* Remember how many variables are in our current count.  Since we never
+         remove variables from the list, this is a reliable way to know whether
+         the list is up to date or needs to be recomputed.  */
+
       last_var_count = global_variable_set.table.ht_fill;
     }
 
@@ -262,7 +290,7 @@ lookup_variable (name, length)
 
       v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
       if (v)
-       return handle_special_var (v);
+       return v->special ? handle_special_var (v) : v;
     }
 
 #ifdef VMS
@@ -814,9 +842,10 @@ do_variable_definition (flocp, varname, value, origin, flavor, target_var)
           {
             /* Paste the old and new values together in VALUE.  */
 
-            unsigned int oldlen, newlen;
+            unsigned int oldlen, vallen;
+            char *val;
 
-            p = value;
+            val = value;
             if (v->recursive)
               /* The previous definition of the variable was recursive.
                  The new value is the unexpanded old and new values. */
@@ -827,14 +856,14 @@ do_variable_definition (flocp, varname, value, origin, flavor, target_var)
                  when it was set; and from the expanded new value.  Allocate
                  memory for the expansion as we may still need the rest of the
                  buffer if we're looking at a target-specific variable.  */
-              p = alloc_value = allocated_variable_expand (p);
+              val = alloc_value = allocated_variable_expand (val);
 
             oldlen = strlen (v->value);
-            newlen = strlen (p);
-            p = (char *) alloca (oldlen + 1 + newlen + 1);
+            vallen = strlen (val);
+            p = (char *) alloca (oldlen + 1 + vallen + 1);
             bcopy (v->value, p, oldlen);
             p[oldlen] = ' ';
-            bcopy (value, &p[oldlen + 1], newlen + 1);
+            bcopy (val, &p[oldlen + 1], vallen + 1);
           }
       }
     }
index 15661b587473d2f6370d658140ba88f3eb6990bc..d9cd7f7c7d200224b9bf4e498c759b8d9e9e368b 100644 (file)
@@ -60,6 +60,7 @@ struct variable
     unsigned int per_target:1; /* Nonzero if a target-specific variable.  */
     unsigned int append:1;     /* Nonzero if an appending target-specific
                                    variable.  */
+    unsigned int special:1;     /* Nonzero if this is a special variable. */
     unsigned int expanding:1;  /* Nonzero if currently being expanded.  */
     unsigned int exp_count:EXP_COUNT_BITS;
                                 /* If >1, allow this many self-referential