summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2002-07-09 06:35:56 +0000
committerPaul Smith <psmith@gnu.org>2002-07-09 06:35:56 +0000
commit6c9a393f954805d49ab6c66957b46199ddd6e78e (patch)
tree88a3c6a2e807a1356d4bcca1ecca91a6cc037ee5
parent724925be2b9a48f7911ee6baa315b872bd86995c (diff)
downloadgunmake-6c9a393f954805d49ab6c66957b46199ddd6e78e.tar.gz
Documentation and tests for order-only prerequisites.
Add a new test suite for automatic variables.
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog20
-rw-r--r--NEWS7
-rw-r--r--commands.c2
-rw-r--r--doc/make.texi48
-rw-r--r--file.c19
-rw-r--r--read.c11
-rw-r--r--tests/ChangeLog8
-rw-r--r--tests/scripts/features/order_only47
-rw-r--r--tests/scripts/variables/automatic50
10 files changed, 196 insertions, 17 deletions
diff --git a/AUTHORS b/AUTHORS
index e3acf48..88d61c3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -47,6 +47,7 @@ Other contributors:
Jim Kelton <jim_kelton@tivoli.com>
David Lubbren <uhay@rz.uni-karlsruhe.de>
Tim Magill <tim.magill@telops.gte.com>
+ Greg McGary <greg@mcgary.org>
Han-Wen Nienhuys <hanwen@cs.uu.nl>
Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Carl Staelin (Princeton University)
diff --git a/ChangeLog b/ChangeLog
index 65ba46f..97e88bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,25 @@
+2002-07-09 Paul D. Smith <psmith@gnu.org>
+
+ * doc/make.texi (Prerequisite Types): Add a new section describing
+ order-only prerequisites.
+
+ * read.c (uniquize_deps): If we have the same file as both a
+ normal and order-only prereq, get rid of the order-only prereq,
+ since the normal one supersedes it.
+
2002-07-08 Paul D. Smith <psmith@gnu.org>
+ * AUTHORS: Added Greg McGary to the AUTHORS file.
+ * NEWS: Blurbed order-only prerequisites.
+ * file.c (print_file): Show order-only deps properly when printing
+ the database.
+
* maintMakefile: Add "update" targets for wget'ing the latest
versions of various external files. Taken from Makefile.maint in
autoconf, etc.
- * dosbuild.bat: Somehow we got _extra_ ^M's. Remove them.
- Reported by Eli Zaretskii <eliz@is.elta.co.il>.
+ * dosbuild.bat: Somehow we got _double_ ^M's. Remove them.
+ Reported by Eli Zaretskii <eliz@is.elta.co.il>.
2002-07-07 Paul D. Smith <psmith@gnu.org>
@@ -22,7 +36,7 @@
* implicit.c (pattern_search): Some systems apparently run short
of stack space, and using alloca() in this function caused an
overrun. I modified it to use xmalloc() on the two variables
- which seemed like they might get large. Bug #476.
+ which seemed like they might get large. Fixes Bug #476.
* main.c (print_version): Update copyright notice to conform with
GNU standards.
diff --git a/NEWS b/NEWS
index 0237ae4..4c73093 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,13 @@ reports.
Version <next>
+* A new feature exists: order-only prerequisites. These prerequisites
+ affect the order in which targets are built, but they do not impact
+ the rebuild/no-rebuild decision of their dependents. That is to say,
+ they allow you to require target B be built before target A, without
+ requiring that target A will always be rebuilt if target B is updated.
+ Patch for this feature provided by Greg McGary <greg@mcgary.org>.
+
* A new function is defined: $(quote ...). The argument to this
function is the _name_ of a variable. The result of the function is
the value of the variable, without having been expanded.
diff --git a/commands.c b/commands.c
index 19a175e..f6baefc 100644
--- a/commands.c
+++ b/commands.c
@@ -124,7 +124,7 @@ set_file_variables (file)
DEFINE_VARIABLE ("@", 1, at);
DEFINE_VARIABLE ("%", 1, percent);
- /* Compute the values for $^, $+, and $?. */
+ /* Compute the values for $^, $+, $?, and $|. */
{
unsigned int qmark_len, plus_len, bar_len;
diff --git a/doc/make.texi b/doc/make.texi
index 20fc1c8..6fac114 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -158,6 +158,7 @@ Writing Rules
* Rule Example:: An example explained.
* Rule Syntax:: General syntax explained.
+* Prerequisite Types:: There are two types of prerequisites.
* Wildcards:: Using wildcard characters such as `*'.
* Directory Search:: Searching other directories for source files.
* Phony Targets:: Using a target that is not a real file's name.
@@ -1473,6 +1474,7 @@ the makefile (often with a target called @samp{all}).
@menu
* Rule Example:: An example explained.
* Rule Syntax:: General syntax explained.
+* Prerequisite Types:: There are two types of prerequisites.
* Wildcards:: Using wildcard characters such as `*'.
* Directory Search:: Searching other directories for source files.
* Phony Targets:: Using a target that is not a real file's name.
@@ -1524,7 +1526,7 @@ added to the prerequisites.
@end itemize
@end ifinfo
-@node Rule Syntax, Wildcards, Rule Example, Rules
+@node Rule Syntax, Prerequisite Types, Rule Example, Rules
@section Rule Syntax
@cindex rule syntax
@@ -1593,7 +1595,49 @@ How to update is specified by @var{commands}. These are lines to be
executed by the shell (normally @samp{sh}), but with some extra features
(@pxref{Commands, ,Writing the Commands in Rules}).
-@node Wildcards, Directory Search, Rule Syntax, Rules
+@node Prerequisite Types, Wildcards, Rule Syntax, Rules
+@comment node-name, next, previous, up
+@section Types of Prerequisites
+@cindex prerequisite types
+@cindex types of prerequisites
+
+@cindex prerequisites, normal
+@cindex normal prerequisites
+@cindex prerequisites, order-only
+@cindex order-only prerequisites
+There are actually two different types of prerequisites understood by
+GNU @code{make}: normal prerequisites such as described in the
+previous section, and @dfn{order-only} prerequisites. A normal
+prerequisite actually makes two statements: first, it imposes an order
+of execution of build commands: any commands necessary to build any of
+a target's prerequisites will be fully executed before any commands
+necessary to build the target. Second, it imposes a dependency
+relationship: if any prerequisite is newer than the target, then the
+target is considered out-of-date and must be rebuilt.
+
+Normally, this is exactly what you want: if a target's prerequisite is
+updated, then the target should also be updated.
+
+Occasionally, however, you have a situation where you want to impose a
+specific ordering on the rules to be invoked @emph{without} forcing
+the target to be updated if one of those rules is executed. In that
+case, you want to define @dfn{order-only} prerequisites. Order-only
+prerequisites can be specified by placing a pipe symbol (@code{|})
+in the prerequisites list: any prerequisites to the left of the pipe
+symbol are normal; any prerequisites to the right are order-only:
+
+@example
+@var{targets} : @var{normal-prerequisites} | @var{order-only-prerequisites}
+@end example
+
+The normal prerequisites section may of course be empty. Also, you
+may still declare multiple lines of prerequisites for the same target:
+they are appended appropriately. Note that if you declare the same
+file to be both a normal and an order-only prerequisite, the normal
+prerequisite takes precedence (since they are a strict superset of the
+behavior of an order-only prerequisite).
+
+@node Wildcards, Directory Search, Prerequisite Types, Rules
@section Using Wildcard Characters in File Names
@cindex wildcard
@cindex file name with wildcards
diff --git a/file.c b/file.c
index 2602810..1e87443 100644
--- a/file.c
+++ b/file.c
@@ -680,15 +680,30 @@ static void
print_file (f)
struct file *f;
{
- register struct dep *d;
+ struct dep *d;
+ struct dep *ood = 0;
putchar ('\n');
if (!f->is_target)
puts (_("# Not a target:"));
printf ("%s:%s", f->name, f->double_colon ? ":" : "");
+ /* Print all normal dependencies; note any order-only deps. */
for (d = f->deps; d != 0; d = d->next)
- printf (" %s", dep_name (d));
+ if (! d->ignore_mtime)
+ printf (" %s", dep_name (d));
+ else if (! ood)
+ ood = d;
+
+ /* Print order-only deps, if we have any. */
+ if (ood)
+ {
+ printf (" | %s", dep_name (ood));
+ for (d = ood->next; d != 0; d = d->next)
+ if (d->ignore_mtime)
+ printf (" %s", dep_name (d));
+ }
+
putchar ('\n');
if (f->precious)
diff --git a/read.c b/read.c
index 510266a..4b7c79c 100644
--- a/read.c
+++ b/read.c
@@ -1524,10 +1524,17 @@ uniquize_deps (chain)
last = d;
next = d->next;
while (next != 0)
- if (streq (dep_name (d), dep_name (next))
- && d->ignore_mtime == next->ignore_mtime)
+ if (streq (dep_name (d), dep_name (next)))
{
struct dep *n = next->next;
+ /* If ignore_mtimes are not equal, one of these is an order-only
+ prerequisite and one isn't. That means that we should remove
+ the one that isn't and keep the one that is. Ideally we'd
+ like to keep the normal one always but that's hard, and
+ probably not very important, so just remove the second one and
+ force the first one to be normal. */
+ if (d->ignore_mtime != next->ignore_mtime)
+ d->ignore_mtime = 0;
last->next = n;
if (next->name != 0 && next->name != d->name)
free (next->name);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index aa5f78d..fec5186 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+2002-07-09 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/variables/automatic: Create a test for automatic variables.
+
+2002-07-08 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/features/order_only: Test new order-only prerequisites.
+
2002-07-07 Paul D. Smith <psmith@gnu.org>
* scripts/functions/eval: Test new function.
diff --git a/tests/scripts/features/order_only b/tests/scripts/features/order_only
index 81284c5..e324d68 100644
--- a/tests/scripts/features/order_only
+++ b/tests/scripts/features/order_only
@@ -10,7 +10,6 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
foo: bar | baz
@echo '$$^ = $^'
- @echo '$$? = $?'
@echo '$$| = $|'
touch $@
@@ -26,7 +25,7 @@ close(MAKEFILE);
# TEST #1 -- just the syntax
&run_make_with_options($makefile, "", &get_logfile);
-$answer = "touch bar\ntouch baz\n\$^ = bar\n\$? = bar\n\$| = baz\ntouch foo\n";
+$answer = "touch bar\ntouch baz\n\$^ = bar\n\$| = baz\ntouch foo\n";
&compare_output($answer,&get_logfile(1));
@@ -47,7 +46,6 @@ open(MAKEFILE,"> $makefile2");
print MAKEFILE <<'EOF';
foo: bar | baz
@echo '$$^ = $^'
- @echo '$$? = $?'
@echo '$$| = $|'
touch $@
@@ -61,19 +59,54 @@ EOF
close(MAKEFILE);
-# TEST #3 -- just the syntax
+# TEST #3 -- Make sure the order-only prereq was promoted to normal.
&run_make_with_options($makefile2, "", &get_logfile);
-$answer = "touch bar\ntouch baz\n\$^ = bar baz\n\$? = bar baz\n\$| = baz\ntouch foo\n";
+$answer = "touch bar\ntouch baz\n\$^ = bar baz\n\$| = \ntouch foo\n";
&compare_output($answer,&get_logfile(1));
-# TEST #2 -- now we do it again: baz is PHONY but foo should _NOT_ be updated
+# TEST #4 -- now we do it again
&run_make_with_options($makefile2, "", &get_logfile);
-$answer = "touch baz\$^ = bar baz\n\$? = baz\n\$| = baz\ntouch foo\n";
+$answer = "touch baz\n\$^ = bar baz\n\$| = \ntouch foo\n";
&compare_output($answer,&get_logfile(1));
unlink(qw(foo bar baz));
+# Test empty normal prereqs
+
+$makefile3 = &get_tmpfile;
+
+open(MAKEFILE,"> $makefile3");
+
+print MAKEFILE <<'EOF';
+foo:| baz
+ @echo '$$^ = $^'
+ @echo '$$| = $|'
+ touch $@
+
+.PHONY: baz
+
+baz:
+ touch $@
+EOF
+
+close(MAKEFILE);
+
+# TEST #5 -- make sure the parser was correct.
+
+&run_make_with_options($makefile3, "", &get_logfile);
+$answer = "touch baz\n\$^ = \n\$| = baz\ntouch foo\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST #6 -- now we do it again: this time foo won't be built
+
+&run_make_with_options($makefile3, "", &get_logfile);
+$answer = "touch baz\n";
+&compare_output($answer,&get_logfile(1));
+
+unlink(qw(foo baz));
+
1;
diff --git a/tests/scripts/variables/automatic b/tests/scripts/variables/automatic
new file mode 100644
index 0000000..b80d478
--- /dev/null
+++ b/tests/scripts/variables/automatic
@@ -0,0 +1,50 @@
+# -*-perl-*-
+
+$description = "Test automatic variable setting.";
+
+$details = "";
+
+use Cwd;
+
+$dir = cwd;
+$dir =~ s,.*/([^/]+)$,../$1,;
+
+open(MAKEFILE, "> $makefile");
+print MAKEFILE "dir = $dir\n";
+print MAKEFILE <<'EOF';
+.SUFFIXES:
+.SUFFIXES: .x .y .z
+$(dir)/foo.x : baz.z $(dir)/bar.y baz.z
+ @echo '$$@ = $@, $$(@D) = $(@D), $$(@F) = $(@F)'
+ @echo '$$* = $*, $$(*D) = $(*D), $$(*F) = $(*F)'
+ @echo '$$< = $<, $$(<D) = $(<D), $$(<F) = $(<F)'
+ @echo '$$^ = $^, $$(^D) = $(^D), $$(^F) = $(^F)'
+ @echo '$$+ = $+, $$(+D) = $(+D), $$(+F) = $(+F)'
+ @echo '$$? = $?, $$(?D) = $(?D), $$(?F) = $(?F)'
+ touch $@
+
+$(dir)/bar.y baz.z : ; touch $@
+EOF
+close(MAKEFILE);
+
+# TEST #1 -- simple test
+# -------
+
+&touch(qw(foo.x baz.z));
+
+sleep(1);
+
+&run_make_with_options($makefile, "", &get_logfile);
+$answer = "touch $dir/bar.y
+\$\@ = $dir/foo.x, \$(\@D) = $dir, \$(\@F) = foo.x
+\$* = $dir/foo, \$(*D) = $dir, \$(*F) = foo
+\$< = baz.z, \$(<D) = ., \$(<F) = baz.z
+\$^ = baz.z $dir/bar.y, \$(^D) = . $dir, \$(^F) = baz.z bar.y
+\$+ = baz.z $dir/bar.y baz.z, \$(+D) = . $dir ., \$(+F) = baz.z bar.y baz.z
+\$? = $dir/bar.y, \$(?D) = $dir, \$(?F) = bar.y
+touch $dir/foo.x\n";
+&compare_output($answer, &get_logfile(1));
+
+unlink(qw(foo.x bar.y baz.z));
+
+1;