decided to implement this a different way, and didn't use it.
+2002-07-10 Paul D. Smith <psmith@gnu.org>
+
+ Implement the SysV make syntax $$@, $$(@D), and $$(@F) in the
+ prerequisite list. A real SysV make will expand the entire
+ prerequisites list _twice_: we don't do that as it's a big
+ backward-compatibility problem. We only replace those specific
+ variables.
+
+ * read.c (record_files): Replace any $@, $(@D), and $(@F) variable
+ references left in the list of prerequisites. Check for .POSIX as
+ we record targets, so we can disable non-POSIX behavior while
+ reading makefiles as well as running them.
+ (eval): Check the prerequisite list to see if we have anything
+ that looks like a SysV prerequisite variable reference.
+
2002-07-09 Paul D. Smith <psmith@gnu.org>
* doc/make.texi (Prerequisite Types): Add a new section describing
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
- 06 July 2002
+ 10 July 2002
Copyright (C) 2002 Free Software Foundation, Inc.
See the end for copying conditions.
See the README file and the GNU make manual for details on sending bug
reports.
\f
-Version <next>
+Version 3.80
* A new feature exists: order-only prerequisites. These prerequisites
affect the order in which targets are built, but they do not impact
requiring that target A will always be rebuilt if target B is updated.
Patch for this feature provided by Greg McGary <greg@mcgary.org>.
+* For compatibility with SysV make, GNU make now supports the peculiar
+ syntax $$@, $$(@D), and $$(@F) in the prerequisites list of a rule.
+ This syntax is only valid within explicit and static pattern rules: it
+ cannot be used in implicit (suffix or pattern) rules. Edouard G. Parmelan
+ <egp@free.fr> provided a patch implementing this feature; however, I
+ decided to implemented it myself in a different way.
+
* 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.
Lists of the directory parts and the file-within-directory
parts of all prerequisites.
+@vindex $(+D)
+@vindex +D @r{(automatic variable)}
+@item $(+D)
+@vindex $(+F)
+@vindex +F @r{(automatic variable)}
+@itemx $(+F)
+Lists of the directory parts and the file-within-directory
+parts of all prerequisites, including multiple instances of duplicated
+prerequisites.
+
@vindex $(?D)
@vindex ?D @r{(automatic variable)}
@item $(?D)
as @samp{$(CFLAGS)} refers to the variable named @code{CFLAGS}.
You could just as well use @samp{$(<)} in place of @samp{$<}.
+@vindex $$@@
+@vindex $$(@@D)
+@vindex $$(@@F)
+@cindex $$@@, support for
+GNU @code{make} provides support for the SysV @code{make} feature that
+allows special variable references @code{$$@@}, @code{$$(@@D)}, and
+@code{$$(@@F)} (note the required double-''$''!) to appear with the
+@emph{prerequisites list} (normal automatic variables are available
+only within a command script). When appearing in a prerequisites
+list, these variables are expanded to the name of the target, the
+directory component of the target, and the file component of the
+target, respectively.
+
+Note that these variables are available only within explicit and
+static pattern (@pxref{Static Pattern, ,Static Pattern Rules}) rules;
+they have no special significance within implicit (suffix or pattern)
+rules. Also note that while SysV @code{make} actually expands its
+entire prerequisite list @emph{twice}, GNU @code{make} does not behave
+this way: instead it simply expands these special variables without
+re-expanding any other part of the prerequisites list.
+
+This somewhat bizarre feature is included only to provide some
+compatibility with SysV makefiles. In a native GNU @code{make} file
+there are other ways to accomplish the same results. This feature is
+disabled if the special pseudo target @code{.POSIX} is defined.
+
@node Pattern Match, Match-Anything Rules, Automatic, Pattern Rules
@subsection How Patterns Match
@xref{Chained Rules, ,Chains of Implicit Rules}.
@item
-In System V @code{make}, the string @samp{$$@@} has the strange meaning
-that, in the prerequisites of a rule with multiple targets, it stands
-for the particular target that is being processed.
-
-This is not defined in GNU @code{make} because @samp{$$} should always
-stand for an ordinary @samp{$}.
-
-It is possible to get portions of this functionality through the use of
-static pattern rules (@pxref{Static Pattern, ,Static Pattern Rules}).
-The System V @code{make} rule:
-
-@example
-$(targets): $$@@.o lib.a
-@end example
-
-@noindent
-can be replaced with the GNU @code{make} static pattern rule:
-
-@example
-$(targets): %: %.o lib.a
-@end example
-
-@item
In System V and 4.3 BSD @code{make}, files found by @code{VPATH} search
(@pxref{Directory Search, ,Searching Directories for Prerequisites}) have their names changed inside command
strings. We feel it is much cleaner to always use automatic variables
}
if (!remote_description || *remote_description == '\0')
- fprintf (usageto, _("\nBuilt for %s"), make_host);
+ fprintf (usageto, _("\nThis program built for %s"), make_host);
else
- fprintf (usageto, "\nBuilt for %s (%s)", make_host, remote_description);
+ fprintf (usageto, "\nThis program built for %s (%s)", make_host, remote_description);
fprintf (usageto, _("\nReport bugs to <bug-make@gnu.org>\n"));
}
-*.gmo *.mo *.pot
+*.gmo *.mo *.pot *.po
Makefile.in Makefile
+POTFILES
static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent,
struct dep *deps, unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
- const struct floc *flocp, int set_default));
+ int have_sysv_atvar,
+ const struct floc *flocp, int set_default));
static void record_target_var PARAMS ((struct nameseq *filenames, char *defn,
int two_colon,
enum variable_origin origin,
unsigned int cmds_started, tgts_started;
int ignoring = 0, in_ignored_define = 0;
int no_targets = 0; /* Set when reading a rule without targets. */
+ int have_sysv_atvar = 0;
struct nameseq *filenames = 0;
struct dep *deps = 0;
long nlines = 0;
fi.lineno = tgts_started; \
record_files (filenames, pattern, pattern_percent, deps, \
cmds_started, commands, commands_idx, two_colon, \
- &fi, set_default); \
+ have_sysv_atvar, &fi, set_default); \
} \
filenames = 0; \
commands_idx = 0; \
}
}
+ /* Do any of the prerequisites appear to have $@ etc.? */
+ have_sysv_atvar = 0;
+ if (!posix_pedantic)
+ for (p = strchr (p2, '$'); p != 0; p = strchr (p+1, '$'))
+ if (p[1] == '@' || (p[1] == '(' && p[2] == '@'))
+ {
+ have_sysv_atvar = 1;
+ break;
+ }
+
/* Is this a static pattern rule: `target: %targ: %dep; ...'? */
p = strchr (p2, ':');
while (p != 0 && p[-1] == '\\')
static void
record_files (filenames, pattern, pattern_percent, deps, cmds_started,
- commands, commands_idx, two_colon, flocp, set_default)
+ commands, commands_idx, two_colon, have_sysv_atvar,
+ flocp, set_default)
struct nameseq *filenames;
char *pattern, *pattern_percent;
struct dep *deps;
char *commands;
unsigned int commands_idx;
int two_colon;
+ int have_sysv_atvar;
const struct floc *flocp;
int set_default;
{
for (; filenames != 0; filenames = nextf)
{
-
- register char *name = filenames->name;
- register struct file *f;
- register struct dep *d;
+ char *name = filenames->name;
+ struct file *f;
+ struct dep *d;
struct dep *this;
char *implicit_percent;
nextf = filenames->next;
free (filenames);
+ /* Check for .POSIX. We used to do this in snap_deps() but that's not
+ good enough: it doesn't happen until after the makefile is read,
+ which means we cannot use its value during parsing. */
+
+ if (streq (name, ".POSIX"))
+ posix_pedantic = 1;
+
implicit_percent = find_percent (name);
implicit |= implicit_percent != 0;
}
}
+ /* If at least one of the dependencies uses $$@ etc. deal with that.
+ It would be very nice and very simple to just expand everything, but
+ it would break a lot of backward compatibility. Maybe that's OK
+ since we're just emulating a SysV function, and if we do that then
+ why not emulate it completely (that's what SysV make does: it
+ re-expands the entire prerequisite list, all the time, with $@
+ etc. in scope. But, it would be a pain indeed to document this
+ ("iff you use $$@, your prerequisite lists is expanded twice...")
+ Ouch. Maybe better to make the code more complex. */
+
+ if (have_sysv_atvar)
+ {
+ char *p;
+ int tlen = strlen (name);
+ char *fnp = strrchr (name, '/');
+ int dlen;
+ int flen;
+
+ if (fnp)
+ {
+ dlen = fnp - name;
+ ++fnp;
+ flen = strlen (fnp);
+ }
+ else
+ {
+ dlen = 0;
+ fnp = name;
+ flen = tlen;
+ }
+
+
+ for (d = this; d != 0; d = d->next)
+ for (p = strchr (d->name, '$'); p != 0; p = strchr (p+1, '$'))
+ {
+ char *s = p;
+ char *at;
+ int atlen;
+
+ /* If it's a '$@' or '$(@', it's escaped */
+ if ((++p)[0] == '$'
+ && (p[1] == '@' || (p[1] == '(' && p[2] == '@')))
+ {
+ bcopy (p, s, strlen (p)+1);
+ continue;
+ }
+
+ /* Maybe found one. Check. p will point to '@' [for $@] or
+ ')' [for $(@)] or 'D' [for $(@D)] or 'F' [for $(@F)]. */
+ if (p[0] != '@'
+ && (p[0] != '(' || (++p)[0] != '@'
+ || ((++p)[0] != ')'
+ && (p[1] != ')' || (p[0] != 'D' && p[0] != 'F')))))
+ continue;
+
+ /* Found one. Compute the length and string ptr. Move p
+ past the variable reference. */
+ switch (p[0])
+ {
+ case 'D':
+ atlen = dlen;
+ at = name;
+ p += 2;
+ break;
+
+ case 'F':
+ atlen = flen;
+ at = fnp;
+ p += 2;
+ break;
+
+ default:
+ atlen = tlen;
+ at = name;
+ ++p;
+ break;
+ }
+
+ /* Get more space. */
+ {
+ int soff = s - d->name;
+ int poff = p - d->name;
+ d->name = (char *) xrealloc (d->name,
+ strlen (d->name) + atlen + 1);
+ s = d->name + soff;
+ p = d->name + poff;
+ }
+
+ /* Copy the string over. */
+ bcopy(p, s+atlen, strlen (p)+1);
+ bcopy(at, s, atlen);
+ p = s + atlen - 1;
+ }
+ }
+
if (!two_colon)
{
/* Single-colon. Combine these dependencies
+2002-07-10 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/variables/automatic: Add some tests for $$@, $$(@D), and
+ $$(@F).
+
2002-07-09 Paul D. Smith <psmith@gnu.org>
* scripts/variables/automatic: Create a test for automatic variables.
# TEST #1 -- simple test
# -------
-&touch(qw(foo.x baz.z));
-
-sleep(1);
+# Touch these into the past
+&utouch(-10, qw(foo.x baz.z));
&run_make_with_options($makefile, "", &get_logfile);
$answer = "touch $dir/bar.y
unlink(qw(foo.x bar.y baz.z));
+# TEST #2 -- test the SysV emulation of $$@ etc.
+# -------
+
+$makefile2 = &get_tmpfile;
+
+open(MAKEFILE, "> $makefile2");
+print MAKEFILE "dir = $dir\n";
+print MAKEFILE <<'EOF';
+.SUFFIXES:
+.DEFAULT: ; @echo '$@'
+
+$(dir)/foo $(dir)/bar: $@.x $$@.x $$$@.x $$$$@.x $$(@D).x $$(@F).x
+
+$(dir)/x.z $(dir)/y.z: $(dir)/%.z : $@.% $$@.% $$$@.% $$$$@.% $$(@D).% $$(@F).%
+EOF
+
+&run_make_with_options($makefile2, "$dir/foo $dir/bar", &get_logfile);
+$answer = ".x\n$dir/foo.x\n\$.x\n\$@.x\n$dir.x\nfoo.x\n$dir/bar.x\nbar.x\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile2, "$dir/x.z $dir/y.z", &get_logfile);
+$answer = ".x\n$dir/x.z.x\n\$.x\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\n\$.y\n\$@.y\n$dir.y\ny.z.y\n";
+&compare_output($answer, &get_logfile(1));
+
1;
sub touch
{
- local (@filenames) = @_;
local ($file);
- foreach $file (@filenames) {
+ foreach $file (@_) {
(open(T, ">> $file") && print(T "\n") && close(T))
|| &error("Couldn't touch $file: $!\n", 1);
}
}
+# Touch with a time offset. To DTRT, call touch() then use stat() to get the
+# access/mod time for each file and apply the offset.
+
+sub utouch
+{
+ local ($off) = shift;
+ local ($file);
+
+ &touch(@_);
+
+ local (@s) = stat($_[0]);
+
+ utime($s[8]+$off, $s[9]+$off, @_);
+}
+
# open a file, write some stuff to it, and close it.
sub create_file