Documentation and tests for order-only prerequisites.

Add a new test suite for automatic variables.
This commit is contained in:
Paul Smith 2002-07-09 06:35:56 +00:00
parent 724925be2b
commit 6c9a393f95
10 changed files with 196 additions and 17 deletions

View file

@ -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)

View file

@ -1,10 +1,24 @@
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.
* 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.

7
NEWS
View file

@ -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.

View file

@ -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;

View file

@ -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

17
file.c
View file

@ -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)
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)

11
read.c
View file

@ -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);

View file

@ -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.

View file

@ -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;

View file

@ -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;