Fix Savannah bugs # 15341, 15534, and 15533.
authorPaul Smith <psmith@gnu.org>
Mon, 6 Feb 2006 16:21:59 +0000 (16:21 +0000)
committerPaul Smith <psmith@gnu.org>
Mon, 6 Feb 2006 16:21:59 +0000 (16:21 +0000)
Rewrite large chunks of the "Commands" section of the manual to better
describe then backslash-newline handling, the SHELL variable, etc.

ChangeLog
dir.c
doc/make.texi
file.c
filedef.h
remake.c
tests/ChangeLog
tests/scripts/options/dash-W
vpath.c

index d31150a..80cb5cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2006-02-06  Paul D. Smith  <psmith@gnu.org>
+
+       * vpath.c (selective_vpath_search): If the file we find has a
+       timestamp from -o or -W, use that instead of the real time.
+       * remake.c (f_mtime): If the mtime is a special token from -o or
+       -W, don't overwrite it with the real mtime.
+       Fixes Savannah bug #15341.
+
+2006-02-05  Paul D. Smith  <psmith@gnu.org>
+
+       * file.c (enter_file): Keep track of the last double_colon entry,
+       to avoid walking the list every time we want to add a new one.
+       Fixes Savannah bug #15533.
+       * filedef.h (struct file): Add a new LAST pointer.
+
+       * dir.c (directory_contents_hash_cmp): Don't use subtraction to do
+       the comparison.  For 64-bits systems the result of the subtraction
+       might not fit into an int.  Use comparison instead.
+       Fixes Savannah bug #15534.
+
+       * doc/make.texi: Update the chapter on writing commands to reflect
+       the changes made in 3.81 for backslash/newline and SHELL handling.
+
 2006-02-01  Paul D. Smith  <psmith@gnu.org>
 
        * dir.c (dir_contents_file_exists_p) [WINDOWS32]: Make sure
diff --git a/dir.c b/dir.c
index f6a03bd..d2f6b98 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -289,6 +289,17 @@ directory_contents_hash_2 (const void *key_0)
   return hash;
 }
 
+/* Sometimes it's OK to use subtraction to get this value:
+     result = X - Y;
+   But, if we're not sure of the type of X and Y they may be too large for an
+   int (on a 64-bit system for example).  So, use ?: instead.
+   See Savannah bug #15534.
+
+   NOTE!  This macro has side-effects!
+*/
+
+#define MAKECMP(_x,_y)  ((_x)<(_y)?-1:((_x)==(_y)?0:1))
+
 static int
 directory_contents_hash_cmp (const void *xv, const void *yv)
 {
@@ -300,28 +311,28 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
   ISTRING_COMPARE (x->path_key, y->path_key, result);
   if (result)
     return result;
-  result = x->ctime - y->ctime;
+  result = MAKECMP(x->ctime, y->ctime);
   if (result)
     return result;
 #else
 # ifdef VMS
-  result = x->ino[0] - y->ino[0];
+  result = MAKECMP(x->ino[0], y->ino[0]);
   if (result)
     return result;
-  result = x->ino[1] - y->ino[1];
+  result = MAKECMP(x->ino[1], y->ino[1]);
   if (result)
     return result;
-  result = x->ino[2] - y->ino[2];
+  result = MAKECMP(x->ino[2], y->ino[2]);
   if (result)
     return result;
 # else
-  result = x->ino - y->ino;
+  result = MAKECMP(x->ino, y->ino);
   if (result)
     return result;
 # endif
 #endif /* WINDOWS32 */
 
-  return x->dev - y->dev;
+  return MAKECMP(x->dev, y->dev);
 }
 
 /* Table of directory contents hashed by device and inode number.  */
index eba92c7..96d0f71 100644 (file)
@@ -10,8 +10,8 @@
 @set RCSID $Id$
 @set EDITION 0.70
 @set VERSION 3.81
-@set UPDATED 29 Jan 2006
-@set UPDATE-MONTH Jan 2006
+@set UPDATED 5 Feb 2006
+@set UPDATE-MONTH Feb 2006
 @c ISBN provided by Lisa M. Opus Goldstein <opus@gnu.org>, 5 May 2004
 @set ISBN 1-882114-83-5
 
@@ -39,7 +39,7 @@ This is Edition @value{EDITION}, last updated @value{UPDATED},
 of @cite{The GNU Make Manual}, for @code{make}, Version @value{VERSION}.
 
 Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2002, 2003, 2004, 2005
+1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
 Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
@@ -173,8 +173,8 @@ Writing Rules
 * Directory Search::            Searching other directories for source files.
 * Phony Targets::               Using a target that is not a real file's name.
 * Force Targets::               You can use a target without commands
-                                  or prerequisites to mark other
-                                  targets as phony.
+                                  or prerequisites to mark other targets
+                                  as phony.
 * Empty Targets::               When only the date matters and the
                                   files are empty.
 * Special Targets::             Targets with special built-in meanings.
@@ -214,6 +214,7 @@ Static Pattern Rules
 
 Writing the Commands in Rules
 
+* Command Syntax::              Command syntax features and pitfalls.
 * Echoing::                     How to control when commands are echoed.
 * Execution::                   How commands are executed.
 * Parallel::                    How commands can be executed in parallel.
@@ -301,8 +302,8 @@ Using Implicit Rules
 * Implicit Variables::          How to change what predefined rules do.
 * Chained Rules::               How to use a chain of implicit rules.
 * Pattern Rules::               How to define new implicit rules.
-* Last Resort::                 How to defining commands for rules
-                                  which cannot find any.
+* Last Resort::                 How to define commands for rules which
+                                  cannot find any.
 * Suffix Rules::                The old-fashioned style of implicit rule.
 * Implicit Rule Search::        The precise algorithm for applying
                                   implicit rules.
@@ -331,15 +332,6 @@ Implicit Rule for Archive Member Targets
 
 * Archive Symbols::             How to update archive symbol directories.
 
-Makefile Conventions
-
-* Makefile Basics::             General Conventions for Makefiles
-* Utilities in Makefiles::      Utilities in Makefiles
-* Command Variables::           Variables for Specifying Commands
-* Directory Variables::         Variables for Installation Directories
-* Standard Targets::            Standard Targets for Users
-* Install Command Categories::  Three categories of commands in the `install'
-
 @end detailmenu
 @end menu
 
@@ -1852,8 +1844,8 @@ the makefile (often with a target called @samp{all}).
 * Directory Search::            Searching other directories for source files.
 * Phony Targets::               Using a target that is not a real file's name.
 * Force Targets::               You can use a target without commands
-                                  or prerequisites to mark other
-                                  targets as phony.
+                                  or prerequisites to mark other targets
+                                  as phony.
 * Empty Targets::               When only the date matters and the
                                   files are empty.
 * Special Targets::             Targets with special built-in meanings.
@@ -1937,19 +1929,23 @@ target per rule, but occasionally there is a reason to have more
 The @var{command} lines start with a tab character.  The first command may
 appear on the line after the prerequisites, with a tab character, or may
 appear on the same line, with a semicolon.  Either way, the effect is the
-same.  @xref{Commands, ,Writing the Commands in Rules}.
+same.  There are other differences in the syntax of command lines.
+@xref{Commands, ,Writing the Commands in Rules}.
 
 @cindex dollar sign (@code{$}), in rules
 @cindex @code{$}, in rules
-@cindex rule, and @code{$}
-Because dollar signs are used to start variable references, if you really
-want a dollar sign in a rule you must write two of them, @samp{$$}
-(@pxref{Using Variables, ,How to Use Variables}).  In prerequisite
-lists you must actually write @emph{four} dollar signs (@samp{$$$$}),
-due to secondary expansion (@pxref{Secondary Expansion}).
-You may split a long line by inserting a backslash
-followed by a newline, but this is not required, as @code{make} places no
-limit on the length of a line in a makefile.
+@cindex rules, and @code{$}
+Because dollar signs are used to start @code{make} variable
+references, if you really want a dollar sign in a target or
+prerequisite you must write two of them, @samp{$$} (@pxref{Using
+Variables, ,How to Use Variables}).  If you have enabled secondary
+expansion (@pxref{Secondary Expansion}) and you want a literal dollar
+sign in the prerequisites lise, you must actually write @emph{four}
+dollar signs (@samp{$$$$}).
+
+You may split a long line by inserting a backslash followed by a
+newline, but this is not required, as @code{make} places no limit on
+the length of a line in a makefile.
 
 A rule tells @code{make} two things: when the targets are out of date,
 and how to update them when necessary.
@@ -3497,28 +3493,17 @@ object file become the default goal.
 @cindex rule commands
 @cindex writing rule commands
 
-The commands of a rule consist of shell command lines to be executed one
-by one.  Each command line must start with a tab, except that the first
-command line may be attached to the target-and-prerequisites line with a
-semicolon in between.  Blank lines and lines of just comments may appear
-among the command lines; they are ignored.  (But beware, an apparently
-``blank'' line that begins with a tab is @emph{not} blank!  It is an
-empty command; @pxref{Empty Commands}.)
+The commands of a rule consist of one or more shell command lines to
+be executed, one at a time, in the order they appear.  Typically, the
+result of executing these commands is that the target of the rule is
+brought up to date.
 
 Users use many different shell programs, but commands in makefiles are
 always interpreted by @file{/bin/sh} unless the makefile specifies
 otherwise.  @xref{Execution, ,Command Execution}.
 
-@cindex comments, in commands
-@cindex commands, comments in
-@cindex @code{#} (comments), in commands
-The shell that is in use determines whether comments can be written on
-command lines, and what syntax they use.  When the shell is
-@file{/bin/sh}, a @samp{#} starts a comment that extends to the end of
-the line.  The @samp{#} does not have to be at the beginning of a line.
-Text on a line before a @samp{#} is not part of the comment.
-
 @menu
+* Command Syntax::              Command syntax features and pitfalls.
 * Echoing::                     How to control when commands are echoed.
 * Execution::                   How commands are executed.
 * Parallel::                    How commands can be executed in parallel.
@@ -3529,96 +3514,87 @@ Text on a line before a @samp{#} is not part of the comment.
 * Empty Commands::              Defining useful, do-nothing commands.
 @end menu
 
-@node Echoing, Execution, Commands, Commands
-@section Command Echoing
-@cindex echoing of commands
-@cindex silent operation
-@cindex @code{@@} (in commands)
-@cindex commands, echoing
-@cindex printing of commands
-
-Normally @code{make} prints each command line before it is executed.
-We call this @dfn{echoing} because it gives the appearance that you
-are typing the commands yourself.
-
-When a line starts with @samp{@@}, the echoing of that line is suppressed.
-The @samp{@@} is discarded before the command is passed to the shell.
-Typically you would use this for a command whose only effect is to print
-something, such as an @code{echo} command to indicate progress through
-the makefile:
-
-@example
-@@echo About to make distribution files
-@end example
+@node Command Syntax, Echoing, Commands, Commands
+@section Command Syntax
+@cindex command syntax
+@cindex syntax of commands
+
+Makefiles have the unusual property that there are really two distinct
+syntaxes in one file.  Most of the makefile uses @code{make} syntax
+(@pxref{Makefiles, ,Writing Makefiles}).  However, commands are meant to be
+interpreted by the shell and so they are written using shell syntax.
+The @code{make} program does not try to understand shell syntax: it
+performs only a very few specific translations on the content of the
+command before handing it to the shell.
+
+Each command line must start with a tab, except that the first command
+line may be attached to the target-and-prerequisites line with a
+semicolon in between.  @emph{Any} line in the makefile that begins
+with a tab and appears in a ``rule context'' (that is, after a rule
+has been started until another rule or variable definition) will be
+considered a command line for that rule.  Blank lines and lines of
+just comments may appear among the command lines; they are ignored.
+
+Some consequences of these rules include:
 
-@cindex @code{-n}
-@cindex @code{--just-print}
-@cindex @code{--dry-run}
-@cindex @code{--recon}
-When @code{make} is given the flag @samp{-n} or @samp{--just-print}
-it only echoes commands, it won't execute them.  @xref{Options Summary,
-,Summary of Options}.  In this case and only this case, even the
-commands starting with @samp{@@} are printed.  This flag is useful for
-finding out which commands @code{make} thinks are necessary without
-actually doing them.
-
-@cindex @code{-s}
-@cindex @code{--silent}
-@cindex @code{--quiet}
-@findex .SILENT
-The @samp{-s} or @samp{--silent}
-flag to @code{make} prevents all echoing, as if all commands
-started with @samp{@@}.  A rule in the makefile for the special target
-@code{.SILENT} without prerequisites has the same effect
-(@pxref{Special Targets, ,Special Built-in Target Names}).
-@code{.SILENT} is essentially obsolete since @samp{@@} is more flexible.@refill
+@itemize @bullet
+@item
+A blank line that begins with a tab is not blank: it's an empty
+command (@pxref{Empty Commands}).
 
-@node Execution, Parallel, Echoing, Commands
-@section Command Execution
-@cindex commands, execution
-@cindex execution, of commands
-@cindex shell command, execution
-@vindex SHELL @r{(command execution)}
+@cindex comments, in commands
+@cindex commands, comments in
+@cindex @code{#} (comments), in commands
+@item
+A comment in a command line is not a @code{make} comment; it will be
+passed to the shell as-is.  Whether the shell treats it as a comment
+or not depends on your shell.
 
-When it is time to execute commands to update a target, they are executed
-by making a new subshell for each line.  (In practice, @code{make} may
-take shortcuts that do not affect the results.)
+@item
+A variable definition in a ``rule context'' which is indented by a tab
+as the first character on the line, will be considered a command line,
+not a @code{make} variable definition, and passed to the shell.
 
-@cindex @code{cd} (shell command)
-@strong{Please note:} this implies that shell commands such as
-@code{cd} that set variables local to each process will not affect the
-following command lines.@footnote{On MS-DOS, the value of current
-working directory is @strong{global}, so changing it @emph{will}
-affect the following command lines on those systems.}  If you want to
-use @code{cd} to affect the next command, put them on a single line.
-Then @code{make} will consider them a single command and pass them
-both to a single shell which will execute them in sequence.  For
-example:
+@item
+A conditional expression (@code{ifdef}, @code{ifeq},
+etc. @pxref{Conditional Syntax, ,Syntax of Conditionals}) in a ``rule
+context'' which is indented by a tab as the first character on the
+line, will be considered a command line and be passed to the shell.
 
-@example
-foo : bar/lose
-        cd $(@@D) && gobble $(@@F) > ../$@@
-@end example
+@end itemize
 
-@noindent
-Here we use the shell AND operator (@code{&&}) so that if the
-@code{cd} command fails, the script will fail without trying to invoke
-the @code{gobble} command in the wrong directory, which could very
-easily cause problems (in this case it would certainly cause
-@file{../foo} to be truncated, at least).
+@menu
+* Splitting Lines::             Breaking long command lines for readability.
+* Variables in Commands::       Using @code{make} variables in commands.
+@end menu
 
+@node Splitting Lines, Variables in Commands, Command Syntax, Command Syntax
+@subsection Splitting Command Lines
+@cindex commands, splitting
+@cindex splitting commands
 @cindex commands, backslash (@code{\}) in
 @cindex commands, quoting newlines in
 @cindex backslash (@code{\}), in commands
 @cindex @code{\} (backslash), in commands
 @cindex quoting newline, in commands
 @cindex newline, quoting, in commands
-A shell command can be split into multiple lines of text by placing a
-backslash before each newline.  Such a sequence of lines is provided
-to the shell as a single command script.  The backslash and newline
-are preserved in the shell command.  If the first character on the
-line after a backslash-newline is a tab, the tab will @emph{not} be
-included in the shell command.  So, this makefile:
+
+One of the few ways in which @code{make} does interpret command lines
+is checking for a backslash just before the newline.  As in normal
+makefile syntax, a single command can be split into multiple lines in
+the makefile by placing a backslash before each newline.  A sequence
+of lines like this is considered a single command, and one instance of
+the shell will be invoked to run it.
+
+However, in contrast to how they are treated in other places in a
+makefile, backslash-newline pairs are @emph{not} removed from the
+command.  Both the backslash and the newline characters are preserved
+and passed to the shell.  How the backslash-newline is interpreted
+depends on your shell.  If the first character of the next line
+after the backslash-newline is a tab, then that tab (and only that
+tab) is removed.  Whitespace is never added to the command.
+
+For example, this makefile:
 
 @example
 @group
@@ -3685,9 +3661,220 @@ quotes (@code{'...'}).  This is the way the default shell (@file{/bin/sh})
 handles backslash/newline pairs.  If you specify a different shell in your
 makefiles it may treat them differently.
 
+Sometimes you want to split a long line inside of single quotes, but
+you don't want the backslash-newline to appear in the quoted content.
+This is often the case when passing scripts to languages such as Perl,
+where extraneous backslashes inside the script can change its meaning
+or even be a syntax error.  One simple way of handling this is to
+place the quoted string, or even the entire command, into a
+@code{make} variable then use the variable in the command.  In this
+situation the newline quoting rules for makefiles will be used, and
+the backslash-newline will be removed.  If we rewrite our example
+above using this method:
+
+@example
+@group
+HELLO = 'hello \
+world'
+
+all : ; @@echo $(HELLO)
+@end group
+@end example
+
+@noindent
+we will get output like this:
+
+@example
+@group
+hello world
+@end group
+@end example
+
+If you like, you can also use target-specific variables
+(@pxref{Target-specific, ,Target-specific Variable Values}) to obtain
+a tighter correspondence between the variable and the command that
+uses it.
+
+@node Variables in Commands,  , Splitting Lines, Command Syntax
+@subsection Using Variables in Commands
+@cindex variable references in commands
+@cindex commands, using variables in
+
+The other way in which @code{make} processes commands is by expanding
+any variable references in them (@pxref{Reference,Basics of Variable
+References}).  This occurs after make has finished reading all the
+makefiles and the target is determined to be out of date; so, the
+commands for targets which are not rebuilt are never expanded.
+
+Variable and function references in commands have identical syntax and
+semantics to references elsewhere in the makefile.  They also have the
+same quoting rules: if you want a dollar sign to appear in your
+command, you must double it (@samp{$$}).  For shells like the default
+shell, that use dollar signs to introduce variables, it's important to
+keep clear in your mind whether the variable you want to reference is
+a @code{make} variable (use a single dollar sign) or a shell variable
+(use two dollar signs).  For example:
+
+@example
+@group
+LIST = one two three
+all:
+        for i in $(LIST); do \
+            echo $$i; \
+        done
+@end group
+@end example
+
+@noindent
+results in the following command being passed to the shell:
+
+@example
+@group
+for i in one two three; do \
+    echo $i; \
+done
+@end group
+@end example
+
+@noindent
+which generates the expected result:
+
+@example
+@group
+one
+two
+three
+@end group
+@end example
+
+@node Echoing, Execution, Command Syntax, Commands
+@section Command Echoing
+@cindex echoing of commands
+@cindex silent operation
+@cindex @code{@@} (in commands)
+@cindex commands, echoing
+@cindex printing of commands
+
+Normally @code{make} prints each command line before it is executed.
+We call this @dfn{echoing} because it gives the appearance that you
+are typing the commands yourself.
+
+When a line starts with @samp{@@}, the echoing of that line is suppressed.
+The @samp{@@} is discarded before the command is passed to the shell.
+Typically you would use this for a command whose only effect is to print
+something, such as an @code{echo} command to indicate progress through
+the makefile:
+
+@example
+@@echo About to make distribution files
+@end example
+
+@cindex @code{-n}
+@cindex @code{--just-print}
+@cindex @code{--dry-run}
+@cindex @code{--recon}
+When @code{make} is given the flag @samp{-n} or @samp{--just-print}
+it only echoes commands, it won't execute them.  @xref{Options Summary,
+,Summary of Options}.  In this case and only this case, even the
+commands starting with @samp{@@} are printed.  This flag is useful for
+finding out which commands @code{make} thinks are necessary without
+actually doing them.
+
+@cindex @code{-s}
+@cindex @code{--silent}
+@cindex @code{--quiet}
+@findex .SILENT
+The @samp{-s} or @samp{--silent}
+flag to @code{make} prevents all echoing, as if all commands
+started with @samp{@@}.  A rule in the makefile for the special target
+@code{.SILENT} without prerequisites has the same effect
+(@pxref{Special Targets, ,Special Built-in Target Names}).
+@code{.SILENT} is essentially obsolete since @samp{@@} is more flexible.@refill
+
+@node Execution, Parallel, Echoing, Commands
+@section Command Execution
+@cindex commands, execution
+@cindex execution, of commands
+@cindex shell command, execution
+@vindex @code{SHELL} @r{(command execution)}
+
+When it is time to execute commands to update a target, they are
+executed by invoking a new subshell for each command line.  (In
+practice, @code{make} may take shortcuts that do not affect the
+results.)
+
+@cindex @code{cd} (shell command)
+@cindex shell variables, setting in commands
+@cindex commands setting shell variables
+@strong{Please note:} this implies that setting shell variables and
+invoking shell commands such as @code{cd} that set a context local to
+each process will not affect the following command lines.@footnote{On
+MS-DOS, the value of current working directory is @strong{global}, so
+changing it @emph{will} affect the following command lines on those
+systems.}  If you want to use @code{cd} to affect the next statement,
+put both statements in a single command line.  Then @code{make} will
+invoke one shell to run the entire line, and the shell will execute
+the statements in sequence.  For example:
+
+@example
+foo : bar/lose
+        cd $(@@D) && gobble $(@@F) > ../$@@
+@end example
+
+@noindent
+Here we use the shell AND operator (@code{&&}) so that if the
+@code{cd} command fails, the script will fail without trying to invoke
+the @code{gobble} command in the wrong directory, which could cause
+problems (in this case it would certainly cause @file{../foo} to be
+truncated, at least).
+
+@menu
+* Choosing the Shell::          How @code{make} chooses the shell used
+                                  to run commands.
+@end menu
+
+@node Choosing the Shell,  , Execution, Execution
+@subsection Choosing the Shell
+@cindex shell, choosing the
+@cindex @code{SHELL}, value of
+
 @vindex SHELL
 The program used as the shell is taken from the variable @code{SHELL}.
-By default, the program @file{/bin/sh} is used.
+If this variable is not set in your makefile, the program
+@file{/bin/sh} is used as the shell.
+
+@cindex environment, @code{SHELL} in
+Unlike most variables, the variable @code{SHELL} is never set from the
+environment.  This is because the @code{SHELL} environment variable is
+used to specify your personal choice of shell program for interactive
+use.  It would be very bad for personal choices like this to affect the
+functioning of makefiles.  @xref{Environment, ,Variables from the
+Environment}.
+
+Furthermore, when you do set @code{SHELL} in your makefile that value
+is @emph{not} exported in the environment to commands that @code{make}
+invokes.  Instead, the value inherited from the user's environment, if
+any, is exported.  You can override this behavior by explicitly
+exporting @code{SHELL} (@pxref{Variables/Recursion, ,Communicating
+Variables to a Sub-@code{make}}), forcing it to be passed in the
+environment to commands.
+
+@vindex @code{MAKESHELL} @r{(MS-DOS alternative to @code{SHELL})}
+However, on MS-DOS and MS-Windows the value of @code{SHELL} in the
+environment @strong{is} used, since on those systems most users do not
+set this variable, and therefore it is most likely set specifically to
+be used by @code{make}.  On MS-DOS, if the setting of @code{SHELL} is
+not suitable for @code{make}, you can set the variable
+@code{MAKESHELL} to the shell that @code{make} should use; if set it
+will be used as the shell instead of the value of @code{SHELL}.
+
+@subsubheading Choosing a Shell in DOS and Windows
+@cindex shell, in DOS and Windows
+@cindex DOS, choosing a shell in
+@cindex Windows, choosing a shell in
+
+Choosing a shell in MS-DOS and MS-Windows is much more complex than on
+other systems.
 
 @vindex COMSPEC
 On MS-DOS, if @code{SHELL} is not set, the value of the variable
@@ -3741,25 +3928,10 @@ environment or command line, you are expected to set it to the full
 pathname of the shell, exactly as things are on Unix.
 
 The effect of the above DOS-specific processing is that a Makefile that
-says @samp{SHELL = /bin/sh} (as many Unix makefiles do), will work
+contains @samp{SHELL = /bin/sh} (as many Unix makefiles do), will work
 on MS-DOS unaltered if you have e.g.@: @file{sh.exe} installed in some
 directory along your @code{PATH}.
 
-@cindex environment, @code{SHELL} in
-@vindex MAKESHELL @r{(MS-DOS alternative to @code{SHELL})}
-Unlike most variables, the variable @code{SHELL} is never set from the
-environment.  This is because the @code{SHELL} environment variable is
-used to specify your personal choice of shell program for interactive
-use.  It would be very bad for personal choices like this to affect the
-functioning of makefiles.  @xref{Environment, ,Variables from the
-Environment}.  However, on MS-DOS and MS-Windows the value of
-@code{SHELL} in the environment @strong{is} used, since on those systems
-most users do not set this variable, and therefore it is most likely set
-specifically to be used by @code{make}.  On MS-DOS, if the setting of
-@code{SHELL} is not suitable for @code{make}, you can set the variable
-@code{MAKESHELL} to the shell that @code{make} should use; this will
-override the value of @code{SHELL}.
-
 @node Parallel, Errors, Execution, Commands
 @section Parallel Execution
 @cindex commands, execution in parallel
@@ -4128,7 +4300,7 @@ The value of the @code{make} variable @code{SHELL} is not exported.
 Instead, the value of the @code{SHELL} variable from the invoking
 environment is passed to the sub-@code{make}.  You can force
 @code{make} to export its value for @code{SHELL} by using the
-@code{export} directive, described below.
+@code{export} directive, described below.  @xref{Choosing the Shell}.
 
 The special variable @code{MAKEFLAGS} is always exported (unless you
 unexport it).  @code{MAKEFILES} is exported if you set it to anything.
@@ -5564,22 +5736,12 @@ different results from the same makefile.  This is against the whole
 purpose of most makefiles.
 
 @cindex SHELL, import from environment
-Such problems would be especially likely with the variable @code{SHELL},
-which is normally present in the environment to specify the user's choice
-of interactive shell.  It would be very undesirable for this choice to
-affect @code{make}.  So @code{make} ignores the environment value of
-@code{SHELL} (except on MS-DOS and MS-Windows, where @code{SHELL} is
-usually not set.  @xref{Execution, ,Special handling of SHELL on
-MS-DOS}.)@refill
-
-@cindex SHELL, export to environment
-The @code{SHELL} variable is special in another way: just as the value
-of the @code{make} variable @code{SHELL} is not taken from the
-environment, so also it is not placed into the environment of commands
-that @code{make} invokes.  Instead, the value of @code{SHELL} from the
-invoking environment is provided to the command.  You can use
-@code{export SHELL} to force the value of the @code{make} variable
-@code{SHELL} to be placed in the environment of commands.
+Such problems would be especially likely with the variable
+@code{SHELL}, which is normally present in the environment to specify
+the user's choice of interactive shell.  It would be very undesirable
+for this choice to affect @code{make}; so, @code{make} handles the
+@code{SHELL} environment variable in a special way; see @ref{Choosing
+the Shell}.@refill
 
 @node Target-specific, Pattern-specific, Environment, Using Variables
 @section Target-specific Variable Values
@@ -8067,7 +8229,7 @@ retained for compatibility.
 * Chained Rules::               How to use a chain of implicit rules.
 * Pattern Rules::               How to define new implicit rules.
 * Last Resort::                 How to define commands for rules which
-                                cannot find any.
+                                  cannot find any.
 * Suffix Rules::                The old-fashioned style of implicit rule.
 * Implicit Rule Search::        The precise algorithm for applying
                                   implicit rules.
@@ -8491,7 +8653,7 @@ with spaces.
 
 The following tables describe of some of the more commonly-used predefined
 variables.  This list is not exhaustive, and the default values shown here may
-not be what is selected by @code{make} for your environment.  To see the
+not be what are selected by @code{make} for your environment.  To see the
 complete list of predefined variables for your instance of GNU @code{make} you
 can run @samp{make -p} in a directory with no makefiles.
 
@@ -10423,7 +10585,7 @@ The name of the system default command interpreter, usually @file{/bin/sh}.
 You can set @code{SHELL} in the makefile to change the shell used to run
 commands.  @xref{Execution, ,Command Execution}.  The @code{SHELL}
 variable is handled specially when importing from and exporting to the
-environment.  @xref{Environment, ,Using Variable from the Environment}.
+environment.  @xref{Choosing the Shell}.
 
 @item MAKESHELL
 
diff --git a/file.c b/file.c
index ddec34d..383f460 100644 (file)
--- a/file.c
+++ b/file.c
@@ -180,14 +180,16 @@ enter_file (char *name)
   new->update_status = -1;
 
   if (HASH_VACANT (f))
-    hash_insert_at (&files, new, file_slot);
+    {
+      new->last = new;
+      hash_insert_at (&files, new, file_slot);
+    }
   else
     {
       /* There is already a double-colon entry for this file.  */
       new->double_colon = f;
-      while (f->prev != 0)
-       f = f->prev;
-      f->prev = new;
+      f->last->prev = new;
+      f->last = new;
     }
 
   return new;
@@ -718,14 +720,18 @@ snap_deps (void)
            f2->command_flags |= COMMANDS_SILENT;
     }
 
-  f = lookup_file (".POSIX");
-  if (f != 0 && f->is_target)
-    posix_pedantic = 1;
-
   f = lookup_file (".NOTPARALLEL");
   if (f != 0 && f->is_target)
     not_parallel = 1;
 
+#ifndef NO_MINUS_C_MINUS_O
+  /* If .POSIX was defined, remove OUTPUT_OPTION to comply.  */
+  /* This needs more work: what if the user sets this in the makefile?
+  if (posix_pedantic)
+    define_variable (STRING_SIZE_TUPLE("OUTPUT_OPTION"), "", o_default, 1);
+  */
+#endif
+
   /* Remember that we've done this. */
   snapped_deps = 1;
 }
index ae71110..e2d9c3c 100644 (file)
--- a/filedef.h
+++ b/filedef.h
@@ -42,6 +42,7 @@ struct file
     struct file *prev;         /* Previous entry for same file name;
                                   used when there are multiple double-colon
                                   entries for the same file.  */
+    struct file *last;          /* Last entry for the same file name.  */
 
     /* File that this file was renamed to.  After any time that a
        file could be renamed, call `check_renamed' (below).  */
index 184e910..0003ee3 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -1248,70 +1248,71 @@ f_mtime (struct file *file, int search)
 
              rehash_file (file, name);
              check_renamed (file);
-             mtime = name_mtime (name);
+              /* If the result of a vpath search is -o or -W, preserve it.
+                 Otherwise, find the mtime of the resulting file.  */
+              if (mtime != OLD_MTIME && mtime != NEW_MTIME)
+                mtime = name_mtime (name);
            }
        }
     }
 
-  {
-    /* Files can have bogus timestamps that nothing newly made will be
-       "newer" than.  Updating their dependents could just result in loops.
-       So notify the user of the anomaly with a warning.
+  /* Files can have bogus timestamps that nothing newly made will be
+     "newer" than.  Updating their dependents could just result in loops.
+     So notify the user of the anomaly with a warning.
 
-       We only need to do this once, for now. */
+     We only need to do this once, for now. */
 
-    if (!clock_skew_detected
-       && mtime != NONEXISTENT_MTIME
-       && !file->updated)
-      {
-       static FILE_TIMESTAMP adjusted_now;
+  if (!clock_skew_detected
+      && mtime != NONEXISTENT_MTIME && mtime != NEW_MTIME
+      && !file->updated)
+    {
+      static FILE_TIMESTAMP adjusted_now;
 
-       FILE_TIMESTAMP adjusted_mtime = mtime;
+      FILE_TIMESTAMP adjusted_mtime = mtime;
 
 #if defined(WINDOWS32) || defined(__MSDOS__)
-       /* Experimentation has shown that FAT filesystems can set file times
-          up to 3 seconds into the future!  Play it safe.  */
+      /* Experimentation has shown that FAT filesystems can set file times
+         up to 3 seconds into the future!  Play it safe.  */
 
 #define FAT_ADJ_OFFSET  (FILE_TIMESTAMP) 3
 
-       FILE_TIMESTAMP adjustment = FAT_ADJ_OFFSET << FILE_TIMESTAMP_LO_BITS;
-       if (ORDINARY_MTIME_MIN + adjustment <= adjusted_mtime)
-         adjusted_mtime -= adjustment;
+      FILE_TIMESTAMP adjustment = FAT_ADJ_OFFSET << FILE_TIMESTAMP_LO_BITS;
+      if (ORDINARY_MTIME_MIN + adjustment <= adjusted_mtime)
+        adjusted_mtime -= adjustment;
 #elif defined(__EMX__)
-       /* FAT filesystems round time to the nearest even second!
-          Allow for any file (NTFS or FAT) to perhaps suffer from this
-          brain damage.  */
-       FILE_TIMESTAMP adjustment = (((FILE_TIMESTAMP_S (adjusted_mtime) & 1) == 0
-                      && FILE_TIMESTAMP_NS (adjusted_mtime) == 0)
-                     ? (FILE_TIMESTAMP) 1 << FILE_TIMESTAMP_LO_BITS
-                     : 0);
+      /* FAT filesystems round time to the nearest even second!
+         Allow for any file (NTFS or FAT) to perhaps suffer from this
+         brain damage.  */
+      FILE_TIMESTAMP adjustment = (((FILE_TIMESTAMP_S (adjusted_mtime) & 1) == 0
+                     && FILE_TIMESTAMP_NS (adjusted_mtime) == 0)
+                    ? (FILE_TIMESTAMP) 1 << FILE_TIMESTAMP_LO_BITS
+                    : 0);
 #endif
 
-       /* If the file's time appears to be in the future, update our
-          concept of the present and try once more.  */
-       if (adjusted_now < adjusted_mtime)
-         {
-           int resolution;
-           FILE_TIMESTAMP now = file_timestamp_now (&resolution);
-           adjusted_now = now + (resolution - 1);
-           if (adjusted_now < adjusted_mtime)
-             {
+      /* If the file's time appears to be in the future, update our
+         concept of the present and try once more.  */
+      if (adjusted_now < adjusted_mtime)
+        {
+          int resolution;
+          FILE_TIMESTAMP now = file_timestamp_now (&resolution);
+          adjusted_now = now + (resolution - 1);
+          if (adjusted_now < adjusted_mtime)
+            {
 #ifdef NO_FLOAT
-               error (NILF, _("Warning: File `%s' has modification time in the future"),
-                       file->name);
+              error (NILF, _("Warning: File `%s' has modification time in the future"),
+                     file->name);
 #else
-               double from_now =
-                 (FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now)
-                  + ((FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now))
-                     / 1e9));
-               error (NILF, _("Warning: File `%s' has modification time %.2g s in the future"),
-                      file->name, from_now);
+              double from_now =
+                (FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now)
+                 + ((FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now))
+                    / 1e9));
+              error (NILF, _("Warning: File `%s' has modification time %.2g s in the future"),
+                     file->name, from_now);
 #endif
-               clock_skew_detected = 1;
-             }
-          }
-      }
-  }
+              clock_skew_detected = 1;
+            }
+        }
+    }
 
   /* Store the mtime into all the entries for this file.  */
   if (file->double_colon)
index 80f4a0d..8a3b988 100644 (file)
@@ -1,3 +1,7 @@
+2006-02-06  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/options/dash-W: Add a test for bug #15341.
+
 2006-01-03  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/variables/automatic: Add a test for bug #8154.
index baa04a5..50745f7 100644 (file)
@@ -57,4 +57,32 @@ run_make_test(undef, '-W bar.x', "restarts=\ntouch foo.x\nrestarts=1\ntouch baz.
 
 rmfiles('foo.x', 'bar.x');
 
+# Test -W on vpath-found files: it should take effect.
+# Savannah bug # 15341
+
+mkdir('x-dir');
+utouch(-20, 'x-dir/x');
+touch('y');
+
+run_make_test('
+y: x ; @echo cp $< $@
+',
+              '-W x-dir/x VPATH=x-dir',
+              'cp x-dir/x y');
+
+# Make sure ./ stripping doesn't interfere with the match.
+
+run_make_test('
+y: x ; @echo cp $< $@
+',
+              '-W ./x-dir/x VPATH=x-dir',
+              'cp x-dir/x y');
+
+run_make_test(undef,
+              '-W x-dir/x VPATH=./x-dir',
+              'cp ./x-dir/x y');
+
+unlink(qw(y x-dir/x));
+rmdir('x-dir');
+
 1;
diff --git a/vpath.c b/vpath.c
index 458fb18..05f15c6 100644 (file)
--- a/vpath.c
+++ b/vpath.c
@@ -466,11 +466,27 @@ selective_vpath_search (struct vpath *path, char **file,
 
         In December 1993 I loosened this restriction to allow a file
         to be chosen if it is mentioned as a target in a makefile.  This
-        seem logical.  */
+        seem logical.
+
+         Special handling for -W / -o: make sure we preserve the special
+         values here.  Actually this whole thing is a little bogus: I think
+         we should ditch the name/hname thing and look into the renamed
+         capability that already exists for files: that is, have a new struct
+         file* entry for the VPATH-found file, and set the renamed field if
+         we use it.
+      */
       {
        struct file *f = lookup_file (name);
        if (f != 0)
-         exists = not_target || f->is_target;
+          {
+            exists = not_target || f->is_target;
+            if (exists && mtime_ptr
+                && (f->last_mtime == OLD_MTIME || f->last_mtime == NEW_MTIME))
+              {
+                *mtime_ptr = f->last_mtime;
+                mtime_ptr = 0;
+              }
+          }
       }
 
       if (!exists)
@@ -517,6 +533,13 @@ selective_vpath_search (struct vpath *path, char **file,
                   exists = 0;
                   continue;
                 }
+
+              /* Store the modtime into *MTIME_PTR for the caller.  */
+              if (mtime_ptr != 0)
+                {
+                  *mtime_ptr = FILE_TIMESTAMP_STAT_MODTIME (name, st);
+                  mtime_ptr = 0;
+                }
             }
 
           /* We have found a file.
@@ -524,13 +547,10 @@ selective_vpath_search (struct vpath *path, char **file,
 
           *file = savestring (name, (n + 1 - name) + flen);
 
+          /* If we get here and mtime_ptr hasn't been set, record
+             UNKNOWN_MTIME to indicate this.  */
           if (mtime_ptr != 0)
-            /* Store the modtime into *MTIME_PTR for the caller.
-               If we have had no need to stat the file here,
-               we record UNKNOWN_MTIME to indicate this.  */
-            *mtime_ptr = (exists_in_cache
-                          ? FILE_TIMESTAMP_STAT_MODTIME (name, st)
-                          : UNKNOWN_MTIME);
+            *mtime_ptr = UNKNOWN_MTIME;
 
           free (name);
           return 1;