Fix for complex situations where directories are declared as prerequisites.
authorPaul Smith <psmith@gnu.org>
Wed, 4 Sep 2002 07:26:19 +0000 (07:26 +0000)
committerPaul Smith <psmith@gnu.org>
Wed, 4 Sep 2002 07:26:19 +0000 (07:26 +0000)
Info on this fix from barkalow@reputation.com: thanks!

Some updates/cleanups of some of the tests; added a forgotten -t test, etc.

14 files changed:
ChangeLog
configure.in
doc/make.texi
implicit.c
tests/ChangeLog
tests/scripts/features/reinvoke
tests/scripts/features/vpathgpath
tests/scripts/features/vpathplus
tests/scripts/misc/general4 [new file with mode: 0644]
tests/scripts/misc/version [deleted file]
tests/scripts/options/dash-n
tests/scripts/options/dash-t [new file with mode: 0644]
tests/scripts/targets/INTERMEDIATE
tests/scripts/targets/SECONDARY

index 5b1f72b..55dfbc4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-09-04  Paul D. Smith  <psmith@gnu.org>
+
+       * implicit.c (pattern_search): Daniel <barkalow@reputation.com>
+       reports that GNU make sometimes doesn't recognize that targets can
+       be made, when directories can be created as prerequisites.  He
+       reports changing the order of predicates in the DEP->changed flag
+       test so that lookup_file() is always performed, solves this
+       problem.
+
 2002-08-08  Paul D. Smith  <psmith@gnu.org>
 
        * configure.in: Require a newer version of gettext.
index 1f5cdd7..4507f0a 100644 (file)
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT(GNU make,3.80b2,bug-make@gnu.org)
+AC_INIT(GNU make,3.80rc2,bug-make@gnu.org)
 
 AC_PREREQ(2.53)
 
index b36383a..4ef1107 100644 (file)
@@ -999,13 +999,25 @@ Defining a variable from a verbatim string containing multiple lines
 @cindex comments, in makefile
 @cindex @code{#} (comments), in makefile
 @item
-@samp{#} in a line of a makefile starts a @dfn{comment}.  It and the rest of
-the line are ignored, except that a trailing backslash not escaped by
-another backslash will continue the comment across multiple lines.
-Comments may appear on any of the lines in the makefile, except within a
-@code{define} directive, and perhaps within commands (where the shell
-decides what is a comment).  A line containing just a comment (with
-perhaps spaces before it) is effectively blank, and is ignored.@refill
+@samp{#} in a line of a makefile starts a @dfn{comment}.  It and the
+rest of the line are ignored, except that a trailing backslash not
+escaped by another backslash will continue the comment across multiple
+lines.  A line containing just a comment (with perhaps spaces before
+it) is effectively blank, and is ignored.  If you want a literal
+@code{#}, escape it with a backslash (e.g., @code{\#}).  Comments may
+appear on any line in the makefile, although they are treated
+specially in certain situations.
+
+Within a command script (if the line begins with a TAB character) the
+entire line is passed to the shell, just as with any other line that
+begins with a TAB.  The shell decides how to interpret the text:
+whether or not this is a comment is up to the shell.
+
+Within a @code{define} directive, comments are not ignored during the
+definition of the variable, but rather kept intact in the value of the
+variable.  When the variable is expanded they will either be treated
+as @code{make} comments or as command script text, depending on the
+context in which the variable is evaluated.
 @end itemize
 
 @node Makefile Names, Include, Makefile Contents, Makefiles
@@ -2322,10 +2334,11 @@ clean:
 @end example
 
 Another example of the usefulness of phony targets is in conjunction
-with recursive invocations of @code{make}.  In this case the makefile
-will often contain a variable which lists a number of subdirectories to
-be built.  One way to handle this is with one rule whose command is a
-shell loop over the subdirectories, like this:
+with recursive invocations of @code{make} (for more information, see
+@ref{Recursion, ,Recursive Use of @code{make}}).  In this case the
+makefile will often contain a variable which lists a number of
+subdirectories to be built.  One way to handle this is with one rule
+whose command is a shell loop over the subdirectories, like this:
 
 @example
 @group
@@ -3597,7 +3610,10 @@ subsystem:
 
 You can write recursive @code{make} commands just by copying this example,
 but there are many things to know about how they work and why, and about
-how the sub-@code{make} relates to the top-level @code{make}.
+how the sub-@code{make} relates to the top-level @code{make}.  You may
+also find it useful to declare targets that invoke recursive
+@code{make} commands as @samp{.PHONY} (for more discussion on when
+this is useful, see @ref{Phony Targets}).
 
 For your convenience, GNU @code{make} sets the variable @code{CURDIR} to
 the pathname of the current working directory for you.  If @code{-C} is
index 0ce7a49..857895d 100644 (file)
@@ -399,8 +399,8 @@ pattern_search (file, archive, depth, recursions)
                 directory (the one gotten by prepending FILENAME's directory),
                 so it might actually exist.  */
 
-             if ((!dep->changed || check_lastslash)
-                 && (lookup_file (p) != 0 || file_exists_p (p)))
+             if (lookup_file (p) != 0
+                 || ((!dep->changed || check_lastslash) && file_exists_p (p)))
                {
                  found_files[deps_found++] = xstrdup (p);
                  continue;
index 387c08f..7336bd3 100644 (file)
@@ -1,3 +1,22 @@
+2002-09-04  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/features/reinvoke: Change touch/sleep combos to utouch
+       invocations.
+       * scripts/features/vpathgpath: Ditto.
+       * scripts/features/vpathplus: Ditto.
+       * scripts/options/dash-n: Ditto.
+       * scripts/targets/INTERMEDIATE: Ditto.
+       * scripts/targets/SECONDARY: Ditto.
+
+       * scripts/options/dash-t: Added a test for the -t bug fixed by
+       Henning Makholm.  This test was also contributed by Henning.
+
+       * scripts/misc/general4: Add a test suite for obscure algorithmic
+       features of make.  First test: make sure creation subdirectories
+       as prerequisites of targets works properly.
+
+       * scripts/misc/version: Remove this bogus test.
+
 2002-08-07  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/misc/general3: Add a test for makefiles that don't end
        * scripts/variables/automatic: Add some tests for $$@, $$(@D), and
        $$(@F).
 
+       * test_driver.pl (utouch): Create a new function that creates a
+       file with a specific timestamp offset.  Use of this function will
+       let us avoid lots of annoying sleep() invocations in the tests
+       just to get proper timestamping, which will make the tests run a
+       lot faster.  So far it's only used in the automatic test suite.
+
 2002-07-09  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/variables/automatic: Create a test for automatic variables.
index 3e9ae66..a5a475c 100644 (file)
@@ -18,7 +18,6 @@ all: ; \@echo 'running rules.'
 
 $makefile $makefile2: $makefile_orig
        \@echo 'rebuilding \$\@.'
-       \@sleep $wtime
        \@echo >> \$\@
 
 include $makefile2
@@ -27,13 +26,8 @@ EOM
 
 close(MAKEFILE);
 
-&touch($makefile2);
-
-# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
-# granularity of file times.
-sleep($wtime);
-
-&touch("$makefile_orig");
+&utouch(-10, $makefile, $makefile2);
+&touch($makefile_orig);
 
 &run_make_with_options($makefile, "", &get_logfile, 0);
 
@@ -66,9 +60,8 @@ EOM
 
 close(MAKEFILE);
 
-&touch('b');
-&touch('a');
-sleep($wtime);
+&utouch(-20, 'b','a');
+#&utouch(-10, 'a');
 &touch('c');
 
 # First try with the file that's not updated "once removed" from the
index 581d16d..f7683f5 100644 (file)
@@ -38,12 +38,14 @@ close(MAKEFILE);
 
 @touchedfiles = ();
 
+$off = -500;
+
 sub touchfiles {
   foreach (@_) {
     ($f = $_) =~ s,VP/,$VP,g;
-    &touch($f);
+    &utouch($off, $f);
+    $off += 10;
     push(@touchedfiles, $f);
-    sleep(1);
   }
 }
 
index 76312b3..a37fbed 100644 (file)
@@ -55,18 +55,19 @@ close(MAKEFILE);
 
 @touchedfiles = ();
 
+$off = -500;
+
 sub touchfiles {
   foreach (@_) {
-    sleep($wtime);
-    ($f = $_) =~ s,VP/,$VP,g;
-    &touch($f);
-    push(@touchedfiles, $f);
+    &utouch($off, $_);
+    $off += 10;
+    push(@touchedfiles, $_);
   }
 }
 
 # Run the general-case test
 
-&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d");
+&touchfiles("$VP/foo.d", "$VP/bar.d", "$VP/foo.c", "$VP/bar.c", "foo.b", "bar.d");
 
 &run_make_with_options($makefile,"general",&get_logfile);
 
@@ -79,7 +80,7 @@ cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1
 
 # Test rules that don't make the target correctly
 
-&touchfiles("VP/notarget.c", "notarget.b", "notarget.d");
+&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d");
 
 &run_make_with_options($makefile,"notarget",&get_logfile,512);
 
@@ -92,7 +93,7 @@ $make_name: *** [notarget.b] Error 1
 
 # Test intermediate file handling (part 1)
 
-&touchfiles("VP/inter.d");
+&touchfiles("$VP/inter.d");
 
 &run_make_with_options($makefile,"intermediate",&get_logfile);
 
@@ -107,7 +108,11 @@ rm inter.b inter.c
 
 # Test intermediate file handling (part 2)
 
-&touchfiles("VP/inter.b", "VP/inter.d");
+&utouch(-20, "inter.a");
+&utouch(-10, "$VP/inter.b");
+&touch("$VP/inter.d");
+
+push(@touchedfiles, "$VP/inter.b", "$VP/inter.d");
 
 &run_make_with_options($makefile,"intermediate",&get_logfile);
 
diff --git a/tests/scripts/misc/general4 b/tests/scripts/misc/general4
new file mode 100644 (file)
index 0000000..dd77f53
--- /dev/null
@@ -0,0 +1,31 @@
+#                                                                    -*-perl-*-
+
+$description = "\
+This tests random features of make's algorithms, often somewhat obscure,
+which have either broken at some point in the past or seem likely to
+break.";
+
+open(MAKEFILE,"> $makefile");
+
+# The contents of the Makefile ...
+
+print MAKEFILE <<'EOF';
+# Make sure that subdirectories built as prerequisites are actually handled
+# properly.
+
+all: dir/subdir/file.a
+
+dir/subdir: ; @echo mkdir -p dir/subdir
+
+dir/subdir/file.b: dir/subdir ; @echo touch dir/subdir/file.b
+
+dir/subdir/%.a: dir/subdir/%.b ; @echo cp $< $@
+EOF
+
+close(MAKEFILE);
+
+&run_make_with_options($makefile,"",&get_logfile);
+$answer = "mkdir -p dir/subdir\ntouch dir/subdir/file.b\ncp dir/subdir/file.b dir/subdir/file.a\n";
+&compare_output($answer,&get_logfile(1));
+
+1;
diff --git a/tests/scripts/misc/version b/tests/scripts/misc/version
deleted file mode 100644 (file)
index d49b153..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-$description = "The following test creates a makefile to ... \n";
-
-$details = "Fill in Later\n";
-
-open(MAKEFILE,"> $makefile");
-
-# The Contents of the MAKEFILE ...
-
-print MAKEFILE "all: \n";
-
-# END of Contents of MAKEFILE
-
-close(MAKEFILE);
-
-&run_make_with_options($makefile,"-v",&get_logfile,0);
-
-# This tells the test driver that the perl test script executed properly.
-1;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
index 35f317d..de19f42 100644 (file)
@@ -49,14 +49,8 @@ EOF
 
 close(MAKEFILE);
 
-&touch('b');
-# Sometimes, on my Solaris 2.5.1 box with a NetApp filesystem NFS-mounted,
-# just touching b first then a isn't good enough: the nsec field in the
-# stat result shows b is _newer_ than a once every 5 or 6 tries!!!  I've
-# no idea what this is about, but that's why there's a sleep(1) here...
-sleep(1);
-&touch('a');
-sleep(1);
+&utouch(-20, 'b');
+&utouch(-10, 'a');
 &touch('c');
 
 # TEST 2
diff --git a/tests/scripts/options/dash-t b/tests/scripts/options/dash-t
new file mode 100644 (file)
index 0000000..8192fbf
--- /dev/null
@@ -0,0 +1,38 @@
+#                                                                    -*-perl-*-
+
+$description = "Test the -t option.\n";
+
+$details = "Look out for regressions of prior bugs related to -t.\n";
+# That means, nobody has even tried to make the tests below comprehensive
+
+# TEST 0
+# bug reported by Henning Makholm <henning@makholm.net> on 2001-11-03:
+#   make 3.79.1 touches only interm-[ab] but reports final-[a] as
+#   'up to date' without touching them.
+# The 'obvious' fix didn't work for double-colon rules, so pay special
+# attention to them.
+
+open(MAKEFILE, "> $makefile");
+print MAKEFILE <<'EOMAKE';
+final-a: interm-a ; echo >> $@
+final-b: interm-b ; echo >> $@
+interm-a:: orig1-a ; echo >> $@
+interm-a:: orig2-a ; echo >> $@
+interm-b:: orig1-b ; echo >> $@
+interm-b:: orig2-b ; echo >> $@
+EOMAKE
+close(MAKEFILE);
+
+&utouch(-30, 'orig1-a','orig2-b');
+&utouch(-20, 'interm-a','interm-b');
+&utouch(-10, 'final-a','final-b');
+&touch('orig2-a','orig1-b');
+
+&run_make_with_options($makefile, "-t final-a final-b", &get_logfile);
+$answer = "touch interm-a\ntouch final-a\ntouch interm-b\ntouch final-b\n";
+&compare_output($answer, &get_logfile(1));
+
+unlink('orig1-a', 'orig2-a', 'interm-a', 'final-a');
+unlink('orig1-b', 'orig2-b', 'interm-b', 'final-b');
+
+1;
index 725ab0e..4fdd7a2 100644 (file)
@@ -33,9 +33,7 @@ close(MAKEFILE);
 
 # TEST #0
 
-&touch('foo.f');
-&touch('bar.f');
-sleep($wtime);
+&utouch(-20, 'foo.f', 'bar.f');
 
 &run_make_with_options($makefile,'foo.d',&get_logfile);
 $answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n";
@@ -49,7 +47,7 @@ $answer = "$make_name: `foo.d' is up to date.\n";
 
 # TEST #2
 
-sleep($wtime);
+&utouch(-10, 'foo.d');
 &touch('foo.f');
 
 &run_make_with_options($makefile,'foo.d',&get_logfile);
@@ -70,7 +68,7 @@ $answer = "$make_name: `foo.c' is up to date.\n";
 
 # TEST #5
 
-sleep($wtime);
+&utouch(-10, 'foo.c');
 &touch('foo.f');
 
 &run_make_with_options($makefile,'foo.c',&get_logfile);
index 3ae34fd..5a60ed2 100644 (file)
@@ -33,7 +33,7 @@ close(MAKEFILE);
 
 # TEST #1
 
-&touch('foo.f');
+&utouch(-20, 'foo.f');
 
 &run_make_with_options($makefile,'foo.d',&get_logfile);
 $answer = "cp foo.f foo.e\ncp foo.e foo.d\n";
@@ -49,7 +49,7 @@ $answer = "$make_name: `foo.d' is up to date.\n";
 
 # TEST #3
 
-sleep($wtime);
+&utouch(-10, 'foo.d');
 &touch('foo.f');
 
 &run_make_with_options($makefile,'foo.d',&get_logfile);
@@ -72,7 +72,7 @@ $answer = "$make_name: `foo.c' is up to date.\n";
 
 # TEST #6
 
-sleep($wtime);
+&utouch(-10, 'foo.c');
 &touch('foo.f');
 
 &run_make_with_options($makefile,'foo.c',&get_logfile);