Compare commits

...

157 Commits

Author SHA1 Message Date
Paul Smith
52191d9d61 GNU Make release 4.0. 2013-10-09 02:09:21 -04:00
Paul Smith
dc9ae5e017 [SV 39709] Fix some typos. 2013-10-09 01:53:55 -04:00
Eli Zaretskii
723e047428 Untabify posixfcn.c. 2013-10-07 19:16:11 +03:00
Eli Zaretskii
b69b04dc8c Foix compilation with MSVC.
w32/compat/posixfcn.c (tmpfile): Move declaration of h before
 the first executable statement.  Reported by Gisle Vanem <gvanem@yahoo.no>.
2013-10-07 19:14:01 +03:00
Paul Smith
b539908f73 Clean up some tests for use on Windows. 2013-10-05 19:30:48 -04:00
Paul Smith
2fb91e19a0 Sanitize the registered function interface.
Expand the characters which are legal in a function name, and check
the name for validity.  Create a type for the function pointer.
Convert the last argument from a boolean to flags, to allow for expansion.
2013-10-05 16:10:30 -04:00
Eli Zaretskii
f96c114e22 function.c (abspath): Reset root_len to one for Cygwin only when
HAVE_DOS_PATHS is defined.  Suggested by Christopher Faylor.
2013-10-03 19:02:14 +03:00
Eli Zaretskii
98197303b1 Fix tmpfile on MS-Windows.
w32/compat/posixfcn.c (tmpfile): New function, a replacement for
 the Windows libc version.
2013-10-02 19:48:21 +03:00
Eli Zaretskii
f8786092ad Fix $abspath on Cygwin when HAVE_DOS_PATHS is in effect.
function.c (IS_ABSOLUTE) [__CYGWIN__]: Special definition for Cygwin.
 (abspath) [__CYGWIN__]: Reset root_len to 1 if the absolute file name
 has the Posix /foo/bar form.
 [HAVE_DOS_PATHS]: Use root_len instead of hard-coded 2.
2013-10-02 19:39:53 +03:00
Paul Smith
1d4c15b4e1 Release GNU Make version 3.99.93. 2013-10-01 00:33:01 -04:00
Paul Smith
b1c7f0df4e Fix portability issues for Guile 1.8. 2013-09-30 10:56:20 -04:00
Paul Smith
8e12202870 Final fixes for obscure output-sync errors. 2013-09-30 00:12:36 -04:00
Paul Smith
1f4ca0539b Fixes for building with MSVC. 2013-09-30 00:12:36 -04:00
Paul Smith
d0944ee2e8 Solaris /bin/sh can't handle multiple options ("-e -c"). 2013-09-30 00:12:18 -04:00
Paul Smith
38066b6f19 Fix build failures on EMX for output-sync support. 2013-09-29 13:17:56 -04:00
Paul Smith
3bf3fde984 Portability for Guile 1.8. Force UTF-8 encoding. 2013-09-29 13:16:21 -04:00
Paul Smith
543521cd47 Reset GNUMAKEFLAGS after parsing.
If we don't do this we'll continually add flags on recursion.  This
is mainly for users to set in their environment before invoking make.
2013-09-29 13:15:00 -04:00
Paul Smith
e8122ecb5d Rename dash-w to print-directory.
Avoid conflicts with dash-W on case-insensitive filesystems.
2013-09-23 11:24:51 -04:00
Eli Zaretskii
55a0c0e414 Fix broken w32 build due to OUTPUT_SYNC -> NO_OUTPUT_SYNC inversion.
w32/compat/posixfcn.c: Fix the forgotten OUTPUT_SYNC conditional.
 job.h: Ditto, but in a comment.
2013-09-23 10:56:51 +03:00
Paul Smith
8a3436c65d Release GNU Make version 3.99.92. 2013-09-23 00:55:55 -04:00
Paul Smith
fd30db1290 [SV 31155] Parse order-only tokens in second expansion results. 2013-09-22 17:10:35 -04:00
Paul Smith
c3524b83b9 Use explicit cast between void* and pointer-to-function. 2013-09-22 17:10:35 -04:00
Paul Smith
0296e40fc7 Allow loaded objects to opt out of the "auto-rebuild" feature. 2013-09-22 17:10:35 -04:00
Paul Smith
f69922b335 Defer Guile initialization until the first $(guile...) call. 2013-09-22 17:10:35 -04:00
Paul Smith
65931ce7a9 Regression test portability to Solaris. 2013-09-22 17:10:34 -04:00
Paul Smith
1a991ada47 Add VMS port updates from Hartmut Becker. 2013-09-22 17:10:34 -04:00
Paul Smith
7e77685bc3 Portability enhancements for Mac OSX.
Don't dup stdout into stderr in the test suite.
Don't rely on $port_type eq "UNIX" to mean case-preserving.
Check against the real output of ar when creating archives.
2013-09-22 17:09:46 -04:00
Paul Smith
300d1296fb Create a target that tests alternative configurations. 2013-09-21 18:10:08 -04:00
Paul Smith
822f8dae41 Remove obsolete tests. 2013-09-21 17:41:11 -04:00
Paul Smith
d2d44f76c4 Invert the #define for output-sync: turn it off with NO_OUTPUT_SYNC 2013-09-21 17:37:59 -04:00
Paul Smith
6c3e88e60f Ensure that output generated while reading makefiles is synced. 2013-09-21 17:24:59 -04:00
Paul Smith
9cd01958da Ensure that stderr from shell functions in recipes is synced. 2013-09-21 17:08:42 -04:00
Paul Smith
4120f91846 Don't write "Entering" every time we re-exec for remake makefiles. 2013-09-21 14:24:44 -04:00
Paul Smith
30a5ee0d85 [SV 40043] Set the current directory before printing errors. 2013-09-18 19:29:28 -04:00
Eli Zaretskii
8a6205b43f Fix a typo in a comment. 2013-09-16 11:42:20 +03:00
Eli Zaretskii
bc120f27bd Avoid compiler warnings in output.c on MS-Windows.
output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
 compiler warnings for CLOSE_ON_EXEC.
2013-09-16 11:30:01 +03:00
Paul Smith
5c0fba7240 Release GNU Make version 3.99.91. 2013-09-16 00:30:01 -04:00
Paul Smith
fa0f2c516a Small cleanup defining MAKEFLAGS. 2013-09-16 00:12:09 -04:00
Paul Smith
20ecc58126 [SV 31326] Enhance the info on static pattern errors. 2013-09-15 17:53:30 -04:00
Paul Smith
1b90248893 [SV 27374] Fatal immediately on unrecoverable fopen() errors. 2013-09-15 17:09:01 -04:00
Paul Smith
a4d8444b59 [SV 39934] Verify jobserver FDs before something else uses them. 2013-09-15 15:21:33 -04:00
Paul Smith
0a81d50d66 [SV 39203] Don't set MAKEFLAGS when restarting.
We are restarting with the original command line flags, so if we set
MAKEFLAGS as well that will cause double flags.
2013-09-15 13:30:21 -04:00
Paul Smith
3aa2aa7e82 [SV 35248] Add --debug "n" flag to turn off current debug options. 2013-09-14 21:01:10 -04:00
Paul Smith
29a94ceb76 [SV 33134] Don't try to close stdout when it's already closed. 2013-09-14 20:40:30 -04:00
Petr Machata
ab78cbc71c [SV 39851] Reinstate stack size limit for processes spawned via $(shell) 2013-09-14 20:38:06 -04:00
Paul Smith
c5bfa40044 Support the -Orecurse option properly.
In this mode we still collect all the output from a given target and
dump it at once.  However we don't treat recursive lines any differently
from non-recursive lines.  Also we don't print enter/leave messages
after every dump.  However we do ensure that we always print them once
to stdout, so the parent make will collect it properly.
2013-09-14 01:04:04 -04:00
Paul Smith
deff9dacc9 Enhance the output sync mode.
Create a new file, output.c, and collect functions that generate output there.
We introduce a new global context specifying where output should go (to stdout
or to a sync file), and the lowest level output generator chooses where to
write output based on that context.

This allows us to set the context globally, and all operations that write
output (including functions like $(info ...) etc.) will use it.

Removed the "--trace=dir" capability.  It was too confusing.  If you have
directory tracking enabled then output sync will print the enter/leave message
for each synchronized block.  If you don't want that, disable directory
tracking.
2013-09-12 04:07:52 -04:00
Paul Smith
40a49f244d [Bug #39310] Parse simple pattern prereqs for globbing.
We tried to get some efficiency by avoiding a parse_file_seq() for simple
pattern prerequisites, but this also means no wildcard expansion was
happening, so add it back.  Add regression tests for wildcards in target and
prerequisite lists.
2013-07-22 02:23:02 -04:00
Paul Smith
87ac68fe79 [Bug #39158] Source cleanups suggested by cppcheck utility. 2013-07-21 17:52:13 -04:00
Paul Smith
72462ef1e1 Safety cleanups: ensure OUTFD is -1 when closed. 2013-07-21 16:56:00 -04:00
Paul Smith
f80222c15b Notify the compiler that exec_command() won't return. 2013-07-14 19:18:46 -04:00
Paul Smith
4b81f5ca92 Modify the update_status field in struct file to be an enum.
Makes the code a little clearer/cleaner, and solves a problem on systems
where a char is unsigned by default.
2013-07-14 19:18:21 -04:00
Paul Smith
5601726151 Keep a local count of the max dependency list size.
This global variable could be modified during recursion so keep our
own local copy to compare against.
2013-07-09 19:14:40 -04:00
Paul Smith
9453a7451d Set O_APPEND mode for stdout/stderr and output-sync temporary files.
POSIX does not guarantee that writes will be atomic if a file is
opened for normal (non-append) output.  That means if multiple processes
are writing to the same file, output could be lost.  I can't think of
a real use-case where we would NOT want append for stdout/stderr, so
force it if we can.
2013-06-28 21:57:59 -04:00
Eli Zaretskii
5e7bf7c554 Minor fix in build_w32.bat.
build_w32.bat (LinkGCC): Prevent a comment from being displayed
 at build time.
2013-06-22 17:32:46 +03:00
Eli Zaretskii
138d020e1b Compare internal commands of non-Unix shells on Windows case-insensitively.
job.c (construct_command_argv_internal) [WINDOWS32]: Use
 case-insensitive comparison with internal commands of non-Unix
 shells.
2013-06-22 16:22:25 +03:00
Eli Zaretskii
5b65c5b916 Fix a fatal error at startup on Windows due to non-ASCII characters in PATH.
main.c (find_and_set_default_shell): Don't use file_exists_p or
 dir_file_exists_p, as those call readdir, which can fail if PATH
 includes directories with non-ASCII characters, and that would
 cause Make to fail at startup with confusing diagnostics.  See
 https://sourceforge.net/mailarchive/message.php?msg_id=30846737
 for the details.
2013-06-22 16:16:56 +03:00
Paul Smith
cc85b927cd Create a character map to use for locating stop-points in strings.
In various places we were passing flags and characters to compare, then
using complex conditionals to see where to stop in string searches.
Performance numbers reveal that we were spending as much as 23% of our
processing time in these functions, most of it in the comparison lines.
Instead create a character map and use a single bitwise comparison to
determine if this is any one of the stop characters.
2013-06-22 00:22:08 -04:00
Paul Smith
bee4d93a59 Disable database verification unless debug enabled.
The database verification can take a long time.  Only enable it if debug mode
is enabled.  If MAKE_MAINTAINER_MODE is set, it's also enabled by default.
2013-06-21 23:59:38 -04:00
Paul Smith
353fcfdb30 Add job.h to POTFILES as it now has a translation. 2013-06-21 21:57:35 -04:00
Paul Smith
d4043519f7 Cleanups. 2013-05-27 13:52:15 -04:00
Paul Smith
ef11217de7 Create a new variable MAKE_HOST providing the host architecture. 2013-05-27 13:52:08 -04:00
Paul Smith
e8f5d322cf Porting to VMS, from Hartmut Becker. 2013-05-27 13:01:48 -04:00
Paul Smith
dc922e3f4c [SV #38442] Add library names to the string cache. 2013-05-26 16:53:17 -04:00
Paul Smith
c11024b3b3 [SV #38945] Copy the entire buffer back when overwriting CR 2013-05-26 14:41:45 -04:00
Paul Smith
2fc0f614be [SV #39028] Fix some small typos in messages. 2013-05-26 14:06:25 -04:00
Paul Smith
bf60bbd67a [SV #39035] Compare OUT to the beginning of the OUT var/func, not IN. 2013-05-26 13:56:51 -04:00
Paul Smith
d2eaed1f0a Add dates to the NEWS file to make things simpler. 2013-05-26 13:53:21 -04:00
Paul Smith
8ab3564a71 Fix regression tests after MAKEFLAGS enhancements. 2013-05-22 07:51:46 -04:00
Paul Smith
ecf307bb0b Force version printing whenever we print the database. 2013-05-22 02:51:45 -04:00
Paul Smith
a674abe702 Make MFLAGS and MAKEFLAGS more reliable and predictable.
Ensure all simple flags are kept in the initial batch of flags.
Do not allow any flags with options in that batch.
If there are only non-simple flags ensure MAKEFLAGS begins with " ".
Don't let MFLAGS start with "- ".
2013-05-22 02:14:19 -04:00
Alexey Pavlov
80183457ad Fix the MS-Windows build using the Posix configury.
w32/Makefile.am (libw32_a_SOURCES): Add compat/posixfcn.c.

 configure.ac (OUTPUT_SYNC): Define for mingw32 target.
2013-05-18 17:58:10 +03:00
Eli Zaretskii
cece7ad61f Support "move" as internal shell command on Windows with cmd.exe.
job.c (construct_command_argv_internal) <sh_cmds_dos> [WINDOWS32]: Add
 "move".  Fixes Savannah bug #30714.
2013-05-18 14:07:36 +03:00
Eli Zaretskii
943c06de47 Fix MS-Windows build with Guile.
guile.c: Move inclusion of makeint.h before gnumake.h.  This
 order must be observed when building Make, because gnumake.h must
 be included with GMK_BUILDING_MAKE defined, which makeint.h
 already does.  Otherwise, the linker will look for, and fail to
 find, gmk_* functions in some external dynamic library.
2013-05-18 14:03:26 +03:00
Eli Zaretskii
171eb41908 Fix MS-Windows compilation when OUTPUT_SYNC is not defined.
main.c (prepare_mutex_handle_string): Define conditioned on OUTPUT_SYNC.
2013-05-17 16:24:13 +03:00
Eli Zaretskii
9babfe49a5 Fix a bug in build_w32.bat when building a released tarball.
build_w32.bat: Copy config.h.W32 to config.h regardless of
 whether or not we are building from SCM.
2013-05-17 13:34:24 +03:00
Paul Smith
b16852a77f Update for GNU make release candidate 3.99.90. 2013-05-17 02:40:37 -04:00
Paul Smith
96cf67bd29 Update source file format: remove TABs, use GNU coding styles. 2013-05-17 02:29:46 -04:00
Paul Smith
5370238316 Update copyright for changes in 2013. 2013-05-17 01:47:42 -04:00
Paul Smith
398058a873 Use xcalloc() in hash.c to handle out of memory errors. 2013-05-17 01:24:19 -04:00
Paul Smith
b730fbc6b8 Remove the dlopen() pointer from struct filedef.
This pointer is almost never needed, and it increases the size of the filedef
struct for all files (of which there are a huge number for large builds).
Instead keep a bit field marking whether the file is a loaded object and if so
call a new function to unload it.  In load.c we keep a simple linked list of
loaded objects (of which there will be very few typically) and their dlopen()
pointers.
2013-05-17 01:20:39 -04:00
Paul Smith
c21c1455fd Add requirement for plugin_is_GPL_compatible symbol in loaded objects. 2013-05-14 22:53:42 -04:00
Paul Smith
58dae24352 [Savannah #20501] Handle adding -r/-R to MAKEFLAGS in the makefile.
If -R is set in the makefile and not the command line, then go through all the
default variables and undefine them.  If -r is set in the makefile and not in
the command line, then remove all .SUFFIX prefixes (unless the user set it)
and SUFFIX variable setting.  In -p mode don't print builtins.
2013-05-13 04:30:20 -04:00
Paul Smith
c7732bd5ad Add a new variable: GNUMAKEFLAGS
This allows you to write portable makefiles that set GNU make-specific command
line options in the environment or makefile: add them to GNUMAKEFLAGS instead
of MAKEFLAGS and they will be seen by GNU make but ignored by other
implementations of make.
2013-05-13 02:48:18 -04:00
Paul Smith
2627d83221 Use level o_env_override for MAKEFLAGS so it's reset even with -e.
Fixes Savannah bug #2216.
2013-05-13 02:30:14 -04:00
Paul Smith
381baeef7a Add new --trace[=MODE] flags, with --trace=dir
This mode replaces the previous heuristic setting enabled with -O, where we
would log directory enter/leave for each synchronized output.  Now we only
do that if --trace=dir is given.
2013-05-13 01:30:24 -04:00
Eli Zaretskii
5367d393dd Avoid printing stdout and stderr messages without a newline between them.
job.c (child_out): Output the newline following the message
 before fllush-ing the stream.  Avoids displaying the following
 failure message, which goes to stderr, on the same line.
2013-05-11 17:42:56 +03:00
Eli Zaretskii
f0529daced Rearrange dllimport/dllexport declarations for MS-Windows.
gnumake.h (GMK_EXPORT) [_WIN32]: Move the dllexport declaration
 here from makeint.h.
 makeint.h (GMK_BUILDING_MAKE) [WINDOWS32]: Define before
 including gnumake.h.
2013-05-06 20:18:58 +03:00
Eli Zaretskii
a668c520b2 doc/make.texi (Loaded Object Example): Add a note about building
shared objects on MS-Windows.
2013-05-06 20:16:40 +03:00
Stefano Lattarini
c8bf04e141 build: enable 'subdir-objects' and 'silent-rules' automake options
On 04/30/2013 05:11 PM, Stefano Lattarini wrote:
> * configure.ac (AM_INIT_AUTOMAKE): Here.  The future major Automake
> version 2.0 (ETA about one, one and half year from now) will likely
> enable them by default, so better prepare ourselves.
>
Please drop this patch.  Enabling 'subdir-objects' would require
sublter changes to several other parts of the build system that I
don't know how to test properly.  We should only enable the
'silent-rules' option for the moment.  The updated patch below
does this.

Sorry for the noise,
  Stefano

---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ----

>From 46623411f017a447caa8fe75b3b42ec2fbeac458 Mon Sep 17 00:00:00 2001
Message-Id: <46623411f017a447caa8fe75b3b42ec2fbeac458.1367335124.git.stefano.lattarini@gmail.com>
From: Stefano Lattarini <stefano.lattarini@gmail.com>
Date: Tue, 30 Apr 2013 16:30:04 +0200
Subject: [PATCH] build: enable the 'silent-rules' automake options

* configure.ac (AM_INIT_AUTOMAKE): Here.  The future major Automake
version 2.0 (ETA about one, one and half year from now) will enable
it by default, so better prepare ourselves.

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-05-06 00:30:19 -04:00
Stefano Lattarini
0a56034aac build: require Autoconf >= 2.62 and Automake >= 1.11.1
Older versions of those tools should be considered fully obsolete.
Also, GNU make already requires Gettext >= 0.18.1, which has been
released six months after Automake 1.11.1 and two years after
Autoconf 2.62; so the new requirement shouldn't be problematic
for people already bootstrapping GNU make from the Git repository.

* configure.ac (AC_PREREQ): Require Autoconf 2.62 or later.
(AM_INIT_AUTOMAKE): Require Automake 1.11.1 or later (1.11 had
some serious bugs, and should not be used).

Copyright-paperwork-exempt: yes
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-05-06 00:26:29 -04:00
Paul Smith
94735f0ad7 Remove use of vfork().
GCC was giving us warnings, most OS's now just run fork() when you call
vfork(), and looking at the standard definition of vfork() we are a long way
from using it safely anyway: you're not allowed to even call a function before
you exec().
2013-05-06 00:22:27 -04:00
Stefano Lattarini
7c77486d1f docs: port manual to Texinfo 5.x
* doc/make.texi: Here.  It was sufficient to change an '@itemx'
into an '@item'.

Copyright-paperwork-exempt: yes
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-05-05 20:51:05 -04:00
Stefano Lattarini
13f13b96b3 cosmetics: fix few innocuous typos
Most of these were found using Lucas De Marchi's 'codespell' tool.

* ChangeLog: Fix minor typos.
* ChangeLog.2: Likewise.
* README.Amiga: Likewise.
* TODO.private: Likewise.
* function.c: Likewise.
* glob/glob.h: Likewise.
* job.c: Likewise.
* main.c: Likewise.
* readme.vms: Likewise.
* remake.c: Likewise.
* tests/ChangeLog: Likewise.
* tests/NEWS: Likewise.
* tests/README: Likewise.
* tests/scripts/variables/private: Likewise.
* vmsdir.h: Likewise.
* signame.c: Likewise.  While at it, improve line wrapping in the
touched comment.

Copyright-paperwork-exempt: yes
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-05-05 20:50:37 -04:00
Stefano Lattarini
c3cd78066c build: get rid of 'HAVE_ANSI_COMPILER' C preprocessor conditional
GNU make already assume C89 or later throughout the codebase, and
that preprocessor conditional was no longer used anyway.

* configure.ac: Remove AC_DEFINE of HAVE_ANSI_COMPILER.
* config.ami.template: Remove #define of HAVE_ANSI_COMPILER.
* config.h-vms.template: Likewise.
* config.h.W32.template: Likewise.
* configh.dos.template: Likewise.

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-05-05 20:45:44 -04:00
Paul Smith
15f7957939 Rename the -O "job" mode to "line" and "make" to "recurse". 2013-05-05 20:19:00 -04:00
Paul Smith
1d992d8fe7 Ensure command lines are written synchronously with -O.
If output-sync is enabled, have make write the command line to the temp file
instead of printing it directly to the screen to ensure that the output is
ordered properly.  Also, remove extraneous enter/leave operations by having
them printed directly when dumping temp file output.
2013-05-05 17:03:51 -04:00
Paul Smith
3484c9675a Add memory allocation cleanup to loadable objects.
Add gmk_alloc() and gmk_free() functions so loadable objects can access our
memory model.  Also provide a more extensive example in the manual.
2013-05-04 17:38:53 -04:00
Paul Smith
a0c5d0c63f Don't pump output to the descriptor, as we use FILE* elsewhere. 2013-05-04 17:31:20 -04:00
Eli Zaretskii
64dd61bcb8 Minor portabiulity fixes for MS-Windows.
makeint.h (ftruncate) [_MSC_VER]: Redirect to _chsize.
 (_S_ISDIR): If not defined (MinGW64), define to S_ISDIR.
2013-05-04 21:03:55 +03:00
Paul Smith
75336026ae Merge branch 'master' of git.savannah.gnu.org:/srv/git/make 2013-05-04 13:14:39 -04:00
Paul Smith
b8467292c9 Improve sync handling for -Ojob/-Otarget and recursion.
If we are not going to sync a command line then dump any collected output
first to preserve ordering.  Do some code cleanup:
  * Move the handle init to a separate function.
  * Move the temp file truncation to the output function.
  * Remember whether we sync in a variable for readability.
  * Handle EINTR and short writes in child_out().
  * Always call sync_output() in case output_sync was changed due to error.
2013-05-04 13:10:56 -04:00
Eli Zaretskii
e44c51ce41 Fix a typo in the manual. 2013-05-04 17:19:56 +03:00
Eli Zaretskii
cb2be0db36 Fix a possibly confusing comment at end of pump_from_tmp_fd. 2013-05-04 10:56:32 +03:00
Eli Zaretskii
01bad6f73a Fix the MS-Windows branch of output_sync code.
job.c (start_job_command): Make the condition for creating a
 temporary output file be identical to the Posix code branch.
 Suggested by Frank Heckenbach <f.heckenbach@fh-soft.de>.
2013-05-04 10:41:11 +03:00
Eli Zaretskii
82793f85f5 Fix invocation of Windows batch files with whitespace in their names.
w32/subproc/sub_proc.c: Include makeint.h.  Remove a private
 incompatible prototype of xmalloc.
 (batch_file_with_spaces): New function, detects Windows batch
 files whose names include whitespace characters.
 (process_begin): If exec_name is a batch file with whitespace
 characters in its name, pass NULL as the first argument to
 CreateProcess.  This avoids weird failures due to buggy quoting by
 CreateProcess.  For the details, see the discussion starting at
 http://lists.gnu.org/archive/html/make-w32/2013-04/msg00008.html.
2013-05-03 16:24:24 +03:00
Eli Zaretskii
a66469e003 Fix interfacing with and remaking dynamic objects on MS-Windows.
load.c (load_object, load_file): Accept an additional argument
 DLP and return in it a pointer that can be used to unload the
 dynamic object.
 read.c (eval): Call load_file with an additional argument, and
 record the pointer returned there in the 'struct file' object of
 dynamic objects in that object's 'struct file'.
 commands.c (execute_file_commands): Unload dynamic objects
 before remaking them, to avoid failure to remake if the OS doesn't
 allow overwriting objects that are in use.
 filedef.h (struct file): New member dlopen_ptr.
 gnumake.h (GMK_EXPORT): Define to dllexport/dllimport
 decorations for Windows and to nothing on other platforms.
 (gmk_eval, gmk_expand, gmk_add_function): Add GMK_EXPORT qualifier
 to prototypes.
 makeint.h (MAIN): Define before including gnumake.h, to give
 correct dllexport decorations to exported functions.
 (load_file): Adjust prototype.
 loadapi.c: Don't include gnumake.h, since makeint.h already
 includes it, and takes care of defining MAIN before doing so.
 build_w32.bat (LinkGCC): Produce an import library for functions
 exported by Make for loadable dynamic objects.

 w32/compat/posixfcn.c (dlclose): New function.
 w32/include/dlfcn.h (dlclose): Add prototype.

 scripts/features/load: Fix signatures of testload_gmk_setup and
 explicit_setup, to bring them in line with the documentation.
2013-05-03 16:09:12 +03:00
Eli Zaretskii
b5ea49bae7 Mention in NEWS change on Windows with quotes in command lines. 2013-05-01 18:41:14 +03:00
Eli Zaretskii
2926f7b466 Fix treatment of whitespace after a backslash on MS-Windows.
job.c (construct_command_argv_internal): Don't treat a backslash as an
 escape character before whitespace, if the shell is not a Posix
 shell.   For the description of the problem, see
 http://lists.gnu.org/archive/html/make-w32/2013-04/msg00014.html.
2013-05-01 18:31:53 +03:00
Eli Zaretskii
a87ff20158 job.c (start_job_command) [WINDOWS32]: Make the same fix for
MS-Windows as the previous commit did for Posix platforms.
2013-05-01 18:15:16 +03:00
Paul Smith
9acb657eb1 Don't synchronize output for recursive make unless -Omake 2013-05-01 07:59:24 -04:00
Eli Zaretskii
19a69bafc0 Support dynamic object loading on MS-Windows.
w32/include/dlfcn.h: New file.
 w32/compat/posixfcn.c: Include dlfcn.h.
 (dlopen, dlerror, dlsym) [MAKE_LOAD]: New functions, in support of
 dynamic loading.

 config.h.W32.template (MAKE_LOAD): Define.
 load.c (load_object) [HAVE_DOS_PATHS]: Support backslashes and
 drive letters in file names of dynamic objects.
2013-04-29 19:26:06 +03:00
Eli Zaretskii
9a7fe22b19 Fix the .ONESHELL operation on MS-Windows.
job.c (construct_command_argv_internal) [WINDOWS32]: Return
 right after generating new_argv for one_shell case.  This fixes
 the Windows build for both Unixy shell and stock Windows shells.
2013-04-29 19:17:07 +03:00
Paul Smith
9253a34a57 Merge branch 'master' of git.savannah.gnu.org:/srv/git/make 2013-04-28 19:25:24 -04:00
Paul Smith
f88eb23b02 Ensure error messages are printed with sync'd output.
Enhance the child_error() function so that it will write error output to the
child's sync output buffer, if it exists.  If it doesn't the output goes to
stdout/stderr.
2013-04-28 19:09:20 -04:00
Paul Smith
441b643355 Remove support for pre-ANSI variadic function calls.
We've required support for ANSI C (ISO C 89) or better for quite a while.  Get
rid of the old varags.h, doprnt() stuff and simply assume ANSI C variadic
function capability and basic C runtime library support (vfprintf, vsprintf,
etc.)
2013-04-28 17:59:28 -04:00
Paul Smith
8b034b7d18 Small cleanups and fixes. 2013-04-28 17:31:46 -04:00
Eli Zaretskii
5667376edc Fix Savannah bug #37065 with $(wildcard foo/*/.) returning non-directories.
dir.c (local_stat) [WINDOWS32]: Use the wrapper on MS-Windows.
 If the argument ends in "dir/.", make sure the parent dir exists
 and is indeed a directory.  Fixes Savannah bug #37065.
2013-04-28 20:53:36 +03:00
Paul Smith
93843ccd08 Fix a few compiler warnings found by Eli. 2013-04-28 01:41:47 -04:00
Paul Smith
7f01830927 Add support for per-job output sync.
A new flag to the -O/--output-sync, "job", selects a per-job (that is, per
line of a recipe) output synchronization.  To support this move the close of
the temp file out of the sync_output() function and don't do it until we free
the child, since we may call sync_output() multiple times in a given recipe.
When we set up for a new temp file, if we're in per-job mode we truncate the
file and seek to the beginning to re-use it for every job.
2013-04-28 01:19:19 -04:00
Paul Smith
30843dea3a Fix support for .ONESHELL when dealing with non-POSIX shells. 2013-04-27 17:28:05 -04:00
Paul Smith
14d7654551 Rework the implementation of load.c to increase portability.
It should be sufficient, now, to write a new version of the load_object()
function.  That function won't be called unless we really want to load, so all
checking and parsing is taken care of before that.
2013-04-27 16:57:05 -04:00
Paul Smith
054d6d91e7 Merge branch 'master' of git.savannah.gnu.org:/srv/git/make 2013-04-27 16:24:08 -04:00
Eli Zaretskii
e56aad4061 Support .ONESHELL on MS-Windows, for default Windows shells.
read.c (record_files): Pay attention to .ONESHELL in MS-Windows.
 job.c (construct_command_argv_internal): Support .ONESHELL on
 MS-Windows, when the shell is not a Unixy shell.
2013-04-27 19:12:01 +03:00
Eli Zaretskii
049f8e88fc job.c: Fix compilation error on GNU/Linux due to "label at end of compound statement". 2013-04-27 14:30:01 +03:00
Eli Zaretskii
da7df54309 Support --output-sync on MS-Windows.
w32/compat/posixfcn.c: New file, with emulations of Posix
 functions and Posix functionality for MS-Windows.
 w32/subproc/sub_proc.c: Include io.h.
 (process_noinherit): New function, forces a file descriptor to not
 be inherited by child processes.
 (process_easy): Accept two additional arguments, and use them to
 set up the standard output and standard error handles of the child
 process.
 w32/include/sub_proc.h (process_easy): Adjust prototype.
 (process_noinherit): Add prototype.

 read.c [WINDOWS32]: Include windows.h and sub_proc.h.
 makeint.h (LOCALEDIR) [WINDOWS32}: Define to NULL if not
 defined.  This is needed because the MS-Windows build doesn't have
 a canonical place for LOCALEDIR.
 (WIN32_LEAN_AND_MEAN) [WINDOWS32]: Define, to avoid getting from
 windows.h header too much stuff that could conflict with the code.
 main.c <sync_mutex>: New static variable.
 <switches>: Add support for "--sync-mutex" switch.
 (decode_output_sync_flags): Decode the --sync-mutex= switch.
 (prepare_mutex_handle_string) [WINDOWS32]: New function.
 (main): Add "output-sync" to .FEATURES.
 job.h (CLOSE_ON_EXEC) [WINDOWS32]: Define to call
 process_noinherit.
 (F_GETFD, F_SETLKW, F_WRLCK, F_UNLCK, struct flock) [WINDOWS32]:
 New macros.
 (RECORD_SYNC_MUTEX): New macro, a no-op for Posix platforms.
 (sync_handle_t): New typedef.
 job.c <sync_handle>: Change type to sync_handle_t.
 (FD_NOT_EMPTY): Seek to the file's end.  Suggested by Frank
 Heckenbach <f.heckenbach@fh-soft.de>.
 (pump_from_tmp_fd) [WINDOWS32]: Switch to_fd to binary mode for
 the duration of this function, and then change back before
 returning.
 (start_job_command) [WINDOWS32]: Support output_sync mode on
 MS-Windows.  Use a system-wide mutex instead of locking
 stdout/stderr.  Call process_easy with two additional arguments:
 child->outfd and child->errfd.
 (exec_command) [WINDOWS32]: Pass two additional arguments, both
 -1, to process_easy, to adjust for the changed function signature.
 function.c (windows32_openpipe) [WINDOWS32]: This function now
 returns an int, which is -1 if it fails and zero otherwise.  It
 also calls 'error' instead of 'fatal', to avoid exiting
 prematurely.
 (func_shell_base) [WINDOWS32]: Call perror_with_name if
 windows32_openpipe fails, now that it always returns.  This avoids
 a compiler warning that error_prefix is not used in the MS-Windows
 build.
 config.h.W32.template (OUTPUT_SYNC): Define.
 build_w32.bat: Add w32/compat/posixfcn.c to compilation and
 linking commands.

 From Frank Heckenbach <f.heckenbach@fh-soft.de>:
 job.c (sync_output): Don't discard the output if
 acquire_semaphore fails; instead, dump the output unsynchronized.
2013-04-27 14:20:49 +03:00
Eli Zaretskii
f3a4b4ce6f Improve MS-Windows build scripts.
build_w32.bat: Improve.  Remove 'setlocal', as it isn't
 supported on Windows 9X.  Add --help and usage instructions.
 Support both debug and optimized builds with GCC under --debug.
 If building out of Git repo, always produce config.h, and edit
 gmk-default.scm into gmk-default.h.
 w32/subproc/build.bat: Support debug and optimized builds with
 GCC.
2013-04-25 20:41:53 +03:00
Stefano Lattarini
0daa9d37c4 Reflect the 'configure.in' -> 'configure.ac' rename throughout
In README, code comments, and auxiliary files.

Copyright-paperwork-exempt: yes
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
2013-04-21 19:21:43 -04:00
Paul Smith
50e2cb1b1a Some cleanups for Windows builds after the output-sync option.
Note currently output-sync is not supported on Windows.
2013-04-16 19:51:29 -04:00
Paul Smith
330d97a9ba Cleanup some source and fix autoconf warnings. 2013-04-16 01:47:05 -04:00
Paul Smith
b5d017c624 Create an open_tmpfd() function to return temp files by FD. Use it. 2013-04-16 01:03:59 -04:00
Paul Smith
79e9347892 Save the output from the entire recipe, not per-job. 2013-04-15 19:17:19 -04:00
Paul Smith
2bd957a89d Change the arg option for -O from numeric to string. 2013-04-15 13:22:51 -04:00
Paul Smith
7f7e6f80c5 Modify output-sync tests to be more reliable. 2013-04-15 10:33:42 -04:00
Paul Smith
af87d56157 Handle test timeouts in a more understandable way. 2013-04-14 19:11:47 -04:00
Paul Smith
4bf3c33f83 Rename the "parallel-sync" option to "output-sync". 2013-04-14 16:31:18 -04:00
Frank Heckenbach
cb64352c75 Initial patch for output synchronization. See Savannah bug #33138.
Based on work by David Boyce <David.S.Boyce@gmail.com>.
2013-04-14 15:38:07 -04:00
Paul Smith
6a52395ed1 Clarify LDFLAGS vs. LDLIBS. Fixes Savannah bug #37970. 2013-04-06 10:51:57 -04:00
Paul Smith
29cd1e9699 Reconsider targets waiting for prerequisites. Fixes Savannah bug #37703. 2013-04-06 10:29:20 -04:00
Paul Smith
450b7e1a3d Use ENULLLOOP to handle EINTR during realpath(). Fixes Savannah bug #38420 2013-02-28 00:55:15 -05:00
Paul Smith
5058a94ee7 Expand the loadable object support.
Provide a simple API for loaded objects to interact with GNU make.  I still
won't guarantee that this API won't change but it's much closer to something
that's supported and provides easy-to-use interfaces with a public header
file.
2013-02-25 01:38:36 -05:00
Paul Smith
4baf9ab456 Adding new file. 2013-01-20 16:36:28 -05:00
Paul Smith
ac1c6b404a Create externally referencable header file "gnumake.h".
Move the gmk_floc type to gnumake.h.
2013-01-20 13:39:54 -05:00
Paul Smith
51fb930ef2 Rename struct floc to typedef gmk_floc as an externally scoped symbol. 2013-01-20 13:16:46 -05:00
Paul Smith
a45f25ece3 Rename the make.h file to makeint.h for internal use only. 2013-01-20 11:33:20 -05:00
Paul Smith
b70aa3709e Allow dynamically loaded objects to be rebuilt by make. 2013-01-20 00:55:57 -05:00
Paul Smith
8e0a5645b8 Add more documentation on Git workflow and rules. 2013-01-19 17:11:23 -05:00
Eli Zaretskii
7899c6f383 Fix a typo in ChangeLog. 2013-01-18 18:02:16 +02:00
Paul Smith
6ca41d9b17 [SV #37878] Add a check for targets with parens that are not archives. 2013-01-13 12:40:13 -05:00
Paul Smith
686a74bfb2 [SV #38051] Recover all MAKEFLAGS after makefile rebuild step is complete.
Patch suggested by Frank Heckenbach <f.heckenbach@fh-soft.de>.
2013-01-13 12:21:01 -05:00
Paul Smith
ca17e5538f Add ChangeLog entries for Git migration. 2013-01-13 12:17:03 -05:00
Paul Smith
5c69b3fe53 Change configure.in to configure.ac, and other Git fixes. 2013-01-12 22:38:17 -05:00
Paul Smith
1d298acf9d Ensure parallel test works properly. 2013-01-12 21:54:41 -05:00
Paul Smith
5a5a1aff6a Fix clean rules. 2013-01-12 21:53:15 -05:00
Paul Smith
002702c89c Modify instructions, etc. for Git support. 2013-01-12 19:31:13 -05:00
Paul Smith
a3bd466e25 Modify .gitignore for proper formatting. 2013-01-12 17:56:25 -05:00
Paul Smith
97fe6e7dd1 Rename CVS ignore files to .gitignore 2013-01-12 17:48:58 -05:00
151 changed files with 11484 additions and 7046 deletions

View File

@@ -1,37 +0,0 @@
*.gz *.Z *.tar *.tgz
=*
TODO COPYING* ABOUT-NLS
make-3* make-test*
*.info *.info-*
stamp-*
makebook*
.*gdbinit
.gdb_history
*.dep *.dvi *.toc *.aux *.log
*.cp *.cps *.fn *.fns *.vr *.vrs *.tp *.tps *.ky *.kys *.pg *.pgs
README README.DOS README.W32 README.OS2
aclocal.m4 autom4te.cache
config.h.in config.h config.status config.cache configure
Makefile.in Makefile
build.sh.in build.sh
SMakefile NMakefile Makefile.DOS
config.ami configh.dos config.h.W32 config.h-vms
loadavg loadavg.c make
gmk-default.h
.deps .dep_segment ID TAGS
_*
sun4 i386 i386-netbsd hp300-netbsd hp300 rs6000 sun3 news800 amiga
hp700 hp834 mips sol2 i486-linux
customs
install-sh mkinstalldirs
.directive.asc

46
.gitignore vendored Normal file
View File

@@ -0,0 +1,46 @@
# Development artifacts
ID
TAGS
.*gdbinit
.gdb_history
*~
#*
.#*
# Configure artifacts
ABOUT-NLS
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.h
config.h.in
config.log
config.status
configure
stamp-h1
# Build artifacts
.deps
gmk-default.h
loadavg
make
*.o
# Distribution artifacts
.dep_segment
Makefile.DOS
NMakefile
README
README.DOS
README.OS2
README.W32
SMakefile
build.sh
build.sh.in
config.ami
config.h-vms
config.h.W32
configh.dos
make-[0-9]*/
make-[0-9]*.tar.*

View File

@@ -37,10 +37,11 @@ GNU make porting efforts:
Port to MS-DOS (DJGPP), OS/2, and MS-Windows (native/MinGW) by: Port to MS-DOS (DJGPP), OS/2, and MS-Windows (native/MinGW) by:
DJ Delorie <dj@delorie.com> DJ Delorie <dj@delorie.com>
Rob Tulloh <rob_tulloh@tivoli.com> Rob Tulloh <rob_tulloh@tivoli.com>
Eli Zaretskii <eliz@is.elta.co.il> Eli Zaretskii <eliz@gnu.org>
Jonathan Grant <jg@jguk.org> Jonathan Grant <jg@jguk.org>
Andreas Beuning <andreas.buening@nexgo.de> Andreas Beuning <andreas.buening@nexgo.de>
Earnie Boyd <earnie@uses.sf.net> Earnie Boyd <earnie@uses.sf.net>
Troy Runkel <Troy.Runkel@mathworks.com>
----------------------------------- -----------------------------------
Other contributors: Other contributors:
@@ -64,12 +65,14 @@ Other contributors:
Carl Staelin (Princeton University) Carl Staelin (Princeton University)
Ian Stewartson (Data Logic Limited) Ian Stewartson (Data Logic Limited)
David A. Wheeler <dwheeler@dwheeler.com> David A. Wheeler <dwheeler@dwheeler.com>
David Boyce <dsb@boyski.com>
Frank Heckenbach <f.heckenbach@fh-soft.de>
With suggestions/comments/bug reports from a cast of ... well ... With suggestions/comments/bug reports from a cast of ... well ...
hundreds, anyway :) hundreds, anyway :)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1997-2012 Free Software Foundation, Inc. Copyright (C) 1997-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

1052
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@@ -1703,7 +1703,7 @@ Thu Sep 14 18:29:38 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
existing variable's origin, is `o_env', make it `o_env_override'. existing variable's origin, is `o_env', make it `o_env_override'.
* load.c: Use the symbol KERNEL_FILE_NAME instead of KERNEL_FILE. * load.c: Use the symbol KERNEL_FILE_NAME instead of KERNEL_FILE.
* compatMakefile: Changed the comment for `LOAD_AVG' accordinly. * compatMakefile: Changed the comment for `LOAD_AVG' accordingly.
Thu Sep 7 16:46:26 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU) Thu Sep 7 16:46:26 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
@@ -3218,7 +3218,7 @@ Sun Feb 5 19:52:38 1989 Roland McGrath (mcgrath at paris.Berkeley.EDU)
* variable.c (expand_function: `shell'): Use * variable.c (expand_function: `shell'): Use
`shell_function_completed'. Block children before forking and `shell_function_completed'. Block children before forking and
unblock after `shell_function_pid' is set properly and unblock after `shell_function_pid' is set properly and
`shell_functon_completed' is reset to 0. `shell_function_completed' is reset to 0.
* commands.c (child_handler): When the child of the `shell' function * commands.c (child_handler): When the child of the `shell' function
completes, set `shell_function_completed' to 1 if it actually ran, completes, set `shell_function_completed' to 1 if it actually ran,
@@ -4465,7 +4465,7 @@ Fri Sep 16 13:59:59 1988 Roland McGrath (mcgrath at tully.Berkeley.EDU)
`maxsuffix', and must be called before count_implicit_rule_limits. `maxsuffix', and must be called before count_implicit_rule_limits.
* rule.c (pattern_search): If an existent (non-intermediate) * rule.c (pattern_search): If an existent (non-intermediate)
dependendency was found via a terminal rule, set its dependency was found via a terminal rule, set its
`tried_implicit' flag, so it will never have implicit rule search done. `tried_implicit' flag, so it will never have implicit rule search done.
* glob.c: Bug fix to avoid alloca(0). * glob.c: Bug fix to avoid alloca(0).
@@ -4826,7 +4826,7 @@ Sat Jul 30 15:47:23 1988 Roland McGrath (mcgrath at tully.Berkeley.EDU)
new entry as the old entry's prev pointer. new entry as the old entry's prev pointer.
* dir.c: Re-indented the `struct dir' definition to be right. * dir.c: Re-indented the `struct dir' definition to be right.
(dir_load): Cleaned up slighty. (dir_load): Cleaned up slightly.
(file_exists_p): Removed comment saying we could use `access', since (file_exists_p): Removed comment saying we could use `access', since
that is a bad idea (except for setuid programs). Cleaned up slightly. that is a bad idea (except for setuid programs). Cleaned up slightly.

View File

@@ -3080,7 +3080,7 @@ Sun May 12 19:19:43 1996 Aaron Digulla <digulla@fh-konstanz.de>
* main.c: (main), variable.c Changed handling of ENV-vars. Make * main.c: (main), variable.c Changed handling of ENV-vars. Make
stores now the names of the variables only and reads their contents stores now the names of the variables only and reads their contents
when they are accessed to reflect that these variables are really when they are accessed to reflect that these variables are really
global (ie. they CAN change WHILE make runs !) This handling is global (i.e., they CAN change WHILE make runs !) This handling is
made in lookup_variable() made in lookup_variable()
* Makefile.ami: renamed file.h to filedep.h * Makefile.ami: renamed file.h to filedep.h
@@ -6630,9 +6630,9 @@ Fri Nov 1 19:34:28 1991 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
See ChangeLog.1, available in the CVS repository at: See ChangeLog.1, available in the Git repository at:
http://savannah.gnu.org/cvs/?group=make http://git.savannah.gnu.org/cgit/make.git/tree/
for earlier changes. for earlier changes.

View File

@@ -1,7 +1,7 @@
# -*-Makefile-*- template for DJGPP # -*-Makefile-*- template for DJGPP
# Makefile.in generated automatically by automake 1.2 from Makefile.am # Makefile.in generated automatically by automake 1.2 from Makefile.am
# #
# Copyright (C) 1994-2012 Free Software Foundation, Inc. # Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -88,7 +88,7 @@ INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"$(prefix)$(libdir)\" -DINCLUDEDIR=\"$(pre
BUILT_SOURCES = README build.sh-in BUILT_SOURCES = README build.sh-in
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms README.VMS vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h
SUBDIRS = glob doc SUBDIRS = glob doc
mkinstalldirs = ${exec_prefix}/bin/gmkdir -p mkinstalldirs = ${exec_prefix}/bin/gmkdir -p
@@ -122,7 +122,7 @@ man1dir = $(mandir)/man1
MANS = $(man_MANS) MANS = $(man_MANS)
NROFF = nroff NROFF = nroff
DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh-in config.h-in configure configure.in getloadavg.c DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh-in config.h-in configure configure.ac getloadavg.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@@ -506,7 +506,7 @@ html
# #
dist-hook: dist-hook:
(cd $(srcdir); \ (cd $(srcdir); \
w32=`find w32 -follow \( -name CVS -prune \) -o -type f -print`; \ w32=`find w32 -follow \( -name .git -prune \) -o -type f -print`; \
tar chf - $$w32) \ tar chf - $$w32) \
| (cd $(distdir); tar xfBp -) | (cd $(distdir); tar xfBp -)

View File

@@ -1,6 +1,6 @@
# This is a -*-Makefile-*-, or close enough # This is a -*-Makefile-*-, or close enough
# #
# Copyright (C) 1997-2012 Free Software Foundation, Inc. # Copyright (C) 1997-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -31,6 +31,7 @@ endif
SUBDIRS = glob config po doc $(MAYBE_W32) SUBDIRS = glob config po doc $(MAYBE_W32)
bin_PROGRAMS = make bin_PROGRAMS = make
include_HEADERS = gnumake.h
if USE_CUSTOMS if USE_CUSTOMS
remote = remote-cstms.c remote = remote-cstms.c
@@ -39,9 +40,9 @@ else
endif endif
make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \ make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
function.c getopt.c getopt1.c implicit.c job.c load.c main.c \ function.c getopt.c getopt1.c implicit.c job.c load.c \
misc.c read.c remake.c rule.c signame.c \ loadapi.c main.c misc.c output.c read.c remake.c rule.c \
strcache.c variable.c version.c vpath.c hash.c \ signame.c strcache.c variable.c version.c vpath.c hash.c \
$(remote) $(remote)
if HAVE_GUILE if HAVE_GUILE
@@ -50,8 +51,8 @@ endif
EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
noinst_HEADERS = commands.h dep.h filedef.h job.h make.h rule.h variable.h \ noinst_HEADERS = commands.h dep.h filedef.h job.h makeint.h rule.h variable.h \
debug.h getopt.h gettext.h hash.h debug.h getopt.h gettext.h hash.h output.h
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ \ make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ \
$(GUILE_LIBS) $(GUILE_LIBS)
@@ -81,7 +82,7 @@ EXTRA_DIST = README build.sh.in $(man_MANS) \
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\ README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \ README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
make_msvc_net2003.sln make_msvc_net2003.vcproj \ make_msvc_net2003.sln make_msvc_net2003.vcproj \
readme.vms makefile.vms makefile.com config.h-vms \ README.VMS makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c \ vmsdir.h vmsfunctions.c vmsify.c \
gmk-default.scm gmk-default.h gmk-default.scm gmk-default.h
@@ -144,7 +145,7 @@ gmk-default.h: $(srcdir)/gmk-default.scm
# #
dist-hook: dist-hook:
(cd $(srcdir); \ (cd $(srcdir); \
sub=`find w32 tests -follow \( -name CVS -o -name .deps -o -name work -o -name .cvsignore -o -name \*.orig -o -name \*.rej -o -name \*~ -o -name Makefile \) -prune -o -type f -print`; \ sub=`find w32 tests -follow \( -name .git -o -name .deps -o -name work -o -name .gitignore -o -name \*.orig -o -name \*.rej -o -name \*~ -o -name Makefile \) -prune -o -type f -print`; \
tar chf - $$sub) \ tar chf - $$sub) \
| (cd $(distdir); tar xfBp -) | (cd $(distdir); tar xfBp -)
@@ -183,18 +184,18 @@ loadavg_LDADD = @GETLOADAVG_LIBS@
MAKETESTFLAGS = MAKETESTFLAGS =
check-regression: check-regression:
@if test -f "$(srcdir)/tests/run_make_tests"; then \ @if test -f '$(srcdir)/tests/run_make_tests'; then \
if $(PERL) -v >/dev/null 2>&1; then \ if $(PERL) -v >/dev/null 2>&1; then \
case `cd $(srcdir); pwd` in `pwd`) : ;; \ case `cd '$(srcdir)'; pwd` in `pwd`) : ;; \
*) test -d tests || mkdir tests; \ *) test -d tests || mkdir tests; \
rm -f srctests; \ rm -f srctests; \
if ln -s "$(srcdir)/tests" srctests; then \ if ln -s '$(srcdir)/tests' srctests; then \
for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \
rm -f tests/$$f; ln -s ../srctests/$$f tests; \ rm -f tests/$$f; ln -s ../srctests/$$f tests; \
done; fi ;; \ done; fi ;; \
esac; \ esac; \
echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make$(EXEEXT) $(MAKETESTFLAGS)"; \ echo "cd tests && $(PERL) ./run_make_tests.pl -srcdir $(abs_srcdir) -make ../make$(EXEEXT) $(MAKETESTFLAGS)"; \
cd tests && $(PERL) ./run_make_tests.pl -make ../make$(EXEEXT) $(MAKETESTFLAGS); \ cd tests && $(PERL) ./run_make_tests.pl -srcdir '$(abs_srcdir)' -make '../make$(EXEEXT)' $(MAKETESTFLAGS); \
else \ else \
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
fi; \ fi; \
@@ -206,7 +207,7 @@ check-regression:
# --------------- Maintainer's Section # --------------- Maintainer's Section
# Tell automake that I haven't forgotten about this file and it will be # Tell automake that I haven't forgotten about this file and it will be
# created before we build a distribution (see maintMakefile in the CVS # created before we build a distribution (see maintMakefile in the Git
# distribution). # distribution).
README: README:

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile, run # NOTE: If you have no 'make' program at all to process this makefile, run
# 'build.sh' instead. # 'build.sh' instead.
# #
# Copyright (C) 1995-2012 Free Software Foundation, Inc. # Copyright (C) 1995-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -134,7 +134,7 @@ srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \
$(srcdir)ar.c $(srcdir)arscan.c $(srcdir)strcache.c \ $(srcdir)ar.c $(srcdir)arscan.c $(srcdir)strcache.c \
$(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \
$(srcdir)commands.h $(srcdir)dep.h $(srcdir)filedep.h \ $(srcdir)commands.h $(srcdir)dep.h $(srcdir)filedep.h \
$(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ $(srcdir)job.h $(srcdir)makeint.h $(srcdir)rule.h \
$(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in
@@ -273,36 +273,36 @@ $(objs): config.h
# Automatically generated dependencies will be put at the end of the file. # Automatically generated dependencies will be put at the end of the file.
# Automatically generated dependencies. # Automatically generated dependencies.
commands.o: commands.c make.h dep.h filedef.h variable.h job.h \ commands.o: commands.c makeint.h dep.h filedef.h variable.h job.h \
commands.h commands.h
job.o: job.c make.h job.h filedef.h commands.h variable.h job.o: job.c makeint.h job.h filedef.h commands.h variable.h
dir.o: dir.c make.h dir.o: dir.c makeint.h
file.o: file.c make.h dep.h filedef.h job.h commands.h variable.h file.o: file.c makeint.h dep.h filedef.h job.h commands.h variable.h
misc.o: misc.c make.h dep.h misc.o: misc.c makeint.h dep.h
main.o: main.c make.h dep.h filedef.h variable.h job.h commands.h \ main.o: main.c makeint.h dep.h filedef.h variable.h job.h commands.h \
getopt.h getopt.h
guile.o: guile.c make.h dep.h debug.h variable.h gmk-default.h guile.o: guile.c makeint.h dep.h debug.h variable.h gmk-default.h
read.o: read.c make.h dep.h filedef.h job.h commands.h variable.h \ read.o: read.c makeint.h dep.h filedef.h job.h commands.h variable.h \
glob/glob.h glob/glob.h
remake.o: remake.c make.h filedef.h job.h commands.h dep.h remake.o: remake.c makeint.h filedef.h job.h commands.h dep.h
rule.o: rule.c make.h dep.h filedef.h job.h commands.h variable.h \ rule.o: rule.c makeint.h dep.h filedef.h job.h commands.h variable.h \
rule.h rule.h
implicit.o: implicit.c make.h rule.h dep.h filedef.h implicit.o: implicit.c makeint.h rule.h dep.h filedef.h
default.o: default.c make.h rule.h dep.h filedef.h job.h commands.h \ default.o: default.c makeint.h rule.h dep.h filedef.h job.h commands.h \
variable.h variable.h
variable.o: variable.c make.h dep.h filedef.h job.h commands.h \ variable.o: variable.c makeint.h dep.h filedef.h job.h commands.h \
variable.h variable.h
expand.o: expand.c make.h filedef.h job.h commands.h variable.h expand.o: expand.c makeint.h filedef.h job.h commands.h variable.h
function.o: function.c make.h filedef.h variable.h dep.h job.h \ function.o: function.c makeint.h filedef.h variable.h dep.h job.h \
commands.h amiga.h commands.h amiga.h
vpath.o: vpath.c make.h filedef.h variable.h vpath.o: vpath.c makeint.h filedef.h variable.h
strcache.o: strcache.c make.h hash.h strcache.o: strcache.c makeint.h hash.h
version.o: version.c version.o: version.c
ar.o: ar.c make.h filedef.h dep.h ar.o: ar.c makeint.h filedef.h dep.h
arscan.o: arscan.c make.h arscan.o: arscan.c makeint.h
signame.o: signame.c signame.h signame.o: signame.c signame.h
remote-stub.o: remote-stub.c make.h filedef.h job.h commands.h remote-stub.o: remote-stub.c makeint.h filedef.h job.h commands.h
getopt.o: getopt.c getopt.o: getopt.c
getopt1.o : getopt1.c getopt.h getopt1.o : getopt1.c getopt.h
getloadavg.o: getloadavg.c getloadavg.o: getloadavg.c
amiga.o: amiga.c make.h variable.h amiga.h amiga.o: amiga.c makeint.h variable.h amiga.h

110
NEWS
View File

@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*- GNU make NEWS -*-indented-text-*-
History of user-visible changes. History of user-visible changes.
05 March 2012 09 Oct 2013
See the end of this file for copyrights and conditions. See the end of this file for copyrights and conditions.
@@ -9,7 +9,7 @@ manual, which is contained in this distribution as the file doc/make.texi.
See the README file and the GNU make manual for instructions for See the README file and the GNU make manual for instructions for
reporting bugs. reporting bugs.
Version 3.99.90 Version 4.0 (09 Oct 2013)
A complete list of bugs fixed in this version is available here: A complete list of bugs fixed in this version is available here:
@@ -23,17 +23,40 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* Each backslash/newline (plus subsequent whitespace) is converted to a * Each backslash/newline (plus subsequent whitespace) is converted to a
single space single space
* New feature: GNU Guile integration
This version of GNU make can be compiled with GNU Guile integration.
GNU Guile serves as an embedded extension language for make.
See the "Guile Function" section in the GNU Make manual for details.
Currently GNU Guile 1.8 and 2.0+ are supported. In Guile 1.8 there is no
support for internationalized character sets. In Guile 2.0+, scripts can be
encoded in UTF-8.
* New command line option: --output-sync (-O) enables grouping of output by
target or by recursive make. This is useful during parallel builds to avoid
mixing output from different jobs together giving hard-to-understand
results. Original implementation by David Boyce <dsb@boyski.com>.
Reworked and enhanced by Frank Heckenbach <f.heckenbach@fh-soft.de>.
Windows support by Eli Zaretskii <eliz@gnu.org>.
* New command line option: --trace enables tracing of targets. When enabled * New command line option: --trace enables tracing of targets. When enabled
the recipe to be invoked is printed even if it would otherwise be suppressed the recipe to be invoked is printed even if it would otherwise be suppressed
by .SILENT or a "@" prefix character. Also before each recipe is run the by .SILENT or a "@" prefix character. Also before each recipe is run the
makefile name and linenumber where it was defined are shown as well as the makefile name and linenumber where it was defined are shown as well as the
prerequisites that caused the target to be considered out of date. prerequisites that caused the target to be considered out of date.
* New command line option argument: --debug now accepts a "n" (none) flag
which disables all debugging settings that are currently enabled.
* New feature: The "job server" capability is now supported on Windows. * New feature: The "job server" capability is now supported on Windows.
Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com> Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com>
* New feature: The .ONESHELL capability is now supported on Windows. Support
added by Eli Zaretskii <eliz@gnu.org>.
* New feature: "!=" shell assignment operator as an alternative to the * New feature: "!=" shell assignment operator as an alternative to the
$(shell ...) function. Implemented for compatibility with BSD makefiles. $(shell ...) function. Implemented for compatibility with BSD makefiles.
Note there are subtle differences between "!=" and $(shell ...). See the
description in the GNU make manual.
WARNING: Backward-incompatibility! WARNING: Backward-incompatibility!
Variables ending in "!" previously defined as "variable!= value" will now be Variables ending in "!" previously defined as "variable!= value" will now be
interpreted as shell assignment. Change your assignment to add whitespace interpreted as shell assignment. Change your assignment to add whitespace
@@ -45,11 +68,6 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
version of POSIX (see http://austingroupbugs.net/view.php?id=330). It is version of POSIX (see http://austingroupbugs.net/view.php?id=330). It is
not necessary to define the .POSIX target to access this operator. not necessary to define the .POSIX target to access this operator.
* New feature: GNU Guile integration
This version of GNU make can be compiled with GNU Guile integration.
GNU Guile serves as an embedded extension language for make.
See the "Guile Function" section in the GNU Make manual for details.
* New feature: Loadable objects * New feature: Loadable objects
This version of GNU make contains a "technology preview": the ability to This version of GNU make contains a "technology preview": the ability to
load dynamic objects into the make runtime. These objects can be created by load dynamic objects into the make runtime. These objects can be created by
@@ -57,8 +75,27 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* New function: $(file ...) writes to a file. * New function: $(file ...) writes to a file.
* On failure, the makefile name and linenumber of the recipe that failed are * New variable: $(GNUMAKEFLAGS) will be parsed for make flags, just like
shown. MAKEFLAGS is. It can be set in the environment or the makefile, containing
GNU make-specific flags to allow your makefile to be portable to other
versions of make. Once this variable is parsed, GNU make will set it to the
empty string so that flags will not be duplicated on recursion.
* New variable: `MAKE_HOST' gives the name of the host architecture
make was compiled for. This is the same value you see after 'Built for'
when running 'make --version'.
* Behavior of MAKEFLAGS and MFLAGS is more rigorously defined. All simple
flags are grouped together in the first word of MAKEFLAGS. No options that
accept arguments appear in the first word. If no simple flags are present
MAKEFLAGS begins with a space. Flags with both short and long versions
always use the short versions in MAKEFLAGS. Flags are listed in
alphabetical order using ASCII ordering. MFLAGS never begins with "- ".
* Setting the -r and -R options in MAKEFLAGS inside a makefile now works as
expected, removing all built-in rules and variables, respectively.
* If a recipe fails, the makefile name and linenumber of the recipe are shown.
* A .RECIPEPREFIX setting is remembered per-recipe and variables expanded * A .RECIPEPREFIX setting is remembered per-recipe and variables expanded
in that recipe also use that recipe prefix setting. in that recipe also use that recipe prefix setting.
@@ -66,8 +103,17 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
* In -p output, .RECIPEPREFIX settings are shown and all target-specific * In -p output, .RECIPEPREFIX settings are shown and all target-specific
variables are output as if in a makefile, instead of as comments. variables are output as if in a makefile, instead of as comments.
* On MS-Windows, recipes that use ".." quoting will no longer force
invocation of commands via temporary batch files and stock Windows
shells, they will be short-circuited and invoked directly. (In
other words, " is no longer a special character for stock Windows
shells.) This avoids hitting shell limits for command length when
quotes are used, but nothing else in the command requires the shell.
This change could potentially mean some minor incompatibilities in
behavior when the recipe uses quoted string on shell command lines.
Version 3.82 Version 3.82 (28 Jul 2010)
A complete list of bugs fixed in this version is available here: A complete list of bugs fixed in this version is available here:
@@ -180,7 +226,7 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set
multi-line variable assignment. multi-line variable assignment.
Version 3.81 Version 3.81 (01 Apr 2006)
* GNU make is ported to OS/2. * GNU make is ported to OS/2.
@@ -303,7 +349,7 @@ Version 3.81
could be found on the system. could be found on the system.
* On VMS there is now support for case-sensitive filesystems such as ODS5. * On VMS there is now support for case-sensitive filesystems such as ODS5.
See the readme.vms file for information. See the README.VMS file for information.
* Parallel builds (-jN) no longer require a working Bourne shell on * Parallel builds (-jN) no longer require a working Bourne shell on
Windows platforms. They work even with the stock Windows shells, such Windows platforms. They work even with the stock Windows shells, such
@@ -321,7 +367,7 @@ A complete list of bugs fixed in this version is available here:
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=103 http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=103
Version 3.80 Version 3.80 (03 Oct 2002)
* A new feature exists: order-only prerequisites. These prerequisites * A new feature exists: order-only prerequisites. These prerequisites
affect the order in which targets are built, but they do not impact affect the order in which targets are built, but they do not impact
@@ -403,7 +449,7 @@ A complete list of bugs fixed in this version is available here:
http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=102 http://savannah.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=102
Version 3.79.1 Version 3.79.1 (23 Jun 2000)
* .SECONDARY with no prerequisites now prevents any target from being * .SECONDARY with no prerequisites now prevents any target from being
removed because make thinks it's an intermediate file, not just those removed because make thinks it's an intermediate file, not just those
@@ -412,7 +458,7 @@ Version 3.79.1
* New configure option --disable-nsec-timestamps, but this was * New configure option --disable-nsec-timestamps, but this was
superseded in later versions by the .LOW_RESOLUTION_TIME pseudo-target. superseded in later versions by the .LOW_RESOLUTION_TIME pseudo-target.
Version 3.79 Version 3.79 (04 Apr 2000)
* GNU make optionally supports internationalization and locales via the * GNU make optionally supports internationalization and locales via the
GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS
@@ -453,9 +499,9 @@ Version 3.79
returned. returned.
* Hartmut Becker provided many updates for the VMS port of GNU make. * Hartmut Becker provided many updates for the VMS port of GNU make.
See the readme.vms file for more details. See the README.VMS file for more details.
Version 3.78 Version 3.78 (22 Sep 1999)
* Two new functions, $(error ...) and $(warning ...) are available. The * Two new functions, $(error ...) and $(warning ...) are available. The
former will cause make to fail and exit immediately upon expansion of former will cause make to fail and exit immediately upon expansion of
@@ -511,7 +557,7 @@ Version 3.78
by running "make check" in the distribution. Note that it requires by running "make check" in the distribution. Note that it requires
Perl (either Perl 4 or Perl 5) to run. Perl (either Perl 4 or Perl 5) to run.
Version 3.77 Version 3.77 (28 Jul 1998)
* Implement BSD make's "?=" variable assignment operator. The variable * Implement BSD make's "?=" variable assignment operator. The variable
is assigned the specified value only if that variable is not already is assigned the specified value only if that variable is not already
@@ -557,11 +603,11 @@ Version 3.77
* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32), * Updates to the Windows 95/NT port from Rob Tulloh (see README.W32),
and to the DOS port from Eli Zaretski (see README.DOS). and to the DOS port from Eli Zaretski (see README.DOS).
Version 3.76.1 Version 3.76.1 (19 Sep 1997)
* Small (but serious) bug fix. Quick rollout to get into the GNU source CD. * Small (but serious) bug fix. Quick rollout to get into the GNU source CD.
Version 3.76 Version 3.76 (16 Sep 1997)
* GNU make now uses automake to control Makefile.in generation. This * GNU make now uses automake to control Makefile.in generation. This
should make it more consistent with the GNU standards. should make it more consistent with the GNU standards.
@@ -606,7 +652,7 @@ Version 3.76
* John W. Eaton has updated the VMS port to support libraries and VPATH. * John W. Eaton has updated the VMS port to support libraries and VPATH.
Version 3.75 Version 3.75 (27 Aug 1996)
* The directory messages printed by `-w' and implicitly in sub-makes, * The directory messages printed by `-w' and implicitly in sub-makes,
are now omitted if Make runs no commands and has no other messages to print. are now omitted if Make runs no commands and has no other messages to print.
@@ -627,7 +673,7 @@ Version 3.75
See README.W32 for details, and direct all Windows-related questions to See README.W32 for details, and direct all Windows-related questions to
<rob_tulloh@tivoli.com>. <rob_tulloh@tivoli.com>.
Version 3.73 Version 3.73 (05 Apr 1995)
* Converted to use Autoconf version 2, so `configure' has some new options. * Converted to use Autoconf version 2, so `configure' has some new options.
See INSTALL for details. See INSTALL for details.
@@ -635,7 +681,7 @@ Version 3.73
* You can now send a SIGUSR1 signal to Make to toggle printing of debugging * You can now send a SIGUSR1 signal to Make to toggle printing of debugging
output enabled by -d, at any time during the run. output enabled by -d, at any time during the run.
Version 3.72 Version 3.72 (04 Nov 1994)
* DJ Delorie has ported Make to MS-DOS using the GO32 extender. * DJ Delorie has ported Make to MS-DOS using the GO32 extender.
He is maintaining the DOS port, not the GNU Make maintainer; He is maintaining the DOS port, not the GNU Make maintainer;
@@ -669,7 +715,7 @@ Version 3.72
of `.SILENT', then the recipe to update that file will not be printed of `.SILENT', then the recipe to update that file will not be printed
before it is run. (This change was made to conform to POSIX.2.) before it is run. (This change was made to conform to POSIX.2.)
Version 3.71 Version 3.71 (21 May 1994)
* The automatic variables `$(@D)', `$(%D)', `$(*D)', `$(<D)', `$(?D)', and * The automatic variables `$(@D)', `$(%D)', `$(*D)', `$(<D)', `$(?D)', and
`$(^D)' now omit the trailing slash from the directory name. (This change `$(^D)' now omit the trailing slash from the directory name. (This change
@@ -691,7 +737,7 @@ Version 3.71
The exit status is 1 only when using -q and some target is not up to date. The exit status is 1 only when using -q and some target is not up to date.
(This change was made to comply with POSIX.2.) (This change was made to comply with POSIX.2.)
Version 3.70 Version 3.70 (03 Jan 1994)
* It is no longer a fatal error to have a NUL character in a makefile. * It is no longer a fatal error to have a NUL character in a makefile.
You should never put a NUL in a makefile because it can have strange You should never put a NUL in a makefile because it can have strange
@@ -702,7 +748,7 @@ Version 3.70
makefile name and line number where the `include' appeared, so Emacs's makefile name and line number where the `include' appeared, so Emacs's
C-x ` command takes you there (in case it's a typo you need to fix). C-x ` command takes you there (in case it's a typo you need to fix).
Version 3.69 Version 3.69 (07 Nov 1993)
* Implicit rule search for archive member references is now done in the * Implicit rule search for archive member references is now done in the
opposite order from previous versions: the whole target name `LIB(MEM)' opposite order from previous versions: the whole target name `LIB(MEM)'
@@ -732,7 +778,7 @@ Version 3.69
* The recipe given for `.DEFAULT' is now used for phony targets with no * The recipe given for `.DEFAULT' is now used for phony targets with no
recipe. recipe.
Version 3.68 Version 3.68 (28 Jul 1993)
* You can list several archive member names inside parenthesis: * You can list several archive member names inside parenthesis:
`lib(mem1 mem2 mem3)' is equivalent to `lib(mem1) lib(mem2) lib(mem3)'. `lib(mem1 mem2 mem3)' is equivalent to `lib(mem1) lib(mem2) lib(mem3)'.
@@ -758,16 +804,16 @@ Version 3.68
to set up variables for them. They used to run with the environment to set up variables for them. They used to run with the environment
that `make' started with. that `make' started with.
Version 3.66 Version 3.66 (21 May 1993)
* `make --version' (or `make -v') now exits immediately after printing * `make --version' (or `make -v') now exits immediately after printing
the version number. the version number.
Version 3.65 Version 3.65 (09 May 1993)
* Make now supports long-named members in `ar' archive files. * Make now supports long-named members in `ar' archive files.
Version 3.64 Version 3.64 (21 Apr 1993)
* Make now supports the `+=' syntax for a variable definition which appends * Make now supports the `+=' syntax for a variable definition which appends
to the variable's previous value. See the section `Appending More Text to the variable's previous value. See the section `Appending More Text
@@ -781,7 +827,7 @@ Version 3.64
* The built-in implicit rules now support the alternative extension * The built-in implicit rules now support the alternative extension
`.txinfo' for Texinfo files, just like `.texinfo' and `.texi'. `.txinfo' for Texinfo files, just like `.texinfo' and `.texi'.
Version 3.63 Version 3.63 (22 Jan 1993)
* Make now uses a standard GNU `configure' script. See the new file * Make now uses a standard GNU `configure' script. See the new file
INSTALL for the new (and much simpler) installation procedure. INSTALL for the new (and much simpler) installation procedure.
@@ -1161,7 +1207,7 @@ Version 3.05
(Changes from versions 1 through 3.05 were never recorded. Sorry.) (Changes from versions 1 through 3.05 were never recorded. Sorry.)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile, # NOTE: If you have no 'make' program at all to process this makefile,
# run 'build_w32.bat' instead. # run 'build_w32.bat' instead.
# #
# Copyright (C) 1996-2012 Free Software Foundation, Inc. # Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -91,6 +91,7 @@ OBJS = \
$(OUTDIR)/job.obj \ $(OUTDIR)/job.obj \
$(OUTDIR)/main.obj \ $(OUTDIR)/main.obj \
$(OUTDIR)/misc.obj \ $(OUTDIR)/misc.obj \
$(OUTDIR)/output.obj \
$(OUTDIR)/read.obj \ $(OUTDIR)/read.obj \
$(OUTDIR)/remake.obj \ $(OUTDIR)/remake.obj \
$(OUTDIR)/remote-stub.obj \ $(OUTDIR)/remote-stub.obj \

View File

@@ -25,8 +25,8 @@ GNU make):
endif @@\ endif @@\
$(CC) Link Make.o To make $(CC) Link Make.o To make
works. Note that the @@ must stand alone (ie. "make@@\" is illegal). works. Note that the @@ must stand alone (i.e., "make@@\" is illegal).
Also be carefull that there is a space after the "\" (ie, at the Also be careful that there is a space after the "\" (i.e., at the
beginning of the next line). beginning of the next line).
- Can be made resident to save space and time - Can be made resident to save space and time
- Amiga specific wildcards can be used in $(wildcard ...) - Amiga specific wildcards can be used in $(wildcard ...)
@@ -36,17 +36,17 @@ BUGS:
dummy.h : src/*.c dummy.h : src/*.c
tries to make dummy.h from "src/*.c" (ie. no wildcard-expansion takes tries to make dummy.h from "src/*.c" (i.e., no wildcard-expansion takes
place). You have to use "$(wildcard src/*.c)" instead. place). You have to use "$(wildcard src/*.c)" instead.
COMPILING FROM SCRATCH COMPILING FROM SCRATCH
---------------------- ----------------------
To recompile, you need SAS/C 6.51. make itself is not neccessary, there To recompile, you need SAS/C 6.51. make itself is not necessary, there
is an smakefile. is an smakefile.
1. Copy config.ami to config.h 1. Copy config.ami to config.h
2. If you use make to compie, copy Makefile.ami to Makefile and 2. If you use make to compile, copy Makefile.ami to Makefile and
glob/Makefile.ami to glob/Makefile. Copy make into the current glob/Makefile.ami to glob/Makefile. Copy make into the current
directory. directory.
@@ -54,14 +54,14 @@ is an smakefile.
INSTALLATION INSTALLATION
Copy make somewhere in your search path (eg. sc:c or sc:bin). Copy make somewhere in your search path (e.g., sc:c or sc:bin).
If you plan to use recursive makes, install make resident: If you plan to use recursive makes, install make resident:
Resident make Add Resident make Add
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1995-2012 Free Software Foundation, Inc. Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -324,7 +324,7 @@ Bug reports:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1996-2012 Free Software Foundation, Inc. Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -160,7 +160,7 @@ from the make source tree.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2003-2012 Free Software Foundation, Inc. Copyright (C) 2003-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,23 +1,33 @@
This is the VMS version of GNU Make, updated by Hartmut Becker This version of GNU make has been tested on
OpenVMS V8.3 (Alpha) and V8.4 (Integrity).
Changes are based on GNU make 3.82.
This version was built and tested on OpenVMS V7.3 (VAX), V7.3-2 (Alpha) and
V8.3-1H1 (I64).
Build instructions Build instructions
------------------
Make a 1st version Make a 1st version
$ @makefile.com ! ignore any compiler and/or linker warning $ @makefile.com ! ignore any compiler and/or linker warning
$ rena make.exe 1st-make.exe $ copy make.exe 1st-make.exe
Use the 1st version to generate a 2nd version Use the 1st version to generate a 2nd version
$ mc sys$disk:[]1st-make clean $ mc sys$disk:[]1st-make clean ! ignore any file not found messages
$ mc sys$disk:[]1st-make $ mc sys$disk:[]1st-make
Verify your 2nd version Verify your 2nd version
$ rena make.exe 2nd-make.exe $ copy make.exe 2nd-make.exe
$ mc sys$disk:[]2nd-make clean $ mc sys$disk:[]2nd-make clean
$ mc sys$disk:[]2nd-make $ mc sys$disk:[]2nd-make
Don't use the HP C V7.2-001 compiler, which has an incompatible change
how __STDC__ is defined. This results at least in compile time warnings.
Changes since GNU make 3.82
---------------------------
Changes (3.81.90) Fix build problems.
The new feature "Loadable objects" is not yet supported. If you need it,
please send a change request or submit a bug report.
The new option --output-sync (-O) is accepted but has no effect: GNU make
for VMS does not support running multiple commands simultaneously.
Changes for GNU make 3.82
Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with Michael Gehre (at VISTEC-SEMI dot COM) supplied a fix for a problem with
timestamps of object modules in OLBs. The timestamps were not correctly timestamps of object modules in OLBs. The timestamps were not correctly
@@ -34,30 +44,6 @@ systems.
Build fixes for const-ified code in VMS specific sources. Build fixes for const-ified code in VMS specific sources.
Build notes:
- Try to avoid HP C V7.2-001, which has an incompatible change
how __STDC__ is defined. This results at least in compile time warnings.
- On V8.3-1H1, if you press Ctrl+C you may see a traceback, starting with
%SYSTEM-F-CONTROLC, operation completed under CTRL/C
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
DECC$SHR C$SIGNAL gsignal 27991 0000000000001180
FFFFFFFF84AB2DA0
DECC$SHR C$SIGNAL raise 28048 0000000000001280
FFFFFFFF84AB2EA0
DECC$SHR C$SIGPENDING decc$$deliver_signals
12475 0000000000000890
FFFFFFFF84C13690
...
This looks like an incompatibility to the Alpha and VAX behavior, so it looks
like a problem in I64 VMS version(s).
- There is no clean build on VAX. In the environment I tested, I had to use GNU
make's alloca which produced a couple of compile time warnings. It seems too
much effort to work on a clean build on VAX.
A note on appending the redirected output. With this change, a simple mechanism A note on appending the redirected output. With this change, a simple mechanism
is implemented to make ">>" work in action lines. In VMS there is no simple is implemented to make ">>" work in action lines. In VMS there is no simple
feature like ">>" to have DCL command or program output redirected and appended feature like ">>" to have DCL command or program output redirected and appended
@@ -78,117 +64,24 @@ happens. Pressing Ctrl+Y to abort make is one case. In case of Ctrl+Y the
associated command procedure is left in SYS$SCRATCH as well. Its name is associated command procedure is left in SYS$SCRATCH as well. Its name is
CMDxxxxx.COM. CMDxxxxx.COM.
Change in the Ctrl+Y handling Change in the Ctrl+Y handling. The CtrlY handler now uses $delprc to delete all
children. This way also actions with DCL commands will be stopped. As before
the CtrlY handler then sends SIGQUIT to itself, which is handled in common
code.
Ctrl+Y was: The CtrlY handler called $forcex for the current child. Change in deleteing temporary command files. Temporary command files are now
deleted in the vms child termination handler. That deletes them even if
Ctrl+Y changed: The CtrlY handler uses $delprc to delete all children. This way a Ctrl+C was pressed.
also actions with DCL commands will be stopped. As before Ctrl+Y then sends
SIGQUIT to itself, which is handled in common code.
Change in deleteing temporary command files
Temporary command files were deleted in the main line, after returning from the
vms child termination handler. If Ctrl+C was pressed, the handler is called but
did not return to main line.
Now, temporary command files are deleted in the vms child termination
handler. That deletes the them even if a Ctrl+C was pressed.
The behavior of pressing Ctrl+C is not changed. It still has only an effect, The behavior of pressing Ctrl+C is not changed. It still has only an effect,
after the current action is terminated. If that doesn't happen or takes too after the current action is terminated. If that doesn't happen or takes too
long, Ctrl+Y should be used instead. long, Ctrl+Y should be used instead.
Changes (3.80) Changes for GNU make 3.80
. In default.c define variable ARCH as IA64 for VMS on Itanium systems. . In default.c define variable ARCH as IA64 for VMS on Itanium systems.
. In makefile.vms avoid name collision for glob and globfree. . In makefile.vms avoid name collision for glob and globfree.
In newer version of the VMS CRTL there are glob and globfree implemented.
Compiling and linking may result in
%ILINK-W-MULDEFLNKG, symbol DECC$GLOBFREE has subsequent linkage definition
in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
%ILINK-W-MULDEF, symbol DECC$GLOBFREE multiply defined
in module DECC$SHR file SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
linker messages (and similar for DECC$GLOB). The messages just say, that
globfree is a known CRTL whose name was mapped by the compiler to
DECC$GLOBFREE. This is done in glob.c as well, so this name is defined
twice. One possible solution is to use the VMS versions of glob and
globfree. However, then the build environment needs to figure out if
there is a new CRTL supporting these or not. This adds complexity. Even
more, these functions return VMS file specifications, which is not
expected by the other make sources. There is a switch at run time (a VMS
logical DECC$GLOB_UNIX_STYLE), which can be set to get Unix style
names. This may conflict with other software. The recommended solution
for this is to set this switch just prior to calling main: in an
initialization routine. This adds more complexity and more VMS specific
code. It is easier to tell the compiler NOT to map the routine names
with a simple change in makefile.vms.
Some notes on case sensitive names in rules and on the disk. In the VMS
template for CONFIG.H case sensitive rules can be enabled with defining
WANT_CASE_SENSITIVE_TARGETS. For recent version of VMS there is a case
sensitive file system: ODS5. To make use of that, additionally un-defining
the HAVE_CASE_INSENSITIVE_FS is required. As these are C macros, different
versions of make need to be built to have any case sensitivity for VMS
working. Unfortunately, for ODS5 disks that's not all.
- Usually DCL upcases command line tokens (except strings) and usually the
file system is case blind (similar to how Windows systems work)
$ set proc/parse=extended/case=sensitive
preserves lower and UPPER on the command line and (for this process and all
sub-processes) enables case sensitivity in the file system
- Usually the CRTL tries to reverse what DCL did with command line tokens, it
lowercases all tokens (except strings)
$ define DECC$ARGV_PARSE_STYLE enable
passes (the now preserved) lower and UPPER from the command line to main()
- Usually the CRTL upcases the arguments to open() and friends
$ define DECC$EFS_CASE_PRESERVE enable
preserves the names as is.
It is important to know that not all VMS tools are ready for case sensitivity.
With this setup some tools may not work as expected. The setup should not
blindly be applied for all users in default login procedures.
Example? The poor coding gives a compiler message, showing that there are
different files:
$ dir
Directory ODS5DISK[HB]
A.c;1 B.c;1 c.c;1 X.c;1
x.c;1
Total of 5 files.
$ ods5make x.obj
cc /obj=x.obj x.c
foo(){lowercase_x();}
......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "lowercase_x" is implicitly declared as a function.
at line number 1 in file ODS5DISK[HB]x.c;1
$ mc SYS$SYSDEVICE:[HARTMUT.MAKE_3_80P]ods5make X.obj
cc /obj=X.obj X.c
foo() {UPPERCASE_X();}
.......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "UPPERCASE_X" is implicitly declared as a function.
at line number 1 in file ODS5DISK[HB]X.c;1
$ dir
Directory ODS5DISK[HB]
A.c;1 B.c;1 c.c;1 X.c;1
x.c;1 X.obj;1 x.obj;1
Total of 7 files.
$
This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com. This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
@@ -353,7 +246,7 @@ replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
somewhere in the future. Be warned, the time resolution inside make is somewhere in the future. Be warned, the time resolution inside make is
less than what vms provides. This might be a problem on the faster Alphas. less than what vms provides. This might be a problem on the faster Alphas.
You can use a : in a filename only if you preceed it with a backslash ('\'). You can use a : in a filename only if you precede it with a backslash ('\').
E.g.- hobbes\:[bogas.files] E.g.- hobbes\:[bogas.files]
Make ignores success, informational, or warning errors (-S-, -I-, or Make ignores success, informational, or warning errors (-S-, -I-, or
@@ -375,7 +268,7 @@ Long command lines are now converted to command files.
Comma (',') as a separator is now allowed. See makefile.vms for an example. Comma (',') as a separator is now allowed. See makefile.vms for an example.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1996-2012 Free Software Foundation, Inc. Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -7,7 +7,7 @@ It builds with the MinGW port of GCC (tested with GCC 3.4.2).
It also builds with MSVC 2.x, 4.x, 5.x, 6.x, and 2003 as well as It also builds with MSVC 2.x, 4.x, 5.x, 6.x, and 2003 as well as
with .NET 7.x and .NET 2003. with .NET 7.x and .NET 2003.
As of version 3.83, a build with Guile is supported (tested with Guile As of version 4.0, a build with Guile is supported (tested with Guile
2.0.3). To build with Guile, you will need, in addition to Guile 2.0.3). To build with Guile, you will need, in addition to Guile
itself, its dependency libraries and the pkg-config program. The itself, its dependency libraries and the pkg-config program. The
latter is used to figure out which compilation and link switches and latter is used to figure out which compilation and link switches and
@@ -293,7 +293,7 @@ Bug reports:
is described in the GNU make manual and the base README. is described in the GNU make manual and the base README.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1996-2012 Free Software Foundation, Inc. Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -96,7 +96,7 @@ SunOS 4.1.x:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1998-2012 Free Software Foundation, Inc. Copyright (C) 1998-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,7 +1,7 @@
-*-text-*- -*-text-*-
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2002-2012 Free Software Foundation, Inc. Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -17,35 +17,65 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. this program. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Obtaining CVS Code Obtaining Git Code
------------------ ------------------
This seems redundant, since if you're reading this you most likely have This seems redundant, since if you're reading this you most likely have
already performed this step; however, for completeness, you can obtain already performed this step; however, for completeness, you can obtain the GNU
the GNU make source code via anonymous CVS from the FSF's Savannah make source code via Git from the FSF's Savannah project
project <http://savannah.gnu.org/projects/make/>: <http://savannah.gnu.org/projects/make/>:
$ cvs -d:pserver:anoncvs@cvs.savannah.gnu.org:/sources/make co make $ git clone git://git.savannah.gnu.org/make.git
You might want to use the "-z3" option to get compression, and you most
certainly will want the -P option to avoid unneeded directories
cluttering up your source. Personally I add these (as well as -dP for
update) to my ~/.cvsrc file.
If you have an older version of CVS, you might have to login first. Changes using Git
There is no password; just hit the ENTER key if you are asked for one.
Building From CVS
----------------- -----------------
To build GNU make from CVS, you will need Autoconf, Automake, and For non-developers, please continue to provide patches as before, or if you
make a public repository I can pull from that if you prefer.
For developers, I'm still new to Git myself, so I don't have a ton of advice.
In this release we will continue to create ChangeLog files by hand so please
don't forget to update the ChangeLog.
Rule #1: Don't rewrite pushed history (don't use "git push --force").
Typical simple workflow might be:
* Edit files
* Use "git status" and "git diff" to verify your changes
* Use "git add" to stage the changes you want to make
* Use "git commit" to commit the staged changes to your local repository
* Use "git pull" to accept & merge new changes from the Savannah repository
* Use "git push" to push your commits back to the Savannah repository
For Emacs users, there are many options for Git integration but I strongly
recommend the Magit package: http://www.emacswiki.org/emacs/Magit
It makes the workflow much clearer, and has advanced features such as
constructing multiple commits from various files and even from different
diff chunks in the same file. There is a video available which helps a lot.
Coding Standards
----------------
GNU make code adheres to the GNU Coding Standards. Additionally, GNU make is
a foundational bootstrap package for the GNU project; as such it is very
conservative about language features it expects. It should build with any C
compiler conforming to the ANSI C89 / ISO C90 standard.
Please use only spaces and no TAB characters in source code.
Building From Git
-----------------
To build GNU make from Git, you will need Autoconf, Automake, and
Gettext, and any tools that those utilities require (GNU m4, Perl, Gettext, and any tools that those utilities require (GNU m4, Perl,
etc.). See the configure.in file to find the minimum versions of each etc.). See the configure.ac file to find the minimum versions of each
of these tools. You will also need a copy of wget. of these tools. You will also need a copy of wget.
When building from CVS you must build in the source directory: "VPATH When building from Git you must build in the source directory: "VPATH
builds" from remote directories are not supported. Once you've created builds" from remote directories are not supported. Once you've created
a distribution, of course, you can unpack it and do a VPATH build from a distribution, of course, you can unpack it and do a VPATH build from
there. there.
@@ -77,7 +107,7 @@ to the point where you can run "make".
a platform-local make you may get problems with missing files in doc/. a platform-local make you may get problems with missing files in doc/.
At this point you have successfully brought your CVS copy of the GNU At this point you have successfully brought your Git copy of the GNU
make source directory up to the point where it can be treated make source directory up to the point where it can be treated
more-or-less like the official package you would get from ftp.gnu.org. more-or-less like the official package you would get from ftp.gnu.org.
That is, you can just run: That is, you can just run:
@@ -87,7 +117,7 @@ That is, you can just run:
to build and install GNU make. to build and install GNU make.
Windows builds from CVS Windows builds from Git
----------------------- -----------------------
If you have a UNIX emulation like CYGWIN you can opt to run the general If you have a UNIX emulation like CYGWIN you can opt to run the general
@@ -130,18 +160,27 @@ Steps to Release
Here are the things that need to be done (in more or less this order) Here are the things that need to be done (in more or less this order)
before making an official release: before making an official release:
* Update the configure.in file with the new release number. * Update the configure.ac file with the new release number.
* Update the NEWS file with the release number and date. * Update the NEWS file with the release number and date.
* In Savannah modify the "Value", "Rank", and "Description" values for the
current "SCM" entry in both "Component Version" and "Fix Release" fields
to refer to the new release, for "Bugs" and "Patches".
* Update the Savannah bug list URL in the NEWS file to use the correct
"Fixed Release" ID number.
* In Savannah create a new entry for the "Component Version" and "Fix
Release" fields:
- Value: SCM
- Rank: 20
- Descr: Fixed in Git; will be available in the next version of Make.
* Run "make distcheck" to be sure it all works.
* git tag -u <GPGID> <VER> where GPGID is my GPG key fingerprint,
and VER is the release version.
* Push everything:
git push --tags origin master
* Create the new release in the Savannah "Bugs" Administration for * Create the new release in the Savannah "Bugs" Administration for
both the "Component Version" and "Fixed Release" fields. both the "Component Version" and "Fixed Release" fields.
* Create the new release in the Savannah "Patches" Administration for * Create the new release in the Savannah "Patches" Administration for
the "Fixed Release" field. the "Fixed Release" field.
* Update the Savannah bug list URL in the NEWS file to use the correct
"Fixed Release" ID number.
* Run "make distcheck" to be sure it all works.
* Commit everything.
* cvs tag <RTAG> where RTAG is constructed by replacing each "." in
the version with "-" and prefixing it with "make-".
Publishing a Package Publishing a Package
@@ -151,12 +190,11 @@ In order to publish a package on the FSF FTP site, either the release
site ftp://ftp.gnu.org, or the prerelease site ftp://alpha.gnu.org, you site ftp://ftp.gnu.org, or the prerelease site ftp://alpha.gnu.org, you
first need to have my GPG private key and my passphrase to unlock it. first need to have my GPG private key and my passphrase to unlock it.
And, you can't have them! So there! But, just so I remember here's And, you can't have them! So there! But, just so I remember here's
what you do: what to do:
Make sure the "Steps to Release" are complete and committed and tagged. Make sure the "Steps to Release" are complete and committed and tagged.
cvs -d :pserver:anonymous@cvs.savannah.gnu.org:/sources/make \ git clone git://git.savannah.gnu.org/make.git make-release
export -r<RTAG> -d make-release make
cd make-release cd make-release
@@ -166,14 +204,17 @@ what you do:
-OR- -OR-
make upload-ftp # for ftp.gnu.org (official releases) make upload-ftp # for ftp.gnu.org (official releases)
It will ask for the GPG passphrase _THREE_ times. Sigh. Depending on your distribution (whether GnuPG is integrated with your keyring
etc.) it will either pop up a window asking for your GPG key passphrase one
time, or else it will use the CLI to ask for the GPG passphrase _THREE_ times.
Sigh.
For both final releases and pre-releases, send an email with the URL of For both final releases and pre-releases, send an email with the URL of
the package to the GNU translation robot to allow the translators to the package to the GNU translation robot to allow the translators to
work on it: work on it:
<translation@iro.umontreal.ca> <coordinator@translationproject.org>
Where to Announce Where to Announce
@@ -185,8 +226,9 @@ Create the announcement in a text file, then sign it with GPG.
Upload to gnu.org, then login and send from my account there. Upload to gnu.org, then login and send from my account there.
Email to: make-alpha@gnu.org, bug-make@gnu.org, help-make@gnu.org, make-w32@gnu.org. To: bug-make@gnu.org, help-make@gnu.org, make-w32@gnu.org
Email to: info-gnu@gnu.org CC: info-gnu@gnu.org
BCC: make-alpha@gnu.org
Add a news item to the Savannah project site. Add a news item to the Savannah project site.
@@ -198,7 +240,7 @@ Appendix A - For The Brave
For those of you who trust me implicitly, or are just brave (or For those of you who trust me implicitly, or are just brave (or
foolhardy), here is a canned sequence of commands to build a GNU make foolhardy), here is a canned sequence of commands to build a GNU make
distribution package from a virgin CVS source checkout (assuming all the distribution package from a virgin Git source checkout (assuming all the
prerequisites are available of course). prerequisites are available of course).
This list is eminently suitable for a quick swipe o' the mouse and a This list is eminently suitable for a quick swipe o' the mouse and a

View File

@@ -82,19 +82,19 @@ If you need help using GNU make, try these forums:
news:gnu.utils.bug news:gnu.utils.bug
CVS Access Git Access
---------- ----------
The GNU make source repository is available via anonymous CVS from the The GNU make source repository is available via Git from the
GNU Subversions CVS server; look here for details: GNU Savannah Git server; look here for details:
http://savannah.gnu.org/cvs/?group=make http://savannah.gnu.org/git/?group=make
Please note: you won't be able to build GNU make from CVS without Please note: you won't be able to build GNU make from Git without
installing appropriate maintainer's tools, such as GNU m4, automake, installing appropriate maintainer's tools, such as GNU m4, automake,
autoconf, Perl, GNU make, and GCC. See the README.cvs file for hints on autoconf, Perl, GNU make, and GCC. See the README.git file for hints on
how to build GNU make once these tools are available. We make no how to build GNU make once these tools are available. We make no
guarantees about the contents or quality of the latest code in the CVS guarantees about the contents or quality of the latest code in the Git
repository: it is not unheard of for code that is known to be broken to repository: it is not unheard of for code that is known to be broken to
be checked in. Use at your own risk. be checked in. Use at your own risk.
@@ -142,7 +142,7 @@ Ports
- See README.customs for details on integrating GNU make with the - See README.customs for details on integrating GNU make with the
Customs distributed build environment from the Pmake distribution. Customs distributed build environment from the Pmake distribution.
- See readme.vms for details about GNU Make on OpenVMS. - See README.VMS for details about GNU Make on OpenVMS.
- See README.Amiga for details about GNU Make on AmigaDOS. - See README.Amiga for details about GNU Make on AmigaDOS.
@@ -162,7 +162,7 @@ at the right README!
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile, # NOTE: If you have no 'make' program at all to process this makefile,
# run 'build.sh' instead. # run 'build.sh' instead.
# #
# Copyright (C) 1995-2012 Free Software Foundation, Inc. # Copyright (C) 1995-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -128,7 +128,8 @@ CTAGS = ctags -w
objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \
rule.o implicit.o default.o variable.o expand.o function.o \ rule.o implicit.o default.o variable.o expand.o function.o \
vpath.o version.o ar.o arscan.o signame.o strcache.o hash.o \ vpath.o version.o ar.o arscan.o signame.o strcache.o hash.o \
remote-$(REMOTE).o $(GLOB) $(GETOPT) $(ALLOCA) $(extras) $(guile) output.o remote-$(REMOTE).o $(GLOB) $(GETOPT) $(ALLOCA) \
$(extras) $(guile)
srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \ srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \
$(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \ $(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \
@@ -140,7 +141,8 @@ srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \
$(srcdir)ar.c $(srcdir)arscan.c $(srcdir)strcache.c \ $(srcdir)ar.c $(srcdir)arscan.c $(srcdir)strcache.c \
$(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \
$(srcdir)commands.h $(srcdir)dep.h $(srcdir)file.h \ $(srcdir)commands.h $(srcdir)dep.h $(srcdir)file.h \
$(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ $(srcdir)job.h $(srcdir)makeint.h $(srcdir)rule.h \
$(srcdir)output.c $(srcdir)output.h \
$(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in

View File

@@ -6,7 +6,7 @@ This list comes both from the authors and from users of GNU make.
They are listed in no particular order! They are listed in no particular order!
Also, I don't gaurantee that all of them will be ultimately deemed "good Also, I don't guarantee that all of them will be ultimately deemed "good
ideas" and implemented. These are just the ones that, at first blush, ideas" and implemented. These are just the ones that, at first blush,
seem to have some merit (and that I can remember). seem to have some merit (and that I can remember).
@@ -99,33 +99,9 @@ The Rest of the List
you just can't figure it out. The way variables are expanded now you just can't figure it out. The way variables are expanded now
means this isn't 100% trivial, but it probably won't be hard. means this isn't 100% trivial, but it probably won't be hard.
8) Integration of Guile as an embedded scripting language. This means:
allowing Guile functions to be declared in makefiles somehow, then
providing a syntax for invoking them. At least one formulation of
that would have the function resolve to a string which would be
substituted in the makefile, kind of like $(shell ...) does now, but
using the embedded interpreter so there's no process forked of
course. Obviously this is an optional add-on feature.
It could be more advanced than that, even, who knows? Maybe make
could provide Guile functions that allow Guile scripts more direct
access to internal make structures, somehow. This kind of thing
needs a lot of thought.
Also there's always the flip side: in some very fundamental ways
make isn't the best choice right now for a complex build tool. It's
great for simple-to-medium tasks, but there are already other tools
available for the really tough situations. Ask yourself,
realistically, how much work is worthwhile to add to make, given the
fundamentals you can't really overcome without significantly
affecting backward compatibility--and then why not use another tool
in the first place?
Something to think about.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1997-2012 Free Software Foundation, Inc. Copyright (C) 1997-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,7 +1,7 @@
dnl acinclude.m4 -- Extra macros needed for GNU make. dnl acinclude.m4 -- Extra macros needed for GNU make.
dnl dnl
dnl Automake will incorporate this into its generated aclocal.m4. dnl Automake will incorporate this into its generated aclocal.m4.
dnl Copyright (C) 1998-2012 Free Software Foundation, Inc. dnl Copyright (C) 1998-2013 Free Software Foundation, Inc.
dnl This file is part of GNU Make. dnl This file is part of GNU Make.
dnl dnl
dnl GNU Make is free software; you can redistribute it and/or modify it under dnl GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,5 +1,5 @@
/* Running commands on Amiga /* Running commands on Amiga
Copyright (C) 1995-2012 Free Software Foundation, Inc. Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "variable.h" #include "variable.h"
#include "amiga.h" #include "amiga.h"
#include <assert.h> #include <assert.h>
@@ -77,7 +77,7 @@ MyExecute (char **argv)
FreeMem (buffer, len); FreeMem (buffer, len);
if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) if (SetSignal (0L,0L) & SIGBREAKF_CTRL_C)
status = 20; status = 20;
/* Warnings don't count */ /* Warnings don't count */

View File

@@ -1,5 +1,5 @@
/* Definitions for amiga specific things /* Definitions for amiga specific things
Copyright (C) 1995-2012 Free Software Foundation, Inc. Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

6
ar.c
View File

@@ -1,5 +1,5 @@
/* Interface to 'ar' archives for GNU Make. /* Interface to 'ar' archives for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
@@ -15,7 +15,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#ifndef NO_ARCHIVES #ifndef NO_ARCHIVES
@@ -61,7 +61,7 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
*arname_p = xstrdup (name); *arname_p = xstrdup (name);
p = strchr (*arname_p, '('); p = strchr (*arname_p, '(');
*(p++) = '\0'; *(p++) = '\0';
p[strlen(p) - 1] = '\0'; p[strlen (p) - 1] = '\0';
*memname_p = p; *memname_p = p;
} }

View File

@@ -1,5 +1,5 @@
/* Library function for scanning an archive file. /* Library function for scanning an archive file.
Copyright (C) 1987-2012 Free Software Foundation, Inc. Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
#include <fcntl.h> #include <fcntl.h>
@@ -328,12 +328,10 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
{ {
#ifdef AIAMAG #ifdef AIAMAG
FL_HDR fl_header; FL_HDR fl_header;
#ifdef AIAMAGBIG # ifdef AIAMAGBIG
int big_archive = 0; int big_archive = 0;
FL_HDR_BIG fl_header_big; FL_HDR_BIG fl_header_big;
#endif # endif
#else
int long_name = 0;
#endif #endif
char *namemap = 0; char *namemap = 0;
int desc = open (archive, O_RDONLY, 0); int desc = open (archive, O_RDONLY, 0);
@@ -397,7 +395,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else #else
unsigned short int buf; unsigned short int buf;
#endif #endif
register int nread = read(desc, &buf, sizeof (buf)); register int nread = read (desc, &buf, sizeof (buf));
if (nread != sizeof (buf) || buf != ARMAG) if (nread != sizeof (buf) || buf != ARMAG)
{ {
(void) close (desc); (void) close (desc);
@@ -461,6 +459,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
char namebuf[sizeof member_header.ar_name + 1]; char namebuf[sizeof member_header.ar_name + 1];
char *name; char *name;
int is_namemap; /* Nonzero if this entry maps long names. */ int is_namemap; /* Nonzero if this entry maps long names. */
int long_name = 0;
#endif #endif
long int eltsize; long int eltsize;
int eltmode; int eltmode;
@@ -746,9 +745,9 @@ ar_name_equal (const char *name, const char *mem, int truncated)
#else #else
struct ar_hdr hdr; struct ar_hdr hdr;
#if !defined (__hpux) && !defined (cray) #if !defined (__hpux) && !defined (cray)
return strneq (name, mem, sizeof(hdr.ar_name) - 1); return strneq (name, mem, sizeof (hdr.ar_name) - 1);
#else #else
return strneq (name, mem, sizeof(hdr.ar_name) - 2); return strneq (name, mem, sizeof (hdr.ar_name) - 2);
#endif /* !__hpux && !cray */ #endif /* !__hpux && !cray */
#endif /* !AIAMAG */ #endif /* !AIAMAG */
} }
@@ -815,7 +814,7 @@ ar_member_touch (const char *arname, const char *memname)
ar_hdr.ar_date[ui] = ' '; ar_hdr.ar_date[ui] = ' ';
sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime); sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime);
#ifdef AIAMAG #ifdef AIAMAG
ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' '; ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
#endif #endif
#else #else
ar_hdr.ar_date = statbuf.st_mtime; ar_hdr.ar_date = statbuf.st_mtime;

View File

@@ -2,7 +2,7 @@
# Shell script to build GNU Make in the absence of any 'make' program. # Shell script to build GNU Make in the absence of any 'make' program.
# @configure_input@ # @configure_input@
# Copyright (C) 1993-2012 Free Software Foundation, Inc. # Copyright (C) 1993-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,5 +1,5 @@
@echo off @echo off
rem Copyright (C) 1996-2012 Free Software Foundation, Inc. rem Copyright (C) 1996-2013 Free Software Foundation, Inc.
rem This file is part of GNU Make. rem This file is part of GNU Make.
rem rem
rem GNU Make is free software; you can redistribute it and/or modify it under rem GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,26 +15,53 @@ rem
rem You should have received a copy of the GNU General Public License along rem You should have received a copy of the GNU General Public License along
rem with this program. If not, see <http://www.gnu.org/licenses/>. rem with this program. If not, see <http://www.gnu.org/licenses/>.
if exist config.h.W32 GoTo NotCVS if "%1" == "-h" GoTo Usage
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.in > config.h.W32.sed if "%1" == "--help" GoTo Usage
if not exist config.h.W32.template GoTo NotSCM
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > config.h.W32.sed
echo s,%%PACKAGE%%,make,g >> config.h.W32.sed echo s,%%PACKAGE%%,make,g >> config.h.W32.sed
sed -f config.h.W32.sed config.h.W32.template > config.h.W32 sed -f config.h.W32.sed config.h.W32.template > config.h.W32
:NotCVS echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
if not exist config.h copy config.h.W32 config.h sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\/" gmk-default.scm >> gmk-default.h
echo ^";>> gmk-default.h
:NotSCM
copy config.h.W32 config.h
rem Guile configuration rem Guile configuration
set GUILECFLAGS= set GUILECFLAGS=
set GUILELIBS= set GUILELIBS=
set GUILESRC= set GUILESRC=
set NOGUILE=
set OPT=-O2
set COMPILER=
set PKGMSC= set PKGMSC=
:ParseSW
if "%1" == "--debug" GoTo SetOpt
if "%1" == "--without-guile" GoTo NoGuile if "%1" == "--without-guile" GoTo NoGuile
if "%2" == "--without-guile" GoTo NoGuile if "%1" == "gcc" GoTo SetCC
if "%1" == "" GoTo ChkGuile
:SetOpt
set OPT=-O0
shift
GoTo ParseSW
:NoGuile
set NOGUILE=Y
echo "Building without Guile"
shift
GoTo ParseSW
:SetCC
set COMPILER=gcc
echo "Building with GCC"
shift
GoTo ParseSW
rem Build with Guile is supported only on NT and later versions rem Build with Guile is supported only on NT and later versions
:ChkGuile
if "%NOGUILE%" == "Y" GoTo GuileDone
if not "%OS%" == "Windows_NT" GoTo NoGuile if not "%OS%" == "Windows_NT" GoTo NoGuile
pkg-config --help > guile.tmp 2> NUL pkg-config --help > guile.tmp 2> NUL
if ERRORLEVEL 1 GoTo NoPkgCfg if ERRORLEVEL 1 GoTo NoPkgCfg
echo "Checking for Guile 2.0" echo "Checking for Guile 2.0"
if not "%1" == "gcc" set PKGMSC=--msvc-syntax if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
pkg-config --cflags --short-errors "guile-2.0" > guile.tmp pkg-config --cflags --short-errors "guile-2.0" > guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > guile.tmp pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > guile.tmp
@@ -47,24 +74,25 @@ pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
if not "%GUILECFLAGS%" == "" GoTo GuileDone if not "%GUILECFLAGS%" == "" GoTo GuileDone
echo "No Guile found, building without Guile" echo "No Guile found, building without Guile"
GoTo NoGuile GoTo GuileDone
:NoPkgCfg :NoPkgCfg
echo "pkg-config not found, building without Guile" echo "pkg-config not found, building without Guile"
:NoGuile
:GuileDone :GuileDone
if not "%GUILECFLAGS%" == "" echo "Guile found, building with Guile" if not "%GUILECFLAGS%" == "" echo "Guile found, building with Guile"
if not "%GUILECFLAGS%" == "" set GUILESRC=guile.c if not "%GUILECFLAGS%" == "" set GUILESRC=guile.c
if not "%GUILECFLAGS%" == "" set GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE if not "%GUILECFLAGS%" == "" set GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE
if "%1" == "--without-guile" shift if "%COMPILER%" == "gcc" if "%OPT%" == "-O0" echo "Building without compiler optimizations"
cd w32\subproc cd w32\subproc
echo.
echo "Creating the subproc library" echo "Creating the subproc library"
%ComSpec% /c build.bat %1 %ComSpec% /c build.bat
cd ..\.. cd ..\..
if exist link.dbg del link.dbg if exist link.dbg del link.dbg
if exist link.rel del link.rel if exist link.rel del link.rel
echo "Creating GNU Make for Windows 9X/NT/2K/XP" echo.
if "%1" == "gcc" GoTo GCCBuild echo "Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8"
if "%COMPILER%" == "gcc" GoTo GCCBuild
set make=gnumake set make=gnumake
echo on echo on
if not exist .\WinDebug\nul mkdir .\WinDebug if not exist .\WinDebug\nul mkdir .\WinDebug
@@ -94,6 +122,8 @@ cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D
echo WinDebug\getopt1.obj >>link.dbg echo WinDebug\getopt1.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c job.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c job.c
echo WinDebug\job.obj >>link.dbg echo WinDebug\job.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c output.c
echo WinDebug\output.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c
echo WinDebug\read.obj >>link.dbg echo WinDebug\read.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c
@@ -118,8 +148,14 @@ cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D
echo WinDebug\vpath.obj >>link.dbg echo WinDebug\vpath.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c
echo WinDebug\implicit.obj >>link.dbg echo WinDebug\implicit.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c loadapi.c
echo WinDebug\loadapi.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c load.c
echo WinDebug\load.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c
echo WinDebug\dirent.obj >>link.dbg echo WinDebug\dirent.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\posixfcn.c
echo WinDebug\posixfcn.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c
echo WinDebug\glob.obj >>link.dbg echo WinDebug\glob.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c
@@ -132,7 +168,7 @@ echo WinDebug\guile.obj >>link.dbg
:LinkDbg :LinkDbg
echo off echo off
echo "Linking WinDebug/%make%.exe" echo "Linking WinDebug/%make%.exe"
rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/hash.obj .\WinDebug/strcache.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/output.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/hash.obj .\WinDebug/strcache.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib >>link.dbg echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib >>link.dbg
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe @link.dbg link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /OUT:.\WinDebug/%make%.exe @link.dbg
if not exist .\WinDebug/%make%.exe echo "WinDebug build failed" if not exist .\WinDebug/%make%.exe echo "WinDebug build failed"
@@ -165,6 +201,8 @@ cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WIND
echo WinRel\getopt1.obj >>link.rel echo WinRel\getopt1.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c
echo WinRel\job.obj >>link.rel echo WinRel\job.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c output.c
echo WinRel\output.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c
echo WinRel\read.obj >>link.rel echo WinRel\read.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c
@@ -189,8 +227,14 @@ cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WIND
echo WinRel\vpath.obj >>link.rel echo WinRel\vpath.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c
echo WinRel\implicit.obj >>link.rel echo WinRel\implicit.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c loadapi.c
echo WinRel\loadapi.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c load.c
echo WinRel\load.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c
echo WinRel\dirent.obj >>link.rel echo WinRel\dirent.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\posixfcn.c
echo WinRel\posixfcn.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c
echo WinRel\glob.obj >>link.rel echo WinRel\glob.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c cl.exe /nologo /MT /W4 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c
@@ -203,7 +247,7 @@ echo WinRel\guile.obj >>link.rel
:LinkRel :LinkRel
echo off echo off
echo "Linking WinRel/%make%.exe" echo "Linking WinRel/%make%.exe"
rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/hash.obj .\WinRel/strcache.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj rem link.exe %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/output.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/hash.obj .\WinRel/strcache.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj
echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib >>link.rel echo %GUILELIBS% kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib >>link.rel
link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe @link.rel link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /OUT:.\WinRel/%make%.exe @link.rel
if not exist .\WinRel/%make%.exe echo "WinRel build failed" if not exist .\WinRel/%make%.exe echo "WinRel build failed"
@@ -212,43 +256,58 @@ set make=
GoTo BuildEnd GoTo BuildEnd
:GCCBuild :GCCBuild
echo on echo on
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c variable.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c rule.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remote-stub.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c commands.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c file.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getloadavg.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c default.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c signame.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c expand.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c dir.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %GUILECFLAGS% -c main.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %GUILECFLAGS% -c main.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt1.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c job.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c output.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c read.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c version.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c getopt.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c arscan.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c remake.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c strcache.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c hash.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c strcache.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c misc.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ar.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c function.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c vpath.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c implicit.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c loadapi.c
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c load.c
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/glob.c -o glob.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./glob/fnmatch.c -o fnmatch.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/pathstuff.c -o pathstuff.o
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c ./w32/compat/posixfcn.c -o posixfcn.o
@echo off @echo off
set GUILEOBJ= set GUILEOBJ=
if "%GUILESRC%" == "" GoTo LinkGCC if "%GUILESRC%" == "" GoTo LinkGCC
set GUILEOBJ=guile.o set GUILEOBJ=guile.o
echo on echo on
gcc -mthreads -Wall -gdwarf-2 -g3 -O2 %GUILECFLAGS% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c guile.c gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% %GUILECFLAGS% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c guile.c
:LinkGCC :LinkGCC
@echo off
Rem The version NN of libgnumake-NN.dll.a should be bumped whenever
Rem the API changes in binary-incompatible manner.
@echo on @echo on
gcc -mthreads -gdwarf-2 -g3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o %GUILEOBJ% job.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o strcache.o ar.o function.o vpath.o implicit.o glob.o fnmatch.o pathstuff.o w32_misc.o sub_proc.o w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 gcc -mthreads -gdwarf-2 -g3 -o gnumake.exe variable.o rule.o remote-stub.o commands.o file.o getloadavg.o default.o signame.o expand.o dir.o main.o getopt1.o %GUILEOBJ% job.o output.o read.o version.o getopt.o arscan.o remake.o misc.o hash.o strcache.o ar.o function.o vpath.o implicit.o loadapi.o load.o glob.o fnmatch.o pathstuff.o posixfcn.o w32_misc.o sub_proc.o w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=libgnumake-1.dll.a
@GoTo BuildEnd
:Usage
echo Usage: %0 [options] [gcc]
echo Options:
echo. --debug For GCC only, make a debug build
echo. (MSVC build always makes both debug and release)
echo. --without-guile Do not compile Guile support even if found
echo. --help Display these instructions and exit
:BuildEnd :BuildEnd
@echo off @echo off
set GUILEOBJ= set GUILEOBJ=
@@ -256,4 +315,7 @@ set GUILESRC=
set GUILELIBS= set GUILELIBS=
set GUILECFLAGS= set GUILECFLAGS=
set PKGMSC= set PKGMSC=
set OPT=
set COMPILER=
set NOGUILE=
echo on echo on

View File

@@ -1,5 +1,5 @@
/* Command processing for GNU Make. /* Command processing for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,9 +14,11 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include <dlfcn.h>
#include "dep.h"
#include "makeint.h"
#include "filedef.h" #include "filedef.h"
#include "dep.h"
#include "variable.h" #include "variable.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
@@ -457,7 +459,7 @@ execute_file_commands (struct file *file)
{ {
/* If there are no commands, assume everything worked. */ /* If there are no commands, assume everything worked. */
set_command_state (file, cs_running); set_command_state (file, cs_running);
file->update_status = 0; file->update_status = us_success;
notice_finished_file (file); notice_finished_file (file);
return; return;
} }
@@ -468,6 +470,11 @@ execute_file_commands (struct file *file)
set_file_variables (file); set_file_variables (file);
/* If this is a loaded dynamic object, unload it before remaking.
Some systems don't support overwriting a loaded object. */
if (file->loaded)
unload_file (file->name);
/* Start the commands running. */ /* Start the commands running. */
new_job (file); new_job (file);
} }

View File

@@ -1,5 +1,5 @@
/* Definition of data structures describing shell commands for GNU Make. /* Definition of data structures describing shell commands for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -19,7 +19,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
struct commands struct commands
{ {
struct floc fileinfo; /* Where commands were defined. */ gmk_floc fileinfo; /* Where commands were defined. */
char *commands; /* Commands text. */ char *commands; /* Commands text. */
char **command_lines; /* Commands chopped up into lines. */ char **command_lines; /* Commands chopped up into lines. */
char *lines_flags; /* One set of flag bits for each line. */ char *lines_flags; /* One set of flag bits for each line. */

View File

@@ -1,5 +1,5 @@
/* config.h -- hand-massaged for Amiga -*-C-*- /* config.h -- hand-massaged for Amiga -*-C-*-
Copyright (C) 1995-2012 Free Software Foundation, Inc. Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -53,9 +53,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ /* Define if you have <alloca.h> and it should be used (not on Ultrix). */
/* #undef HAVE_ALLOCA_H */ /* #undef HAVE_ALLOCA_H */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define if your system has a working fnmatch function. */ /* Define if your system has a working fnmatch function. */
/* #undef HAVE_FNMATCH */ /* #undef HAVE_FNMATCH */
@@ -112,12 +109,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if utime(file, NULL) sets file's timestamp to the present. */ /* Define if utime(file, NULL) sets file's timestamp to the present. */
/* #undef HAVE_UTIME_NULL */ /* #undef HAVE_UTIME_NULL */
/* Define if you have <vfork.h>. */
/* #undef HAVE_VFORK_H */
/* Define if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define if you have the wait3 system call. */ /* Define if you have the wait3 system call. */
/* #undef HAVE_WAIT3 */ /* #undef HAVE_WAIT3 */
@@ -163,9 +154,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if the 'S_IS*' macros in <sys/stat.h> do not work properly. */ /* Define if the 'S_IS*' macros in <sys/stat.h> do not work properly. */
/* #undef STAT_MACROS_BROKEN */ /* #undef STAT_MACROS_BROKEN */
/* Define if your compiler conforms to the ANSI C standard. */
#define HAVE_ANSI_COMPILER 1
/* Define if you have the ANSI C header files. */ /* Define if you have the ANSI C header files. */
#define STDC_HEADERS #define STDC_HEADERS
@@ -185,9 +173,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
instead of <sys/cpustats.h>. */ instead of <sys/cpustats.h>. */
/* #undef UMAX4_3 */ /* #undef UMAX4_3 */
/* Define vfork as fork if vfork does not work. */
/* #undef vfork */
/* Name of this package (needed by automake) */ /* Name of this package (needed by automake) */
#define PACKAGE "%PACKAGE%" #define PACKAGE "%PACKAGE%"
@@ -303,9 +288,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the <ndir.h> header file. */ /* Define if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */ /* #undef HAVE_NDIR_H */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define if you have the <stdlib.h> header file. */ /* Define if you have the <stdlib.h> header file. */
/* #undef HAVE_STDLIB_H */ /* #undef HAVE_STDLIB_H */
@@ -339,6 +321,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the sun library (-lsun). */ /* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */ /* #undef HAVE_LIBSUN */
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Define for Case Insensitve behavior */ /* Define for Case Insensitve behavior */
#define HAVE_CASE_INSENSITIVE_FS #define HAVE_CASE_INSENSITIVE_FS

View File

@@ -1,6 +1,6 @@
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*- /* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*-
Copyright (C) 1996-2012 Free Software Foundation, Inc. Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
/* config.h. Generated automatically by configure. */ /* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.in by autoheader. */ /* config.h.in. Generated automatically from configure.ac by autoheader. */
/* Define to 1 if on AIX 3. /* Define to 1 if on AIX 3.
System headers sometimes define this. System headers sometimes define this.
@@ -75,9 +75,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */ /* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
/* #undef HAVE_ALLOCA_H */ /* #undef HAVE_ALLOCA_H */
/* Define to 1 if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the fdopen function. */ /* Define to 1 if you have the fdopen function. */
#define HAVE_FDOPEN 1 #define HAVE_FDOPEN 1
@@ -141,12 +138,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if utime(file, NULL) sets file's timestamp to the present. */ /* Define to 1 if utime(file, NULL) sets file's timestamp to the present. */
/* #undef HAVE_UTIME_NULL */ /* #undef HAVE_UTIME_NULL */
/* Define to 1 if you have <vfork.h>. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define to 1 if you have the wait3 system call. */ /* Define to 1 if you have the wait3 system call. */
/* #undef HAVE_WAIT3 */ /* #undef HAVE_WAIT3 */
@@ -216,9 +207,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
instead of <sys/cpustats.h>. */ instead of <sys/cpustats.h>. */
/* #undef UMAX4_3 */ /* #undef UMAX4_3 */
/* Define vfork as fork if vfork does not work. */
/* #undef vfork */
/* Name of this package (needed by automake) */ /* Name of this package (needed by automake) */
#define PACKAGE "%PACKAGE%" #define PACKAGE "%PACKAGE%"
@@ -336,12 +324,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the <ndir.h> header file. */ /* Define to 1 if you have the <ndir.h> header file. */
/* #undef HAVE_NDIR_H */ /* #undef HAVE_NDIR_H */
/* Define to 1 if your compiler conforms to the ANSI C standard. */
#define HAVE_ANSI_COMPILER 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdlib.h> header file. */ /* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1 #define HAVE_STDLIB_H 1
@@ -424,10 +406,13 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if using alloca.c. */ /* Define if using alloca.c. */
/* #undef C_ALLOCA */ /* #undef C_ALLOCA */
/* maybe this should be placed into make.h */ /* maybe this should be placed into makeint.h */
#if defined(__VAX) && defined(__DECC) #if defined(__VAX) && defined(__DECC)
#define alloca(n) __ALLOCA(n) #define alloca(n) __ALLOCA(n)
#endif #endif
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Build host information. */ /* Build host information. */
#define MAKE_HOST "VMS" #define MAKE_HOST "VMS"

View File

@@ -1,6 +1,6 @@
/* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*- /* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*-
Copyright (C) 1996-2012 Free Software Foundation, Inc. Copyright (C) 1996-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -62,9 +62,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
*/ */
/* #undef HAVE_ALLOCA_H */ /* #undef HAVE_ALLOCA_H */
/* Define to 1 if your compiler conforms to the ANSI C standard. */
#define HAVE_ANSI_COMPILER 1
/* Define to 1 if you have the 'atexit' function. */ /* Define to 1 if you have the 'atexit' function. */
#define HAVE_ATEXIT 1 #define HAVE_ATEXIT 1
@@ -109,9 +106,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# define HAVE_DIRECT_H 1 # define HAVE_DIRECT_H 1
#endif #endif
/* Define to 1 if you don't have 'vprintf' but do have '_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Use platform specific coding */ /* Use platform specific coding */
#define HAVE_DOS_PATHS 1 #define HAVE_DOS_PATHS 1
@@ -129,9 +123,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'fileno' function. */ /* Define to 1 if you have the 'fileno' function. */
#define HAVE_FILENO 1 #define HAVE_FILENO 1
/* Define to 1 if you have the 'fork' function. */
/* #undef HAVE_FORK */
/* Define to 1 if you have the 'getcwd' function. */ /* Define to 1 if you have the 'getcwd' function. */
#define HAVE_GETCWD 1 #define HAVE_GETCWD 1
@@ -247,9 +238,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the 'socket' function. */ /* Define to 1 if you have the 'socket' function. */
/* #undef HAVE_SOCKET */ /* #undef HAVE_SOCKET */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#ifdef __MINGW32__ #ifdef __MINGW32__
#define HAVE_STDINT_H 1 #define HAVE_STDINT_H 1
@@ -348,37 +336,21 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define HAVE_UNISTD_H 1 #define HAVE_UNISTD_H 1
#endif #endif
/* Define to 1 if you have the <varargs.h> header file. */
/* #undef HAVE_VARARGS_H */
/* Define to 1 if you have the 'vfork' function. */
/* #undef HAVE_VFORK */
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the 'vprintf' function. */
#define HAVE_VPRINTF 1
/* Define to 1 if you have the 'wait3' function. */ /* Define to 1 if you have the 'wait3' function. */
/* #undef HAVE_WAIT3 */ /* #undef HAVE_WAIT3 */
/* Define to 1 if you have the 'waitpid' function. */ /* Define to 1 if you have the 'waitpid' function. */
/* #undef HAVE_WAITPID */ /* #undef HAVE_WAITPID */
/* Define to 1 if 'fork' works. */
/* #undef HAVE_WORKING_FORK */
/* Define to 1 if 'vfork' works. */
/* #undef HAVE_WORKING_VFORK */
/* Build host information. */ /* Build host information. */
#define MAKE_HOST "Windows32" #define MAKE_HOST "Windows32"
/* Define to 1 to enable job server support in GNU make. */ /* Define to 1 to enable job server support in GNU make. */
#define MAKE_JOBSERVER 1 #define MAKE_JOBSERVER 1
/* Define to 1 to enable 'load' support in GNU make. */
#define MAKE_LOAD 1
/* Define to 1 to enable symbolic link timestamp checking. */ /* Define to 1 to enable symbolic link timestamp checking. */
/* #undef MAKE_SYMLINKS */ /* #undef MAKE_SYMLINKS */
@@ -511,9 +483,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define uintmax_t unsigned long #define uintmax_t unsigned long
#endif #endif
/* Define as 'fork' if 'vfork' does not work. */
/*#define vfork fork*/
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ /* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
/* #undef HAVE_SYS_WAIT_H */ /* #undef HAVE_SYS_WAIT_H */

View File

@@ -1,11 +1,11 @@
*.m4
config.*
mkinstalldirs
texinfo.tex
mdate-sh
compile compile
config.guess
config.rpath
config.sub
depcomp depcomp
install-sh install-sh
mdate-sh
missing missing
texinfo.tex
Makefile Makefile.in *.m4
!dospaths.m4

View File

@@ -33,7 +33,7 @@
* Makefile.am: New file. * Makefile.am: New file.
Copyright (C) 2002-2012 Free Software Foundation, Inc. Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough # -*-Makefile-*-, or close enough
# Copyright (C) 2002-2012 Free Software Foundation, Inc. # Copyright (C) 2002-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -15,34 +15,4 @@
# You should have received a copy of the GNU General Public License along with # You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>. # this program. If not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST = \ # Autoconf / automake know how to handle this directory.
codeset.m4 \
dospaths.m4 \
gettext.m4 \
glibc21.m4 \
iconv.m4 \
intdiv0.m4 \
intmax.m4 \
inttypes-pri.m4 \
inttypes.m4 \
inttypes_h.m4 \
isc-posix.m4 \
isc-posix.m4 \
lcmessage.m4 \
lib-ld.m4 \
lib-link.m4 \
lib-prefix.m4 \
longdouble.m4 \
longlong.m4 \
nls.m4 \
po.m4 \
printf-posix.m4 \
progtest.m4 \
signed.m4 \
size_max.m4 \
stdint_h.m4 \
uintmax_t.m4 \
ulonglong.m4 \
wchar_t.m4 \
wint_t.m4 \
xsize.m4

View File

@@ -1,7 +1,7 @@
# Test if the system uses DOS-style pathnames (drive specs and backslashes) # Test if the system uses DOS-style pathnames (drive specs and backslashes)
# By Paul Smith <psmith@gnu.org>. Based on dos.m4 by Jim Meyering. # By Paul Smith <psmith@gnu.org>. Based on dos.m4 by Jim Meyering.
# #
# Copyright (C) 1993-2012 Free Software Foundation, Inc. # Copyright (C) 1993-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,6 +1,6 @@
/* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*- /* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*-
Copyright (C) 1994-2012 Free Software Foundation, Inc. Copyright (C) 1994-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -76,16 +76,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the select function. */ /* Define to 1 if you have the select function. */
#define HAVE_SELECT 1 #define HAVE_SELECT 1
/* Define to 1 if your compiler conforms to the ANSI C standard. */
#define HAVE_ANSI_COMPILER 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the vprintf library function. */
#undef HAVE_VPRINTF
#define HAVE_VPRINTF 1
/* Define to 1 if you have the stricmp function. */ /* Define to 1 if you have the stricmp function. */
#define HAVE_STRICMP 1 #define HAVE_STRICMP 1
@@ -110,8 +100,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "%VERSION%" #define PACKAGE_VERSION "%VERSION%"
/* Define to 1 if the C compiler supports function prototypes. */ /* Output sync sypport */
#define PROTOTYPES 1 #define NO_OUTPUT_SYNC
/* Version number of package */ /* Version number of package */
#define VERSION "%VERSION%" #define VERSION "%VERSION%"

View File

@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
# #
# Copyright (C) 1993-2012 Free Software Foundation, Inc. # Copyright (C) 1993-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -16,10 +16,9 @@
# You should have received a copy of the GNU General Public License along with # You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>. # this program. If not, see <http://www.gnu.org/licenses/>.
AC_INIT([GNU make],[3.82.90],[bug-make@gnu.org]) AC_INIT([GNU make],[4.0],[bug-make@gnu.org])
AC_PREREQ([2.59]) AC_PREREQ([2.62])
AC_REVISION([$Id$])
# Autoconf setup # Autoconf setup
AC_CONFIG_AUX_DIR([config]) AC_CONFIG_AUX_DIR([config])
@@ -27,7 +26,7 @@ AC_CONFIG_SRCDIR([vpath.c])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
# Automake setup # Automake setup
AM_INIT_AUTOMAKE([1.9]) AM_INIT_AUTOMAKE([1.11.1 silent-rules])
# Checks for programs. # Checks for programs.
AC_PROG_CC AC_PROG_CC
@@ -65,16 +64,6 @@ AC_HEADER_TIME
AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \ AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h]) memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h])
# Set a flag if we have an ANSI C compiler
AS_IF([test "$ac_cv_prog_cc_stdc" != no],
[ AC_DEFINE([HAVE_ANSI_COMPILER], [1],
[Define to 1 if your compiler conforms to the ANSI C standard.])
])
# Determine what kind of variadic function calls we support
AC_CHECK_HEADERS([stdarg.h varargs.h], [break])
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_C_CONST AC_C_CONST
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
@@ -142,7 +131,7 @@ AS_IF([test "$ac_cv_func_gettimeofday" = yes],
]) ])
AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \ AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
dup2 getcwd realpath sigsetmask sigaction \ dup dup2 getcwd realpath sigsetmask sigaction \
getgroups seteuid setegid setlinebuf setreuid setregid \ getgroups seteuid setegid setlinebuf setreuid setregid \
getrlimit setrlimit setvbuf pipe strerror strsignal \ getrlimit setrlimit setvbuf pipe strerror strsignal \
lstat readlink atexit]) lstat readlink atexit])
@@ -164,8 +153,6 @@ AC_CHECK_FUNCS([strcasecmp strncasecmp strcmpi strncmpi stricmp strnicmp])
AC_FUNC_STRCOLL AC_FUNC_STRCOLL
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_FUNC_FORK([])
AC_FUNC_VPRINTF
AC_FUNC_CLOSEDIR_VOID AC_FUNC_CLOSEDIR_VOID
# See if the user wants to add (or not) GNU Guile support # See if the user wants to add (or not) GNU Guile support
@@ -352,13 +339,13 @@ AS_IF([test "$make_cv_load" = yes], [
AC_MSG_CHECKING([If the linker accepts -Wl,--export-dynamic]) AC_MSG_CHECKING([If the linker accepts -Wl,--export-dynamic])
old_LDFLAGS="$LDFLAGS" old_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
AC_LINK_IFELSE([int main(){}], AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
[AC_MSG_RESULT([yes]) [AC_MSG_RESULT([yes])
AC_SUBST([AM_LDFLAGS], [-Wl,--export-dynamic])], AC_SUBST([AM_LDFLAGS], [-Wl,--export-dynamic])],
[AC_MSG_RESULT([no]) [AC_MSG_RESULT([no])
AC_MSG_CHECKING([If the linker accepts -rdynamic]) AC_MSG_CHECKING([If the linker accepts -rdynamic])
LDFLAGS="$old_LDFLAGS -rdynamic" LDFLAGS="$old_LDFLAGS -rdynamic"
AC_LINK_IFELSE([int main(){}], AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
[AC_MSG_RESULT([yes]) [AC_MSG_RESULT([yes])
AC_SUBST([AM_LDFLAGS], [-rdynamic])], AC_SUBST([AM_LDFLAGS], [-rdynamic])],
[AC_MSG_RESULT([no])]) [AC_MSG_RESULT([no])])

View File

@@ -1,5 +1,5 @@
@echo off @echo off
rem Copyright (C) 1994-2012 Free Software Foundation, Inc. rem Copyright (C) 1994-2013 Free Software Foundation, Inc.
rem This file is part of GNU Make. rem This file is part of GNU Make.
rem rem
rem GNU Make is free software; you can redistribute it and/or modify it under rem GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,5 +1,5 @@
/* Debugging macros and interface. /* Debugging macros and interface.
Copyright (C) 1999-2012 Free Software Foundation, Inc. Copyright (C) 1999-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,5 +1,5 @@
/* Data base of default implicit rules for GNU Make. /* Data base of default implicit rules for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,10 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <assert.h>
#include "filedef.h" #include "filedef.h"
#include "variable.h" #include "variable.h"
#include "rule.h" #include "rule.h"
@@ -525,6 +528,8 @@ static const char *default_variables[] =
#endif #endif
#endif /* !VMS */ #endif /* !VMS */
/* Make this assignment to avoid undefined variable warnings. */
"GNUMAKEFLAGS", "",
0, 0 0, 0
}; };
@@ -534,15 +539,19 @@ void
set_default_suffixes (void) set_default_suffixes (void)
{ {
suffix_file = enter_file (strcache_add (".SUFFIXES")); suffix_file = enter_file (strcache_add (".SUFFIXES"));
suffix_file->builtin = 1;
if (no_builtin_rules_flag) if (no_builtin_rules_flag)
define_variable_cname ("SUFFIXES", "", o_default, 0); define_variable_cname ("SUFFIXES", "", o_default, 0);
else else
{ {
struct dep *d;
char *p = default_suffixes; char *p = default_suffixes;
suffix_file->deps = enter_prereqs(PARSE_FILE_SEQ (&p, struct dep, '\0', suffix_file->deps = enter_prereqs (PARSE_SIMPLE_SEQ (&p, struct dep),
NULL, 0),
NULL); NULL);
for (d = suffix_file->deps; d; d = d->next)
d->file->builtin = 1;
define_variable_cname ("SUFFIXES", default_suffixes, o_default, 0); define_variable_cname ("SUFFIXES", default_suffixes, o_default, 0);
} }
} }
@@ -563,15 +572,14 @@ install_default_suffix_rules (void)
for (s = default_suffix_rules; *s != 0; s += 2) for (s = default_suffix_rules; *s != 0; s += 2)
{ {
struct file *f = enter_file (strcache_add (s[0])); struct file *f = enter_file (strcache_add (s[0]));
/* Don't clobber cmds given in a makefile if there were any. */ /* This function should run before any makefile is parsed. */
if (f->cmds == 0) assert (f->cmds == 0);
{
f->cmds = xmalloc (sizeof (struct commands)); f->cmds = xmalloc (sizeof (struct commands));
f->cmds->fileinfo.filenm = 0; f->cmds->fileinfo.filenm = 0;
f->cmds->commands = s[1]; f->cmds->commands = s[1];
f->cmds->command_lines = 0; f->cmds->command_lines = 0;
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT; f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
} f->builtin = 1;
} }
} }
@@ -604,3 +612,12 @@ define_default_variables (void)
for (s = default_variables; *s != 0; s += 2) for (s = default_variables; *s != 0; s += 2)
define_variable (s[0], strlen (s[0]), s[1], o_default, 1); define_variable (s[0], strlen (s[0]), s[1], o_default, 1);
} }
void
undefine_default_variables (void)
{
const char **s;
for (s = default_variables; *s != 0; s += 2)
undefine_variable_global (s[0], strlen (s[0]), o_default);
}

23
dep.h
View File

@@ -1,5 +1,5 @@
/* Definitions of dependency data structures for GNU Make. /* Definitions of dependency data structures for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -53,22 +53,23 @@ struct nameseq
const char *name; const char *name;
}; };
#define PARSEFS_NONE 0x0000
#define PARSEFS_NONE (0x0000) #define PARSEFS_NOSTRIP 0x0001
#define PARSEFS_NOSTRIP (0x0001) #define PARSEFS_NOAR 0x0002
#define PARSEFS_NOAR (0x0002) #define PARSEFS_NOGLOB 0x0004
#define PARSEFS_NOGLOB (0x0004) #define PARSEFS_EXISTS 0x0008
#define PARSEFS_EXISTS (0x0008) #define PARSEFS_NOCACHE 0x0010
#define PARSEFS_NOCACHE (0x0010)
#define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \ #define PARSE_FILE_SEQ(_s,_t,_c,_p,_f) \
(_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f)) (_t *)parse_file_seq ((_s),sizeof (_t),(_c),(_p),(_f))
#define PARSE_SIMPLE_SEQ(_s,_t) \
(_t *)parse_file_seq ((_s),sizeof (_t),MAP_NUL,NULL,PARSEFS_NONE)
#ifdef VMS #ifdef VMS
void *parse_file_seq (); void *parse_file_seq ();
#else #else
void *parse_file_seq (char **stringp, unsigned int size, void *parse_file_seq (char **stringp, unsigned int size,
int stopchar, const char *prefix, int flags); int stopmap, const char *prefix, int flags);
#endif #endif
char *tilde_expand (const char *name); char *tilde_expand (const char *name);
@@ -87,5 +88,5 @@ struct dep *copy_dep_chain (const struct dep *d);
void free_dep_chain (struct dep *d); void free_dep_chain (struct dep *d);
void free_ns_chain (struct nameseq *n); void free_ns_chain (struct nameseq *n);
struct dep *read_all_makefiles (const char **makefiles); struct dep *read_all_makefiles (const char **makefiles);
void eval_buffer (char *buffer); void eval_buffer (char *buffer, const gmk_floc *floc);
int update_goal_chain (struct dep *goals); enum update_status update_goal_chain (struct dep *goals);

115
dir.c
View File

@@ -1,5 +1,5 @@
/* Directory hashing for GNU Make. /* Directory hashing for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,8 +14,10 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "hash.h" #include "hash.h"
#include "filedef.h"
#include "dep.h"
#ifdef HAVE_DIRENT_H #ifdef HAVE_DIRENT_H
# include <dirent.h> # include <dirent.h>
@@ -84,21 +86,21 @@ dosify (const char *filename)
df = dos_filename; df = dos_filename;
/* First, transform the name part. */ /* First, transform the name part. */
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i) for (i = 0; i < 8 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
*df++ = tolower ((unsigned char)*filename++); *df++ = tolower ((unsigned char)*filename++);
/* Now skip to the next dot. */ /* Now skip to the next dot. */
while (*filename != '\0' && *filename != '.') while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
++filename; ++filename;
if (*filename != '\0') if (*filename != '\0')
{ {
*df++ = *filename++; *df++ = *filename++;
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i) for (i = 0; i < 3 && ! STOP_SET (*filename, MAP_DOT|MAP_NUL); ++i)
*df++ = tolower ((unsigned char)*filename++); *df++ = tolower ((unsigned char)*filename++);
} }
/* Look for more dots. */ /* Look for more dots. */
while (*filename != '\0' && *filename != '.') while (! STOP_SET (*filename, MAP_DOT|MAP_NUL))
++filename; ++filename;
if (*filename == '.') if (*filename == '.')
return filename; return filename;
@@ -144,11 +146,11 @@ static int
vms_hash (const char *name) vms_hash (const char *name)
{ {
int h = 0; int h = 0;
int g;
while (*name) while (*name)
{ {
unsigned char uc = *name; unsigned char uc = *name;
int g;
#ifdef HAVE_CASE_INSENSITIVE_FS #ifdef HAVE_CASE_INSENSITIVE_FS
h = (h << 4) + (isupper (uc) ? tolower (uc) : uc); h = (h << 4) + (isupper (uc) ? tolower (uc) : uc);
#else #else
@@ -413,19 +415,10 @@ static struct directory *find_directory (const char *name);
static struct directory * static struct directory *
find_directory (const char *name) find_directory (const char *name)
{ {
const char *p;
struct directory *dir; struct directory *dir;
struct directory **dir_slot; struct directory **dir_slot;
struct directory dir_key; struct directory dir_key;
int r;
#ifdef WINDOWS32
char* w32_path;
char fs_label[BUFSIZ];
char fs_type[BUFSIZ];
unsigned long fs_serno;
unsigned long fs_flags;
unsigned long fs_len;
#endif
#ifdef VMS #ifdef VMS
if ((*name == '.') && (*(name+1) == 0)) if ((*name == '.') && (*(name+1) == 0))
name = "[]"; name = "[]";
@@ -439,14 +432,14 @@ find_directory (const char *name)
if (HASH_VACANT (dir)) if (HASH_VACANT (dir))
{ {
struct stat st;
/* The directory was not found. Create a new entry for it. */ /* The directory was not found. Create a new entry for it. */
const char *p = name + strlen (name);
struct stat st;
int r;
p = name + strlen (name);
dir = xmalloc (sizeof (struct directory)); dir = xmalloc (sizeof (struct directory));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS) #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
dir->name = strcache_add_len (downcase(name), p - name); dir->name = strcache_add_len (downcase (name), p - name);
#else #else
dir->name = strcache_add_len (name, p - name); dir->name = strcache_add_len (name, p - name);
#endif #endif
@@ -487,6 +480,9 @@ find_directory (const char *name)
{ {
/* Search the contents hash table; device and inode are the key. */ /* Search the contents hash table; device and inode are the key. */
#ifdef WINDOWS32
char *w32_path;
#endif
struct directory_contents *dc; struct directory_contents *dc;
struct directory_contents **dc_slot; struct directory_contents **dc_slot;
struct directory_contents dc_key; struct directory_contents dc_key;
@@ -510,7 +506,13 @@ find_directory (const char *name)
if (HASH_VACANT (dc)) if (HASH_VACANT (dc))
{ {
/* Nope; this really is a directory we haven't seen before. */ /* Nope; this really is a directory we haven't seen before. */
#ifdef WINDOWS32
char fs_label[BUFSIZ];
char fs_type[BUFSIZ];
unsigned long fs_serno;
unsigned long fs_flags;
unsigned long fs_len;
#endif
dc = (struct directory_contents *) dc = (struct directory_contents *)
xmalloc (sizeof (struct directory_contents)); xmalloc (sizeof (struct directory_contents));
@@ -521,20 +523,16 @@ find_directory (const char *name)
dc->ctime = st.st_ctime; dc->ctime = st.st_ctime;
dc->mtime = st.st_mtime; dc->mtime = st.st_mtime;
/* /* NTFS is the only WINDOWS32 filesystem that bumps mtime on a
* NTFS is the only WINDOWS32 filesystem that bumps mtime directory when files are added/deleted from a directory. */
* on a directory when files are added/deleted from
* a directory.
*/
w32_path[3] = '\0'; w32_path[3] = '\0';
if (GetVolumeInformation(w32_path, if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
fs_label, sizeof (fs_label), &fs_serno, &fs_len, &fs_flags, fs_type,
&fs_serno, &fs_len, sizeof (fs_type)) == FALSE)
&fs_flags, fs_type, sizeof (fs_type)) == FALSE)
dc->fs_flags = FS_UNKNOWN; dc->fs_flags = FS_UNKNOWN;
else if (!strcmp(fs_type, "FAT")) else if (!strcmp (fs_type, "FAT"))
dc->fs_flags = FS_FAT; dc->fs_flags = FS_FAT;
else if (!strcmp(fs_type, "NTFS")) else if (!strcmp (fs_type, "NTFS"))
dc->fs_flags = FS_NTFS; dc->fs_flags = FS_NTFS;
else else
dc->fs_flags = FS_UNKNOWN; dc->fs_flags = FS_UNKNOWN;
@@ -581,7 +579,6 @@ static int
dir_contents_file_exists_p (struct directory_contents *dir, dir_contents_file_exists_p (struct directory_contents *dir,
const char *filename) const char *filename)
{ {
unsigned int hash;
struct dirfile *df; struct dirfile *df;
struct dirent *d; struct dirent *d;
#ifdef WINDOWS32 #ifdef WINDOWS32
@@ -610,7 +607,6 @@ dir_contents_file_exists_p (struct directory_contents *dir,
filename = vmsify (filename,0); filename = vmsify (filename,0);
#endif #endif
hash = 0;
if (filename != 0) if (filename != 0)
{ {
struct dirfile dirfile_key; struct dirfile dirfile_key;
@@ -707,7 +703,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
{ {
df = xmalloc (sizeof (struct dirfile)); df = xmalloc (sizeof (struct dirfile));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS) #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
df->name = strcache_add_len (downcase(d->d_name), len); df->name = strcache_add_len (downcase (d->d_name), len);
#else #else
df->name = strcache_add_len (d->d_name, len); df->name = strcache_add_len (d->d_name, len);
#endif #endif
@@ -767,7 +763,7 @@ file_exists_p (const char *name)
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */ /* Forward and backslashes might be mixed. We need the rightmost one. */
{ {
const char *bslash = strrchr(name, '\\'); const char *bslash = strrchr (name, '\\');
if (!dirend || bslash > dirend) if (!dirend || bslash > dirend)
dirend = bslash; dirend = bslash;
/* The case of "d:file". */ /* The case of "d:file". */
@@ -827,7 +823,7 @@ file_impossible (const char *filename)
# ifdef HAVE_DOS_PATHS # ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */ /* Forward and backslashes might be mixed. We need the rightmost one. */
{ {
const char *bslash = strrchr(p, '\\'); const char *bslash = strrchr (p, '\\');
if (!dirend || bslash > dirend) if (!dirend || bslash > dirend)
dirend = bslash; dirend = bslash;
/* The case of "d:file". */ /* The case of "d:file". */
@@ -882,7 +878,7 @@ file_impossible (const char *filename)
new = xmalloc (sizeof (struct dirfile)); new = xmalloc (sizeof (struct dirfile));
new->length = strlen (filename); new->length = strlen (filename);
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS) #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
new->name = strcache_add_len (downcase(filename), new->length); new->name = strcache_add_len (downcase (filename), new->length);
#else #else
new->name = strcache_add_len (filename, new->length); new->name = strcache_add_len (filename, new->length);
#endif #endif
@@ -896,7 +892,6 @@ int
file_impossible_p (const char *filename) file_impossible_p (const char *filename)
{ {
const char *dirend; const char *dirend;
const char *p = filename;
struct directory_contents *dir; struct directory_contents *dir;
struct dirfile *dirfile; struct dirfile *dirfile;
struct dirfile dirfile_key; struct dirfile dirfile_key;
@@ -910,7 +905,7 @@ file_impossible_p (const char *filename)
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */ /* Forward and backslashes might be mixed. We need the rightmost one. */
{ {
const char *bslash = strrchr(filename, '\\'); const char *bslash = strrchr (filename, '\\');
if (!dirend || bslash > dirend) if (!dirend || bslash > dirend)
dirend = bslash; dirend = bslash;
/* The case of "d:file". */ /* The case of "d:file". */
@@ -941,12 +936,12 @@ file_impossible_p (const char *filename)
dirend++; dirend++;
#endif #endif
cp = alloca (dirend - filename + 1); cp = alloca (dirend - filename + 1);
memcpy (cp, p, dirend - p); memcpy (cp, filename, dirend - filename);
cp[dirend - p] = '\0'; cp[dirend - filename] = '\0';
dirname = cp; dirname = cp;
} }
dir = find_directory (dirname)->contents; dir = find_directory (dirname)->contents;
p = filename = slash + 1; filename = slash + 1;
} }
if (dir == 0 || dir->dirfiles.ht_vec == 0) if (dir == 0 || dir->dirfiles.ht_vec == 0)
@@ -954,13 +949,13 @@ file_impossible_p (const char *filename)
return 0; return 0;
#ifdef __MSDOS__ #ifdef __MSDOS__
filename = dosify (p); filename = dosify (filename);
#endif #endif
#ifdef HAVE_CASE_INSENSITIVE_FS #ifdef HAVE_CASE_INSENSITIVE_FS
filename = downcase (p); filename = downcase (filename);
#endif #endif
#ifdef VMS #ifdef VMS
filename = vmsify (p, 1); filename = vmsify (filename, 1);
#endif #endif
dirfile_key.name = filename; dirfile_key.name = filename;
@@ -1159,7 +1154,7 @@ read_dirstream (__ptr_t stream)
#ifdef __MINGW32__ #ifdef __MINGW32__
# if __MINGW32_MAJOR_VERSION < 3 || (__MINGW32_MAJOR_VERSION == 3 && \ # if __MINGW32_MAJOR_VERSION < 3 || (__MINGW32_MAJOR_VERSION == 3 && \
__MINGW32_MINOR_VERSION == 0) __MINGW32_MINOR_VERSION == 0)
d->d_name = xmalloc(len); d->d_name = xmalloc (len);
# endif # endif
#endif #endif
FAKE_DIR_ENTRY (d); FAKE_DIR_ENTRY (d);
@@ -1181,14 +1176,17 @@ static void
ansi_free (void *p) ansi_free (void *p)
{ {
if (p) if (p)
free(p); free (p);
} }
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a /* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
* macro for stat64(). If stat is a macro, make a local wrapper function to * macro for stat64(). If stat is a macro, make a local wrapper function to
* invoke it. * invoke it.
*
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
* regular file; fix that here.
*/ */
#ifndef stat #if !defined(stat) && !defined(WINDOWS32)
# ifndef VMS # ifndef VMS
int stat (const char *path, struct stat *sbuf); int stat (const char *path, struct stat *sbuf);
# endif # endif
@@ -1198,6 +1196,23 @@ static int
local_stat (const char *path, struct stat *buf) local_stat (const char *path, struct stat *buf)
{ {
int e; int e;
#ifdef WINDOWS32
size_t plen = strlen (path);
/* Make sure the parent of "." exists and is a directory, not a
file. This is because 'stat' on Windows normalizes the argument
foo/. => foo without checking first that foo is a directory. */
if (plen > 1 && path[plen - 1] == '.'
&& (path[plen - 2] == '/' || path[plen - 2] == '\\'))
{
char parent[MAXPATHLEN];
strncpy (parent, path, plen - 2);
parent[plen - 2] = '\0';
if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
return -1;
}
#endif
EINTRLOOP (e, stat (path, buf)); EINTRLOOP (e, stat (path, buf));
return e; return e;

View File

@@ -1,8 +0,0 @@
Makefile Makefile.in
version.texi fdl.texi make-stds.texi texinfo.tex
make.info*
make*.html
make.aux make.cp make.cps make.fn make.fns make.ky
make.pg make.toc make.tp make.vr make.log
make.dvi make.ps make.pdf
stamp-vti

20
doc/.gitignore vendored Normal file
View File

@@ -0,0 +1,20 @@
fdl.texi
make-stds.texi
stamp-vti
version.texi
make.info*
make*.html
make.aux
make.cp
make.cps
make.dvi
make.fn
make.fns
make.ky
make.log
make.pdf
make.pg
make.ps
make.toc
make.tp
make.vr

View File

@@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough # -*-Makefile-*-, or close enough
# Copyright (C) 2000-2012 Free Software Foundation, Inc. # Copyright (C) 2000-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -4,7 +4,6 @@
@include version.texi @include version.texi
@set EDITION 0.72 @set EDITION 0.72
@set RCSID $Id$
@settitle GNU @code{make} @settitle GNU @code{make}
@setchapternewpage odd @setchapternewpage odd
@@ -27,7 +26,7 @@ of @cite{The GNU Make Manual}, for GNU @code{make} version @value{VERSION}.
Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
@quotation @quotation
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
@@ -220,6 +219,11 @@ Recipe Execution
* Choosing the Shell:: How @code{make} chooses the shell used * Choosing the Shell:: How @code{make} chooses the shell used
to run recipes. to run recipes.
Parallel Execution
* Parallel Output:: Handling output during parallel execution
* Parallel Input:: Handling input during parallel execution
Recursive Use of @code{make} Recursive Use of @code{make}
* MAKE Variable:: The special effects of using @samp{$(MAKE)}. * MAKE Variable:: The special effects of using @samp{$(MAKE)}.
@@ -348,6 +352,9 @@ GNU Guile Integration
Loading Dynamic Objects Loading Dynamic Objects
* load Directive:: Loading dynamic objects as extensions. * load Directive:: Loading dynamic objects as extensions.
* Remaking Loaded Objects:: How loaded objects get remade.
* Loaded Object API:: Programmatic interface for loaded objects.
* Loaded Object Example:: Example of a loaded object
@end detailmenu @end detailmenu
@end menu @end menu
@@ -1287,7 +1294,6 @@ in the makefiles. @xref{Include, , Including Other Makefiles}.
@node Remaking Makefiles, Overriding Makefiles, MAKEFILES Variable, Makefiles @node Remaking Makefiles, Overriding Makefiles, MAKEFILES Variable, Makefiles
@section How Makefiles Are Remade @section How Makefiles Are Remade
@cindex updating makefiles @cindex updating makefiles
@cindex remaking makefiles @cindex remaking makefiles
@cindex makefile, remaking of @cindex makefile, remaking of
@@ -4057,44 +4063,16 @@ If there is nothing looking like an integer after the @samp{-j} option,
there is no limit on the number of job slots. The default number of job there is no limit on the number of job slots. The default number of job
slots is one, which means serial execution (one thing at a time). slots is one, which means serial execution (one thing at a time).
One unpleasant consequence of running several recipes simultaneously is Handling recursive @code{make} invocations raises issues for parallel
that output generated by the recipes appears whenever each recipe execution. For more information on this, see @ref{Options/Recursion,
sends it, so messages from different recipes may be interspersed. ,Communicating Options to a Sub-@code{make}}.
Another problem is that two processes cannot both take input from the
same device; so to make sure that only one recipe tries to take input
from the terminal at once, @code{make} will invalidate the standard
input streams of all but one running recipe. This means that
attempting to read from standard input will usually be a fatal error (a
@samp{Broken pipe} signal) for most child processes if there are
several.
@cindex broken pipe
@cindex standard input
It is unpredictable which recipe will have a valid standard input stream
(which will come from the terminal, or wherever you redirect the standard
input of @code{make}). The first recipe run will always get it first, and
the first recipe started after that one finishes will get it next, and so
on.
We will change how this aspect of @code{make} works if we find a better
alternative. In the mean time, you should not rely on any recipe using
standard input at all if you are using the parallel execution feature; but
if you are not using this feature, then standard input works normally in
all recipes.
Finally, handling recursive @code{make} invocations raises issues. For
more information on this, see
@ref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}.
If a recipe fails (is killed by a signal or exits with a nonzero If a recipe fails (is killed by a signal or exits with a nonzero
status), and errors are not ignored for that recipe status), and errors are not ignored for that recipe (@pxref{Errors,
(@pxref{Errors, ,Errors in Recipes}), ,Errors in Recipes}), the remaining recipe lines to remake the same
the remaining recipe lines to remake the same target will not be run. target will not be run. If a recipe fails and the @samp{-k} or
If a recipe fails and the @samp{-k} or @samp{--keep-going} @samp{--keep-going} option was not given (@pxref{Options Summary,
option was not given ,Summary of Options}), @code{make} aborts execution. If make
(@pxref{Options Summary, ,Summary of Options}),
@code{make} aborts execution. If make
terminates for any reason (including a signal) with child processes terminates for any reason (including a signal) with child processes
running, it waits for them to finish before actually exiting.@refill running, it waits for them to finish before actually exiting.@refill
@@ -4127,6 +4105,135 @@ average goes below that limit, or until all the other jobs finish.
By default, there is no load limit. By default, there is no load limit.
@menu
* Parallel Output:: Handling output during parallel execution
* Parallel Input:: Handling input during parallel execution
@end menu
@node Parallel Output, Parallel Input, Parallel, Parallel
@subsection Output During Parallel Execution
@cindex output during parallel execution
@cindex parallel execution, output during
When running several recipes in parallel the output from each
recipe appears as soon as it is generated, with the result that
messages from different recipes may be interspersed, sometimes even
appearing on the same line. This can make reading the output very
difficult.
@cindex @code{--output-sync}
@cindex @code{-O}
To avoid this you can use the @samp{--output-sync} (@samp{-O}) option.
This option instructs @code{make} to save the output from the commands
it invokes and print it all once the commands are completed.
Additionally, if there are multiple recursive @code{make} invocations
running in parallel, they will communicate so that only one of them is
generating output at a time.
If working directory printing is enabled (@pxref{-w Option, ,The
@samp{--print-directory} Option}), the enter/leave messages are
printed around each output grouping. If you prefer not to see these
messages add the @samp{--no-print-directory} option to @code{MAKEFLAGS}.
There are four levels of granularity when synchronizing output,
specified by giving an argument to the option (e.g., @samp{-Oline} or
@samp{--output-sync=recurse}).
@table @code
@item none
This is the default: all output is sent directly as it is generated and
no synchronization is performed.
@item line
Output from each individual line of the recipe is grouped and printed
as soon as that line is complete. If a recipe consists of multiple
lines, they may be interspersed with lines from other recipes.
@item target
Output from the entire recipe for each target is grouped and printed
once the target is complete. This is the default if the
@code{--output-sync} or @code{-O} option is given with no argument.
@item recurse
Output from each recursive invocation of @code{make} is grouped and
printed once the recursive invocation is complete.
@end table
Regardless of the mode chosen, the total build time will be the same.
The only difference is in how the output appears.
The @samp{target} and @samp{recurse} modes both collect the output of
the entire recipe of a target and display it uninterrupted when the
recipe completes. The difference between them is in how recipes that
contain recursive invocations of @code{make} are treated
(@pxref{Recursion, ,Recursive Use of @code{make}}). For all recipes
which have no recursive lines, the @samp{target} and @samp{recurse}
modes behave identically.
If the @samp{recurse} mode is chosen, recipes that contain recursive
@code{make} invocations are treated the same as other targets: the
output from the recipe, including the output from the recursive
@code{make}, is saved and printed after the entire recipe is complete.
This ensures output from all the targets built by a given recursive
@code{make} instance are grouped together, which may make the output
easier to understand. However it also leads to long periods of time
during the build where no output is seen, followed by large bursts of
output. If you are not watching the build as it proceeds, but instead
viewing a log of the build after the fact, this may be the best option
for you.
If you are watching the output, the long gaps of quiet during the
build can be frustrating. The @samp{target} output synchronization
mode detects when @code{make} is going to be invoked recursively,
using the standard methods, and it will not synchronize the output of
those lines. The recursive @code{make} will perform the
synchronization for its targets and the output from each will be
displayed immediately when it completes. Be aware that output from
recursive lines of the recipe are not synchronized (for example if
the recursive line prints a message before running @code{make}, that
message will not be synchronized).
The @samp{line} mode can be useful for front-ends that are watching
the output of @code{make} to track when recipes are started and
completed.
Some programs invoked by @code{make} may behave differently if they
determine they're writing output to a terminal versus a file (often
described as ``interactive'' vs. ``non-interactive'' modes). For
example, many programs that can display colorized output will not do
so if they determine they are not writing to a terminal. If your
makefile invokes a program like this then using the output
synchronization options will cause the program to believe it's running
in ``non-interactive'' mode even though the output will ultimately go
to the terminal.
@node Parallel Input, , Parallel Output, Parallel
@subsection Input During Parallel Execution
@cindex input during parallel execution
@cindex parallel execution, input during
@cindex standard input
Two processes cannot both take input from the same device at the same
time. To make sure that only one recipe tries to take input from the
terminal at once, @code{make} will invalidate the standard input
streams of all but one running recipe. If another recipe attempts to
read from standard input it will usually incur a fatal error (a
@samp{Broken pipe} signal).
@cindex broken pipe
It is unpredictable which recipe will have a valid standard input stream
(which will come from the terminal, or wherever you redirect the standard
input of @code{make}). The first recipe run will always get it first, and
the first recipe started after that one finishes will get it next, and so
on.
We will change how this aspect of @code{make} works if we find a better
alternative. In the mean time, you should not rely on any recipe using
standard input at all if you are using the parallel execution feature; but
if you are not using this feature, then standard input works normally in
all recipes.
@node Errors, Interrupts, Parallel, Recipes @node Errors, Interrupts, Parallel, Recipes
@section Errors in Recipes @section Errors in Recipes
@cindex errors (in recipes) @cindex errors (in recipes)
@@ -4696,6 +4803,23 @@ itself. For instance, the @samp{-t}, @samp{-n}, and @samp{-q} options, if
put in one of these variables, could have disastrous consequences and would put in one of these variables, could have disastrous consequences and would
certainly have at least surprising and probably annoying effects.@refill certainly have at least surprising and probably annoying effects.@refill
If you'd like to run other implementations of @code{make} in addition
to GNU @code{make}, and hence do not want to add GNU
@code{make}-specific flags to the @code{MAKEFLAGS} variable, you can
add them to the @code{GNUMAKEFLAGS} variable instead. This variable
is parsed just before @code{MAKEFLAGS}, in the same way as
@code{MAKEFLAGS}. When @code{make} constructs @code{MAKEFLAGS} to
pass to a recursive @code{make} it will include all flags, even those
taken from @code{GNUMAKEFLAGS}. As a result, after parsing
@code{GNUMAKEFLAGS} GNU @code{make} sets this variable to the empty
string to avoid duplicating flags during recursion.
It's best to use @code{GNUMAKEFLAGS} only with flags which won't
materially change the behavior of your makefiles. If your makefiles
require GNU make anyway then simply use @code{MAKEFLAGS}. Flags such
as @samp{--no-print-directory} or @samp{--output-sync} may be
appropriate for @code{GNUMAKEFLAGS}.
@node -w Option, , Options/Recursion, Recursion @node -w Option, , Options/Recursion, Recursion
@subsection The @samp{--print-directory} Option @subsection The @samp{--print-directory} Option
@cindex directories, printing them @cindex directories, printing them
@@ -6295,7 +6419,6 @@ Has GNU Guile available as an embedded extension language.
@item load @item load
Supports dynamically loadable objects for creating custom extensions. Supports dynamically loadable objects for creating custom extensions.
@xref{Loading Objects, ,Loading Dynamic Objects}. @xref{Loading Objects, ,Loading Dynamic Objects}.
@end table @end table
@vindex .INCLUDE_DIRS @r{(list of include directories)} @vindex .INCLUDE_DIRS @r{(list of include directories)}
@@ -8479,6 +8602,10 @@ By default, the above messages are not enabled while trying to remake
the makefiles. This option enables messages while rebuilding makefiles, the makefiles. This option enables messages while rebuilding makefiles,
too. Note that the @samp{all} option does enable this option. This too. Note that the @samp{all} option does enable this option. This
option also enables @samp{basic} messages. option also enables @samp{basic} messages.
@item n (@i{none})
Disable all debugging currently enabled. If additional debugging
flags are encountered after this they will still take effect.
@end table @end table
@item -e @item -e
@@ -8597,6 +8724,25 @@ prerequisites, and do not remake anything on account of changes in
are ignored. @xref{Avoiding Compilation, ,Avoiding Recompilation of are ignored. @xref{Avoiding Compilation, ,Avoiding Recompilation of
Some Files}.@refill Some Files}.@refill
@item -O[@var{type}]
@cindex @code{-O}
@itemx --output-sync[=@var{type}]
@cindex @code{--output-sync}
@cindex output during parallel execution
@cindex parallel execution, output during
Ensure that the complete output from each recipe is printed in one
uninterrupted sequence. This option is only useful when using the
@code{--jobs} option to run multiple recipes simultaneously
(@pxref{Parallel, ,Parallel Execution}) Without this option output
will be displayed as it is generated by the recipes.@refill
With no type or the type @samp{target}, output from the entire recipe
of each target is grouped together. With the type @samp{line}, output
from each line in the recipe is grouped together. With the type
@samp{recurse}, the output from an entire recursive make is grouped
together. With the type @samp{none}, no output synchronization is
performed. @xref{Parallel Output, ,Output During Parallel Execution}.
@item -p @item -p
@cindex @code{-p} @cindex @code{-p}
@itemx --print-data-base @itemx --print-data-base
@@ -8686,11 +8832,11 @@ recipes were done, in order to fool future invocations of
@item --trace @item --trace
@cindex @code{--trace} @cindex @code{--trace}
@c Extra blank line here makes the table look better. Show tracing information for @code{make} execution. Prints the entire
recipe to be executed, even for recipes that are normally silent (due
Print the entire recipe to be executed, even for recipes that are to @code{.SILENT} or @samp{@@}). Also prints the makefile name and
normally silent (due to @code{.SILENT} or @samp{@@}). Also print the line number where the recipe was defined, and information on why the
makefile name and line number where the recipe was defined. target is being rebuilt.
@item -v @item -v
@cindex @code{-v} @cindex @code{-v}
@@ -8710,7 +8856,7 @@ from complicated nests of recursive @code{make} commands.
rarely need to specify this option since @samp{make} does it for you; rarely need to specify this option since @samp{make} does it for you;
see @ref{-w Option, ,The @samp{--print-directory} Option}.) see @ref{-w Option, ,The @samp{--print-directory} Option}.)
@itemx --no-print-directory @item --no-print-directory
@cindex @code{--no-print-directory} @cindex @code{--no-print-directory}
Disable printing of the working directory under @code{-w}. Disable printing of the working directory under @code{-w}.
This option is useful when @code{-w} is turned on automatically, This option is useful when @code{-w} is turned on automatically,
@@ -9378,14 +9524,16 @@ Extra flags to give to the SCCS @code{get} program.
@item LDFLAGS @item LDFLAGS
@vindex LDFLAGS @vindex LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker, Extra flags to give to compilers when they are supposed to invoke the linker,
@samp{ld}. @samp{ld}, such as @code{-L}. Libraries (@code{-lfoo}) should be
added to the @code{LDLIBS} variable instead.
@item LDLIBS @item LDLIBS
@vindex LDLIBS @vindex LDLIBS
@vindex LOADLIBES @vindex LOADLIBES
Library flags or names given to compilers when they are supposed to Library flags or names given to compilers when they are supposed to
invoke the linker, @samp{ld}. @code{LOADLIBES} is a deprecated (but invoke the linker, @samp{ld}. @code{LOADLIBES} is a deprecated (but
still supported) alternative to @code{LDLIBS}. still supported) alternative to @code{LDLIBS}. Non-library linker
flags, such as @code{-L}, should go in the @code{LDFLAGS} variable.
@item LFLAGS @item LFLAGS
@vindex LFLAGS @vindex LFLAGS
@@ -10539,11 +10687,11 @@ program, although this can be inefficient.
In cases where the built-in capabilities of GNU @code{make} are In cases where the built-in capabilities of GNU @code{make} are
insufficient to your requirements there are two options for extending insufficient to your requirements there are two options for extending
@code{make}. On systems where it's provided, you can utilize GNU @code{make}. On systems where it's provided, you can utilize GNU
Guile as an embedded scripting language (@pxref{Guile Integration, Guile as an embedded scripting language (@pxref{Guile Integration,,GNU
,GNU Guile Integration}). On systems which support dynamically Guile Integration}). On systems which support dynamically loadable
loadable objects, you can write your own extension in any language objects, you can write your own extension in any language (which can
(which can be compiled into such an object) and load it to provide be compiled into such an object) and load it to provide extended
extended capabilities (@pxref{load Directive, ,The @code{load} Directive}). capabilities (@pxref{load Directive, ,The @code{load} Directive}).
@menu @menu
* Guile Integration:: Using Guile as an embedded scripting language. * Guile Integration:: Using Guile as an embedded scripting language.
@@ -10660,23 +10808,24 @@ exports these procedures as public interfaces from that module:
@table @code @table @code
@item gmk-expand @item gmk-expand
@findex gmk-expand
This procedure takes a single argument which is converted into a This procedure takes a single argument which is converted into a
string. The string is expanded by @code{make} using normal string. The string is expanded by @code{make} using normal
@code{make} expansion rules. The result of the expansion is converted @code{make} expansion rules. The result of the expansion is converted
into a Guile string and provided as the result of the procedure. into a Guile string and provided as the result of the procedure.
@item gmk-eval @item gmk-eval
@findex gmk-eval
This procedure takes a single argument which is converted into a This procedure takes a single argument which is converted into a
string. The string is evaluated by @code{make} as if it were a string. The string is evaluated by @code{make} as if it were a
makefile. This is the same capability available via the @code{eval} makefile. This is the same capability available via the @code{eval}
function (@pxref{Eval Function}). The result of the @code{gmk-eval} function (@pxref{Eval Function}). The result of the @code{gmk-eval}
procedure is always the empty string. procedure is always the empty string.
@item gmk-var Note that @code{gmk-eval} is not quite the same as using
This procedure takes a single argument which is converted into a @code{gmk-expand} with the @code{eval} function: in the latter case
string. The string is assumed to be the name of a @code{make} the evaluated string will be expanded @emph{twice}; first by
variable, which is then expanded. The expansion is converted into a @code{gmk-expand}, then again by the @code{eval} function.
string and provided as the result of the procedure.
@end table @end table
@@ -10758,8 +10907,8 @@ symbol to be stored in a @code{make} variable.
@node Loading Objects, , Guile Integration, Extending make @node Loading Objects, , Guile Integration, Extending make
@section Loading Dynamic Objects @section Loading Dynamic Objects
@cindex loading objects @cindex loaded objects
@cindex objects, loading @cindex objects, loaded
@cindex extensions, loading @cindex extensions, loading
@cartouche @cartouche
@@ -10768,13 +10917,8 @@ The @code{load} directive and extension capability is considered a
``technology preview'' in this release of GNU make. We encourage you ``technology preview'' in this release of GNU make. We encourage you
to experiment with this feature and we appreciate any feedback on it. to experiment with this feature and we appreciate any feedback on it.
However we cannot guarantee to maintain backward-compatibility in the However we cannot guarantee to maintain backward-compatibility in the
next release. next release. Consider using GNU Guile instead for extending GNU make
(@pxref{Guile Function, ,The @code{guile} Function}).
In particular, for this feature to be useful your extensions will need
to invoke various functions internal to GNU @code{make}. In this
release there is no stable programming interface defined for
@code{make}: any internal function may change or even disappear in
future releases.
@end quotation @end quotation
@end cartouche @end cartouche
@@ -10786,15 +10930,18 @@ providing new capabilities which may then be invoked by your makefile.
The @code{load} directive is used to load a dynamic object. Once the The @code{load} directive is used to load a dynamic object. Once the
object is loaded, a ``setup'' function will be invoked to allow the object is loaded, a ``setup'' function will be invoked to allow the
object to initialize itself and register new facilities with GNU object to initialize itself and register new facilities with GNU
@code{make}. Typically a dynamic object would create new functions, @code{make}. A dynamic object might include new @code{make} functions,
for example, and the ``setup'' function would register them with GNU for example, and the ``setup'' function would register them with GNU
@code{make}'s function handling system. @code{make}'s function handling system.
@menu @menu
* load Directive:: Loading dynamic objects as extensions. * load Directive:: Loading dynamic objects as extensions.
* Remaking Loaded Objects:: How loaded objects get remade.
* Loaded Object API:: Programmatic interface for loaded objects.
* Loaded Object Example:: Example of a loaded object
@end menu @end menu
@node load Directive, , Loading Objects, Loading Objects @node load Directive, Remaking Loaded Objects, Loading Objects, Loading Objects
@subsection The @code{load} Directive @subsection The @code{load} Directive
@cindex load directive @cindex load directive
@cindex extensions, load directive @cindex extensions, load directive
@@ -10814,21 +10961,35 @@ or:
load @var{object-file}(@var{symbol-name}) @dots{} load @var{object-file}(@var{symbol-name}) @dots{}
@end example @end example
In the first form, the file @var{object-file} is dynamically loaded by The file @var{object-file} is dynamically loaded by GNU @code{make}.
GNU @code{make}. On failure, @code{make} will print a message and If @var{object-file} does not include a directory path then it is
exit. If the load succeeds @code{make} will invoke an initializing first looked for in the current directory. If it is not found there,
function whose name is created by taking the base file name of or a directory path is included, then system-specific paths will be
@var{object-file}, up to the first character which is not a valid searched. If the load fails for any reason, @code{make} will print a
symbol name character (alphanumerics and underscores are valid symbol message and exit.
name characters). To this prefix will be appended the suffix
@code{_gmake_setup}, then this symbol will be invoked.
In the second form, the function @var{symbol-name} will be invoked. If the load succeeds @code{make} will invoke an initializing function.
If @var{symbol-name} is provided, it will be used as the name of the
initializing function.
If no @var{symbol-name} is provided, the initializing function name is
created by taking the base file name of @var{object-file}, up to the
first character which is not a valid symbol name character
(alphanumerics and underscores are valid symbol name characters). To
this prefix will be appended the suffix @code{_gmk_setup}.
More than one object file may be loaded with a single @code{load} More than one object file may be loaded with a single @code{load}
directive, and both forms of @code{load} arguments may be used in the directive, and both forms of @code{load} arguments may be used in the
same directive. same directive.
The initializing function will be provided the file name and line
number of the invocation of the @code{load} operation. It should
return a value of type @code{int}, which must be @code{0} on failure
and non-@code{0} on success. If the return value is @code{-1}, then
GNU make will @emph{not} attempt to rebuild the object file
(@pxref{Remaking Loaded Objects, ,How Loaded Objects Are Remade}).
For example: For example:
@example @example
@@ -10837,7 +10998,7 @@ load ../mk_funcs.so
will load the dynamic object @file{../mk_funcs.so}. After the object will load the dynamic object @file{../mk_funcs.so}. After the object
is loaded, @code{make} will invoke the function (assumed to be defined is loaded, @code{make} will invoke the function (assumed to be defined
by the shared object) @code{mk_funcs_gmake_setup}. by the shared object) @code{mk_funcs_gmk_setup}.
On the other hand: On the other hand:
@@ -10849,7 +11010,7 @@ will load the dynamic object @file{../mk_funcs.so}. After the object
is loaded, @code{make} will invoke the function @code{init_mk_func}. is loaded, @code{make} will invoke the function @code{init_mk_func}.
Regardless of how many times an object file appears in a @code{load} Regardless of how many times an object file appears in a @code{load}
directive, it will only be loaded (and it's setup function will only directive, it will only be loaded (and its setup function will only
be invoked) once. be invoked) once.
@vindex .LOADED @vindex .LOADED
@@ -10864,6 +11025,296 @@ generated if an object fails to load. The failed object is not added
to the @code{.LOADED} variable, which can then be consulted to to the @code{.LOADED} variable, which can then be consulted to
determine if the load was successful. determine if the load was successful.
@node Remaking Loaded Objects, Loaded Object API, load Directive, Loading Objects
@subsection How Loaded Objects Are Remade
@cindex updating loaded objects
@cindex remaking loaded objects
@cindex loaded objects, remaking of
Loaded objects undergo the same re-make procedure as makefiles
(@pxref{Remaking Makefiles, ,How Makefiles Are Remade}). If any
loaded object is recreated, then @code{make} will start from scratch
and re-read all the makefiles, and reload the object files again. It
is not necessary for the loaded object to do anything special to
support this.@refill
It's up to the makefile author to provide the rules needed for
rebuilding the loaded object.
@node Loaded Object API, Loaded Object Example, Remaking Loaded Objects, Loading Objects
@subsection Loaded Object Interface
@cindex loaded object API
@cindex interface for loaded objects
@cartouche
@quotation Warning
For this feature to be useful your extensions will need to invoke
various functions internal to GNU @code{make}. The programming
interfaces provided in this release should not be considered stable:
functions may be added, removed, or change calling signatures or
implementations in future versions of GNU @code{make}.
@end quotation
@end cartouche
To be useful, loaded objects must be able to interact with GNU
@code{make}. This interaction includes both interfaces the loaded
object provides to makefiles and also interfaces @code{make} provides
to the loaded object to manipulate @code{make}'s operation.
The interface between loaded objects and @code{make} is defined by the
@file{gnumake.h} C header file. All loaded objects written in C
should include this header file. Any loaded object not written in C
will need to implement the interface defined in this header file.
Typically, a loaded object will register one or more new GNU
@code{make} functions using the @code{gmk_add_function} routine from
within its setup function. The implementations of these @code{make}
functions may make use of the @code{gmk_expand} and @code{gmk_eval}
routines to perform their tasks, then optionally return a string as
the result of the function expansion.
@subsubheading Loaded Object Licensing
@cindex loaded object licensing
@cindex plugin_is_GPL_compatible
Every dynamic extension should define the global symbol
@code{plugin_is_GPL_compatible} to assert that it has been licensed
under a GPL-compatible license. If this symbol does not exist,
@code{make} emits a fatal error and exits when it tries to load your
extension.
The declared type of the symbol should be @code{int}. It does not need
to be in any allocated section, though. The code merely asserts that
the symbol exists in the global scope. Something like this is enough:
@example
int plugin_is_GPL_compatible;
@end example
@subsubheading Data Structures
@table @code
@item gmk_floc
This structure represents a filename/location pair. It is provided
when defining items, so GNU @code{make} can inform the user later
where the definition occurred if necessary.
@end table
@subsubheading Registering Functions
@findex gmk_add_function
There is currently one way for makefiles to invoke operations provided
by the loaded object: through the @code{make} function call
interface. A loaded object can register one or more new functions
which may then be invoked from within the makefile in the same way as
any other function.
Use @code{gmk_add_function} to create a new @code{make} function. Its
arguments are as follows:
@table @code
@item name
The function name. This is what the makefile should use to invoke the
function. The name must be between 1 and 255 characters long and it
may only contain alphanumeric, period (@samp{.}), dash (@samp{-}), and
underscore (@samp{_}) characters. It may not begin with a period.
@item func_ptr
A pointer to a function that @code{make} will invoke when it expands
the function in a makefile. This function must be defined by the
loaded object.
@item min_args
The minimum number of arguments the function will accept. Must be
between 0 and 255. GNU @code{make} will check this and fail before
invoking @code{func_ptr} if the function was invoked with too few
arguments.
@item max_args
The maximum number of arguments the function will accept. Must be
between 0 and 255. GNU @code{make} will check this and fail before
invoking @code{func_ptr} if the function was invoked with too few
arguments. If the value is 0, then any number of arguments is
accepted. If the value is greater than 0, then it must be greater
than or equal to @code{min_args}.
@item flags
Flags that specify how this function will operate; the desired flags
should be OR'd together. If the @code{GMK_FUNC_NOEXPAND} flag is
given then the function arguments will not be expanded before the
function is called; otherwise they will be expanded first.
@end table
@subsubheading Registered Function Interface
@findex gmk_func_ptr
A function registered with @code{make} must match the
@code{gmk_func_ptr} type. It will be invoked with three parameters:
@code{name} (the name of the function), @code{argc} (the number of
arguments to the function), and @code{argv} (an array of pointers to
arguments to the function). The last pointer (that is,
@code{argv[argc]}) will be null (@code{0}).
The return value of the function is the result of expanding the
function. If the function expands to nothing the return value may be
null. Otherwise, it must be a pointer to a string created with
@code{gmk_alloc}. Once the function returns, @code{make} owns this
string and will free it when appropriate; it cannot be accessed by the
loaded object.
@subsubheading GNU @code{make} Facilities
There are some facilities exported by GNU @code{make} for use by
loaded objects. Typically these would be run from within the
setup function and/or the functions registered via
@code{gmk_add_function}, to retrieve or modify the data @code{make}
works with.
@table @code
@item gmk_expand
@findex gmk_expand
This function takes a string and expands it using @code{make}
expansion rules. The result of the expansion is returned in a
nil-terminated string buffer. The caller is responsible for calling
@code{gmk_free} with a pointer to the returned buffer when done.
@item gmk_eval
@findex gmk_eval
This function takes a buffer and evaluates it as a segment of makefile
syntax. This function can be used to define new variables, new rules,
etc. It is equivalent to using the @code{eval} @code{make} function.
@end table
Note that there is a difference between @code{gmk_eval} and calling
@code{gmk_expand} with a string using the @code{eval} function: in
the latter case the string will be expanded @emph{twice}; once by
@code{gmk_expand} and then again by the @code{eval} function. Using
@code{gmk_eval} the buffer is only expanded once, at most (as it's
read by the @code{make} parser).
@subsubheading Memory Management
Some systems allow for different memory management schemes. Thus you
should never pass memory that you've allocated directly to any
@code{make} function, nor should you attempt to directly free any
memory returned to you by any @code{make} function. Instead, use the
@code{gmk_alloc} and @code{gmk_free} functions.
In particular, the string returned to @code{make} by a function
registered using @code{gmk_add_function} @emph{must} be allocated
using @code{gmk_alloc}, and the string returned from the @code{make}
@code{gmk_expand} function @emph{must} be freed (when no longer
needed) using @code{gmk_free}.
@table @code
@item gmk_alloc
@findex gmk_alloc
Return a pointer to a newly-allocated buffer. This function will
always return a valid pointer; if not enough memory is available
@code{make} will exit.
@item gmk_free
@findex gmk_free
Free a buffer returned to you by @code{make}. Once the
@code{gmk_free} function returns the string will no longer be valid.
@end table
@node Loaded Object Example, , Loaded Object API, Loading Objects
@subsection Example Loaded Object
@cindex loaded object example
@cindex example of loaded objects
Let's suppose we wanted to write a new GNU @code{make} function that
would create a temporary file and return its name. We would like our
function to take a prefix as an argument. First we can write the
function in a file @file{mk_temp.c}:
@example
@group
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <gnumake.h>
int plugin_is_GPL_compatible;
char *
gen_tmpfile(const char *nm, int argc, char **argv)
@{
int fd;
/* Compute the size of the filename and allocate space for it. */
int len = strlen (argv[0]) + 6 + 1;
char *buf = gmk_alloc (len);
strcpy (buf, argv[0]);
strcat (buf, "XXXXXX");
fd = mkstemp(buf);
if (fd >= 0)
@{
/* Don't leak the file descriptor. */
close (fd);
return buf;
@}
/* Failure. */
fprintf (stderr, "mkstemp(%s) failed: %s\n", buf, strerror (errno));
gmk_free (buf);
return NULL;
@}
int
mk_temp_gmk_setup ()
@{
/* Register the function with make name "mk-temp". */
gmk_add_function ("mk-temp", gen_tmpfile, 1, 1, 1);
return 1;
@}
@end group
@end example
Next, we will write a makefile that can build this shared object, load
it, and use it:
@example
@group
all:
@@echo Temporary file: $(mk-temp tmpfile.)
load mk_temp.so
mk_temp.so: mk_temp.c
$(CC) -shared -fPIC -o $@ $<
@end group
@end example
On MS-Windows, due to peculiarities of how shared objects are
produced, the compiler needs to scan the @dfn{import library} produced
when building @code{make}, typically called
@file{libgnumake-@var{version}.dll.a}, where @var{version} is the
version of the load object API. So the recipe to produce a shared
object will look on Windows like this (assuming the API version is 1):
@example
@group
mk_temp.dll: mk_temp.c
$(CC) -shared -o $@ $< -lgnumake-1
@end group
@end example
Now when you run @code{make} you'll see something like:
@example
$ make
cc -shared -fPIC -o mk_temp.so mk_temp.c
Temporary filename: tmpfile.A7JEwd
@end example
@node Features, Missing, Extending make, Top @node Features, Missing, Extending make, Top
@chapter Features of GNU @code{make} @chapter Features of GNU @code{make}
@cindex features of GNU @code{make} @cindex features of GNU @code{make}
@@ -10973,6 +11424,11 @@ The concept of doing several things at once (parallelism) exists in
many incarnations of @code{make} and similar programs, though not in the many incarnations of @code{make} and similar programs, though not in the
System V or BSD implementations. @xref{Execution, ,Recipe Execution}. System V or BSD implementations. @xref{Execution, ,Recipe Execution}.
@item
A number of different build tools that support parallelism also
support collecting output and displaying as a single block.
@xref{Parallel Output, ,Output During Parallel Execution}.
@item @item
Modified variable references using pattern substitution come from Modified variable references using pattern substitution come from
SunOS 4. @xref{Reference, ,Basics of Variable References}. SunOS 4. @xref{Reference, ,Basics of Variable References}.
@@ -11007,6 +11463,12 @@ nonexistent file comes from SunOS 4 @code{make}. (But note that SunOS 4
The @code{!=} shell assignment operator exists in many BSD of The @code{!=} shell assignment operator exists in many BSD of
@code{make} and is purposefully implemented here to behave identically @code{make} and is purposefully implemented here to behave identically
to those implementations. to those implementations.
@item
Various build management tools are implemented using scripting
languages such as Perl or Python and thus provide a natural embedded
scripting language, similar to GNU @code{make}'s integration of GNU
Guile.
@end itemize @end itemize
The remaining features are inventions new in GNU @code{make}: The remaining features are inventions new in GNU @code{make}:
@@ -11113,9 +11575,8 @@ Various new built-in implicit rules.
@xref{Catalogue of Rules, ,Catalogue of Implicit Rules}. @xref{Catalogue of Rules, ,Catalogue of Implicit Rules}.
@item @item
The built-in variable @samp{MAKE_VERSION} gives the version number of Load dynamic objects which can modify the behavior of @code{make}.
@code{make}. @xref{Loading Objects, ,Loading Dynamic Objects}.
@vindex MAKE_VERSION
@end itemize @end itemize
@node Missing, Makefile Conventions, Features, Top @node Missing, Makefile Conventions, Features, Top
@@ -11459,6 +11920,11 @@ Evaluate @var{text} then read the results as makefile commands.
Expands to the empty string.@* Expands to the empty string.@*
@xref{Eval Function, ,The @code{eval} Function}. @xref{Eval Function, ,The @code{eval} Function}.
@item $(file @var{op} @var{filename},@var{text})
Expand the arguments, then open the file @var{filename} using mode
@var{op} and write @var{text} to that file.@*
@xref{File Function, ,The @code{file} Function}.
@item $(value @var{var}) @item $(value @var{var})
Evaluates to the contents of the variable @var{var}, with no expansion Evaluates to the contents of the variable @var{var}, with no expansion
performed on it.@* performed on it.@*
@@ -11558,6 +12024,18 @@ The name with which @code{make} was invoked. Using this variable in
recipes has special meaning. @xref{MAKE Variable, ,How the recipes has special meaning. @xref{MAKE Variable, ,How the
@code{MAKE} Variable Works}. @code{MAKE} Variable Works}.
@item MAKE_VERSION
The built-in variable @samp{MAKE_VERSION} expands to the version
number of the GNU @code{make} program.
@vindex MAKE_VERSION
@item MAKE_HOST
The built-in variable @samp{MAKE_HOST} expands to a string
representing the host that GNU @code{make} was built to run on.
@vindex MAKE_HOST
@item MAKELEVEL @item MAKELEVEL
The number of levels of recursion (sub-@code{make}s).@* The number of levels of recursion (sub-@code{make}s).@*
@@ -11574,6 +12052,17 @@ recipe line: its contents may not be quoted correctly for use in the
shell. Always allow recursive @code{make}'s to obtain these values shell. Always allow recursive @code{make}'s to obtain these values
through the environment from its parent. through the environment from its parent.
@item GNUMAKEFLAGS
Other flags parsed by @code{make}. You can set this in the environment or
a makefile to set @code{make} command-line flags. GNU @code{make}
never sets this variable itself. This variable is only needed if
you'd like to set GNU @code{make}-specific flags in a POSIX-compliant
makefile. This variable will be seen by GNU @code{make} and ignored
by other @code{make} implementations. It's not needed if you only use
GNU @code{make}; just use @code{MAKEFLAGS} directly.
@xref{Options/Recursion, ,Communicating Options to a Sub-@code{make}}.
@item MAKECMDGOALS @item MAKECMDGOALS
The targets given to @code{make} on the command line. Setting this The targets given to @code{make} on the command line. Setting this
@@ -11717,12 +12206,15 @@ of its arguments. @xref{Functions, ,Functions for Transforming Text}.
@itemx multiple target patterns. Stop. @itemx multiple target patterns. Stop.
@itemx target pattern contains no `%'. Stop. @itemx target pattern contains no `%'. Stop.
@itemx mixed implicit and static pattern rules. Stop. @itemx mixed implicit and static pattern rules. Stop.
These are generated for malformed static pattern rules. The first means These are generated for malformed static pattern rules. The first
there's no pattern in the target section of the rule; the second means means there's no pattern in the target section of the rule; the second
there are multiple patterns in the target section; the third means means there are multiple patterns in the target section; the third
the target doesn't contain a pattern character (@code{%}); and the means the target doesn't contain a pattern character (@code{%}); and
fourth means that all three parts of the static pattern rule contain the fourth means that all three parts of the static pattern rule
pattern characters (@code{%})--only the first two parts should. contain pattern characters (@code{%})--only the first two parts
should. If you see these errors and you aren't trying to create a
static pattern rule, check the value of any variables in your target
and prerequisite lists to be sure they do not contain colons.
@xref{Static Usage, ,Syntax of Static Pattern Rules}. @xref{Static Usage, ,Syntax of Static Pattern Rules}.
@item warning: -jN forced in submake: disabling jobserver mode. @item warning: -jN forced in submake: disabling jobserver mode.

View File

@@ -1,5 +1,5 @@
@echo off @echo off
rem Copyright (C) 1998-2012 Free Software Foundation, Inc. rem Copyright (C) 1998-2013 Free Software Foundation, Inc.
rem This file is part of GNU Make. rem This file is part of GNU Make.
rem rem
rem GNU Make is free software; you can redistribute it and/or modify it under rem GNU Make is free software; you can redistribute it and/or modify it under
@@ -20,6 +20,7 @@ echo Building Make for MSDOS
rem Echo ON so they will see what is going on. rem Echo ON so they will see what is going on.
@echo on @echo on
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g commands.c -o commands.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g commands.c -o commands.o
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g output.c -o output.o
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g job.c -o job.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g job.c -o job.o
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g dir.c -o dir.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g dir.c -o dir.o
gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g file.c -o file.o gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g file.c -o file.o
@@ -51,7 +52,7 @@ ar rv libglob.a glob.o fnmatch.o
@echo off @echo off
cd .. cd ..
echo commands.o > respf.$$$ echo commands.o > respf.$$$
for %%f in (job dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$ for %%f in (job output dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$
for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$ for %%f in (expand function vpath hash strcache version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$
echo glob/libglob.a >> respf.$$$ echo glob/libglob.a >> respf.$$$
rem gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g guile.c -o guile.o rem gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g guile.c -o guile.o

View File

@@ -1,5 +1,5 @@
/* Variable expansion functions for GNU Make. /* Variable expansion functions for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <assert.h> #include <assert.h>
@@ -26,7 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Initially, any errors reported when expanding strings will be reported /* Initially, any errors reported when expanding strings will be reported
against the file where the error appears. */ against the file where the error appears. */
const struct floc **expanding_var = &reading_file; const gmk_floc **expanding_var = &reading_file;
/* The next two describe the variable output buffer. /* The next two describe the variable output buffer.
This buffer is used to hold the variable-expansion of a line of the This buffer is used to hold the variable-expansion of a line of the
@@ -96,8 +96,8 @@ char *
recursively_expand_for_file (struct variable *v, struct file *file) recursively_expand_for_file (struct variable *v, struct file *file)
{ {
char *value; char *value;
const struct floc *this_var; const gmk_floc *this_var;
const struct floc **saved_varp; const gmk_floc **saved_varp;
struct variable_set_list *save = 0; struct variable_set_list *save = 0;
int set_reading = 0; int set_reading = 0;
@@ -200,7 +200,7 @@ variable_expand_string (char *line, const char *string, long length)
unsigned int line_offset; unsigned int line_offset;
if (!line) if (!line)
line = initialize_variable_output(); line = initialize_variable_output ();
o = line; o = line;
line_offset = line - variable_buffer; line_offset = line - variable_buffer;
@@ -304,10 +304,8 @@ variable_expand_string (char *line, const char *string, long length)
if (colon) if (colon)
{ {
/* This looks like a substitution reference: $(FOO:A=B). */ /* This looks like a substitution reference: $(FOO:A=B). */
const char *subst_beg, *subst_end, *replace_beg, *replace_end; const char *subst_beg = colon + 1;
const char *subst_end = lindex (subst_beg, end, '=');
subst_beg = colon + 1;
subst_end = lindex (subst_beg, end, '=');
if (subst_end == 0) if (subst_end == 0)
/* There is no = in sight. Punt on the substitution /* There is no = in sight. Punt on the substitution
reference and treat this as a variable name containing reference and treat this as a variable name containing
@@ -315,8 +313,8 @@ variable_expand_string (char *line, const char *string, long length)
colon = 0; colon = 0;
else else
{ {
replace_beg = subst_end + 1; const char *replace_beg = subst_end + 1;
replace_end = end; const char *replace_end = end;
/* Extract the variable name before the colon /* Extract the variable name before the colon
and look up that variable. */ and look up that variable. */
@@ -418,7 +416,7 @@ variable_expand_string (char *line, const char *string, long length)
char * char *
variable_expand (const char *line) variable_expand (const char *line)
{ {
return variable_expand_string(NULL, line, (long)-1); return variable_expand_string (NULL, line, (long)-1);
} }
/* Expand an argument for an expansion function. /* Expand an argument for an expansion function.
@@ -434,7 +432,7 @@ expand_argument (const char *str, const char *end)
char *r; char *r;
if (str == end) if (str == end)
return xstrdup(""); return xstrdup ("");
if (!end || *end == '\0') if (!end || *end == '\0')
return allocated_variable_expand (str); return allocated_variable_expand (str);
@@ -463,7 +461,7 @@ variable_expand_for_file (const char *line, struct file *file)
{ {
char *result; char *result;
struct variable_set_list *savev; struct variable_set_list *savev;
const struct floc *savef; const gmk_floc *savef;
if (file == 0) if (file == 0)
return variable_expand (line); return variable_expand (line);

47
file.c
View File

@@ -1,5 +1,5 @@
/* Target file management for GNU Make. /* Target file management for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,12 +14,12 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <assert.h> #include <assert.h>
#include "dep.h"
#include "filedef.h" #include "filedef.h"
#include "dep.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
#include "variable.h" #include "variable.h"
@@ -153,7 +153,7 @@ enter_file (const char *name)
struct file file_key; struct file file_key;
assert (*name != '\0'); assert (*name != '\0');
assert (strcache_iscached (name)); assert (! verify_flag || strcache_iscached (name));
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
if (*name != '.') if (*name != '.')
@@ -177,11 +177,14 @@ enter_file (const char *name)
file_slot = (struct file **) hash_find_slot (&files, &file_key); file_slot = (struct file **) hash_find_slot (&files, &file_key);
f = *file_slot; f = *file_slot;
if (! HASH_VACANT (f) && !f->double_colon) if (! HASH_VACANT (f) && !f->double_colon)
{
f->builtin = 0;
return f; return f;
}
new = xcalloc (sizeof (struct file)); new = xcalloc (sizeof (struct file));
new->name = new->hname = name; new->name = new->hname = name;
new->update_status = -1; new->update_status = us_none;
if (HASH_VACANT (f)) if (HASH_VACANT (f))
{ {
@@ -213,6 +216,7 @@ rehash_file (struct file *from_file, const char *to_hname)
struct file *f; struct file *f;
/* If it's already that name, we're done. */ /* If it's already that name, we're done. */
from_file->builtin = 0;
file_key.hname = to_hname; file_key.hname = to_hname;
if (! file_hash_cmp (from_file, &file_key)) if (! file_hash_cmp (from_file, &file_key))
return; return;
@@ -318,9 +322,11 @@ rehash_file (struct file *from_file, const char *to_hname)
MERGE (is_target); MERGE (is_target);
MERGE (cmd_target); MERGE (cmd_target);
MERGE (phony); MERGE (phony);
MERGE (loaded);
MERGE (ignore_vpath); MERGE (ignore_vpath);
#undef MERGE #undef MERGE
to_file->builtin = 0;
from_file->renamed = to_file; from_file->renamed = to_file;
} }
@@ -372,7 +378,7 @@ remove_intermediates (int sig)
&& !f->secondary && !f->cmd_target) && !f->secondary && !f->cmd_target)
{ {
int status; int status;
if (f->update_status == -1) if (f->update_status == us_none)
/* If nothing would have created this file yet, /* If nothing would have created this file yet,
don't print an "rm" command for it. */ don't print an "rm" command for it. */
continue; continue;
@@ -424,7 +430,8 @@ remove_intermediates (int sig)
struct dep * struct dep *
split_prereqs (char *p) split_prereqs (char *p)
{ {
struct dep *new = PARSE_FILE_SEQ (&p, struct dep, '|', NULL, 0); struct dep *new = PARSE_FILE_SEQ (&p, struct dep, MAP_PIPE, NULL,
PARSEFS_NONE);
if (*p) if (*p)
{ {
@@ -433,7 +440,7 @@ split_prereqs (char *p)
struct dep *ood; struct dep *ood;
++p; ++p;
ood = PARSE_FILE_SEQ (&p, struct dep, '\0', NULL, 0); ood = PARSE_SIMPLE_SEQ (&p, struct dep);
if (! new) if (! new)
new = ood; new = ood;
@@ -917,6 +924,13 @@ print_file (const void *item)
{ {
const struct file *f = item; const struct file *f = item;
/* If we're not using builtin targets, don't show them.
Ideally we'd be able to delete them altogether but currently there's no
facility to ever delete a file once it's been added. */
if (no_builtin_rules_flag && f->builtin)
return;
putchar ('\n'); putchar ('\n');
if (f->cmds && f->cmds->recipe_prefix != cmd_prefix) if (f->cmds && f->cmds->recipe_prefix != cmd_prefix)
@@ -944,6 +958,8 @@ print_file (const void *item)
puts (_("# Command line target.")); puts (_("# Command line target."));
if (f->dontcare) if (f->dontcare)
puts (_("# A default, MAKEFILES, or -include/sinclude makefile.")); puts (_("# A default, MAKEFILES, or -include/sinclude makefile."));
if (f->builtin)
puts (_("# Builtin rule"));
puts (f->tried_implicit puts (f->tried_implicit
? _("# Implicit rule search has been done.") ? _("# Implicit rule search has been done.")
: _("# Implicit rule search has not been done.")); : _("# Implicit rule search has not been done."));
@@ -985,23 +1001,18 @@ print_file (const void *item)
case cs_finished: case cs_finished:
switch (f->update_status) switch (f->update_status)
{ {
case -1: case us_none:
break; break;
case 0: case us_success:
puts (_("# Successfully updated.")); puts (_("# Successfully updated."));
break; break;
case 1: case us_question:
assert (question_flag); assert (question_flag);
puts (_("# Needs to be updated (-q is set).")); puts (_("# Needs to be updated (-q is set)."));
break; break;
case 2: case us_failed:
puts (_("# Failed to be updated.")); puts (_("# Failed to be updated."));
break; break;
default:
puts (_("# Invalid value in 'update_status' member!"));
fflush (stdout);
fflush (stderr);
abort ();
} }
break; break;
default: default:
@@ -1037,7 +1048,7 @@ print_file_data_base (void)
#define VERIFY_CACHED(_p,_n) \ #define VERIFY_CACHED(_p,_n) \
do{\ do{\
if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \ if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \
error (NULL, "%s: Field '%s' not cached: %s\n", _p->name, # _n, _p->_n); \ error (NULL, _("%s: Field '%s' not cached: %s"), _p->name, # _n, _p->_n); \
}while(0) }while(0)
static void static void

View File

@@ -1,5 +1,5 @@
/* Definition of target file data structures for GNU Make. /* Definition of target file data structures for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -28,13 +28,9 @@ struct file
const char *vpath; /* VPATH/vpath pathname */ const char *vpath; /* VPATH/vpath pathname */
struct dep *deps; /* all dependencies, including duplicates */ struct dep *deps; /* all dependencies, including duplicates */
struct commands *cmds; /* Commands to execute for this target. */ struct commands *cmds; /* Commands to execute for this target. */
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
const char *stem; /* Implicit stem, if an implicit const char *stem; /* Implicit stem, if an implicit
rule has been used */ rule has been used */
struct dep *also_make; /* Targets that are made by making this. */ struct dep *also_make; /* Targets that are made by making this. */
FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
has been performed. */
struct file *prev; /* Previous entry for same file name; struct file *prev; /* Previous entry for same file name;
used when there are multiple double-colon used when there are multiple double-colon
entries for the same file. */ entries for the same file. */
@@ -59,17 +55,28 @@ struct file
the same file. Otherwise this is null. */ the same file. Otherwise this is null. */
struct file *double_colon; struct file *double_colon;
short int update_status; /* Status of the last attempt to update, FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
or -1 if none has been made. */ FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
has been performed. */
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
enum update_status /* Status of the last attempt to update. */
{
us_success = 0, /* Successfully updated. Must be 0! */
us_none, /* No attempt to update has been made. */
us_question, /* Needs to be updated (-q is is set). */
us_failed /* Update failed. */
} update_status ENUM_BITFIELD (2);
enum cmd_state /* State of the commands. */ enum cmd_state /* State of the commands. */
{ /* Note: It is important that cs_not_started be zero. */ {
cs_not_started, /* Not yet started. */ cs_not_started = 0, /* Not yet started. Must be 0! */
cs_deps_running, /* Dep commands running. */ cs_deps_running, /* Dep commands running. */
cs_running, /* Commands running. */ cs_running, /* Commands running. */
cs_finished /* Commands finished. */ cs_finished /* Commands finished. */
} command_state ENUM_BITFIELD (2); } command_state ENUM_BITFIELD (2);
unsigned int builtin:1; /* True if the file is a builtin rule. */
unsigned int precious:1; /* Non-0 means don't delete file on quit */ unsigned int precious:1; /* Non-0 means don't delete file on quit */
unsigned int loaded:1; /* True if the file is a loaded object. */
unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp
has only one-second resolution. */ has only one-second resolution. */
unsigned int tried_implicit:1; /* Nonzero if have searched unsigned int tried_implicit:1; /* Nonzero if have searched

View File

@@ -1,5 +1,5 @@
/* Builtin function expansion for GNU Make. /* Builtin function expansion for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "filedef.h" #include "filedef.h"
#include "variable.h" #include "variable.h"
#include "dep.h" #include "dep.h"
@@ -29,12 +29,16 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
struct function_table_entry struct function_table_entry
{ {
union {
char *(*func_ptr) (char *output, char **argv, const char *fname);
gmk_func_ptr alloc_func_ptr;
} fptr;
const char *name; const char *name;
unsigned char len; unsigned char len;
unsigned char minimum_args; unsigned char minimum_args;
unsigned char maximum_args; unsigned char maximum_args;
char expand_args; unsigned char expand_args:1;
char *(*func_ptr) (char *output, char **argv, const char *fname); unsigned char alloc_fn:1;
}; };
static unsigned long static unsigned long
@@ -112,7 +116,7 @@ subst_expand (char *o, const char *text, const char *subst, const char *replace,
or only at the ends of words, check that this case qualifies. */ or only at the ends of words, check that this case qualifies. */
if (by_word if (by_word
&& ((p > text && !isblank ((unsigned char)p[-1])) && ((p > text && !isblank ((unsigned char)p[-1]))
|| (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) || ! STOP_SET (p[slen], MAP_BLANK|MAP_NUL)))
/* Struck out. Output the rest of the string that is /* Struck out. Output the rest of the string that is
no longer to be replaced. */ no longer to be replaced. */
o = variable_buffer_output (o, subst, slen); o = variable_buffer_output (o, subst, slen);
@@ -265,19 +269,19 @@ patsubst_expand (char *o, const char *text, char *pattern, char *replace)
static const struct function_table_entry * static const struct function_table_entry *
lookup_function (const char *s) lookup_function (const char *s)
{ {
struct function_table_entry function_table_entry_key;
const char *e = s; const char *e = s;
while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-')) while (STOP_SET (*e, MAP_USERFUNC))
e++; e++;
if (*e == '\0' || isblank ((unsigned char) *e))
{ if (e == s || !STOP_SET(*e, MAP_NUL|MAP_SPACE))
struct function_table_entry function_table_entry_key; return NULL;
function_table_entry_key.name = s; function_table_entry_key.name = s;
function_table_entry_key.len = e - s; function_table_entry_key.len = e - s;
return hash_find_item (&function_table, &function_table_entry_key); return hash_find_item (&function_table, &function_table_entry_key);
}
return 0;
} }
@@ -353,7 +357,7 @@ string_glob (char *line)
struct nameseq *chain; struct nameseq *chain;
unsigned int idx; unsigned int idx;
chain = PARSE_FILE_SEQ (&line, struct nameseq, '\0', NULL, chain = PARSE_FILE_SEQ (&line, struct nameseq, MAP_NUL, NULL,
/* We do not want parse_file_seq to strip './'s. /* We do not want parse_file_seq to strip './'s.
That would break examples like: That would break examples like:
$(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */ $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
@@ -503,16 +507,6 @@ func_flavor (char *o, char **argv, const char *funcname UNUSED)
return o; return o;
} }
#ifdef VMS
# define IS_PATHSEP(c) ((c) == ']')
#else
# ifdef HAVE_DOS_PATHS
# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
# else
# define IS_PATHSEP(c) ((c) == '/')
# endif
#endif
static char * static char *
func_notdir_suffix (char *o, char **argv, const char *funcname) func_notdir_suffix (char *o, char **argv, const char *funcname)
@@ -525,17 +519,13 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
int is_suffix = funcname[0] == 's'; int is_suffix = funcname[0] == 's';
int is_notdir = !is_suffix; int is_notdir = !is_suffix;
int stop = MAP_PATHSEP | (is_suffix ? MAP_DOT : 0);
while ((p2 = find_next_token (&list_iterator, &len)) != 0) while ((p2 = find_next_token (&list_iterator, &len)) != 0)
{ {
const char *p = p2 + len; const char *p = p2 + len - 1;
while (p >= p2 && ! STOP_SET (*p, stop))
while (p >= p2 && (!is_suffix || *p != '.'))
{
if (IS_PATHSEP (*p))
break;
--p; --p;
}
if (p >= p2) if (p >= p2)
{ {
@@ -582,16 +572,12 @@ func_basename_dir (char *o, char **argv, const char *funcname)
int is_basename = funcname[0] == 'b'; int is_basename = funcname[0] == 'b';
int is_dir = !is_basename; int is_dir = !is_basename;
int stop = MAP_PATHSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
while ((p2 = find_next_token (&p3, &len)) != 0) while ((p2 = find_next_token (&p3, &len)) != 0)
{ {
const char *p = p2 + len; const char *p = p2 + len - 1;
while (p >= p2 && (!is_basename || *p != '.')) while (p >= p2 && ! STOP_SET (*p, stop))
{
if (IS_PATHSEP (*p))
break;
--p; --p;
}
if (p >= p2 && (is_dir)) if (p >= p2 && (is_dir))
o = variable_buffer_output (o, p2, ++p - p2); o = variable_buffer_output (o, p2, ++p - p2);
@@ -736,7 +722,7 @@ check_numeric (const char *s, const char *msg)
strip_whitespace (&s, &end); strip_whitespace (&s, &end);
for (; s <= end; ++s) for (; s <= end; ++s)
if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see make.h. */ if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see makeint.h. */
break; break;
if (s <= end || end - beg < 0) if (s <= end || end - beg < 0)
@@ -1093,7 +1079,8 @@ func_error (char *o, char **argv, const char *funcname)
} }
strcpy (p, *argvp); strcpy (p, *argvp);
switch (*funcname) { switch (*funcname)
{
case 'e': case 'e':
fatal (reading_file, "%s", msg); fatal (reading_file, "%s", msg);
@@ -1102,8 +1089,8 @@ func_error (char *o, char **argv, const char *funcname)
break; break;
case 'i': case 'i':
printf ("%s\n", msg); outputs (0, msg);
fflush(stdout); outputs (0, "\n");
break; break;
default: default:
@@ -1126,7 +1113,6 @@ func_sort (char *o, char **argv, const char *funcname UNUSED)
int wordi; int wordi;
char *p; char *p;
unsigned int len; unsigned int len;
int i;
/* Find the maximum number of words we'll have. */ /* Find the maximum number of words we'll have. */
t = argv[0]; t = argv[0];
@@ -1151,6 +1137,8 @@ func_sort (char *o, char **argv, const char *funcname UNUSED)
if (wordi) if (wordi)
{ {
int i;
/* Now sort the list of words. */ /* Now sort the list of words. */
qsort (words, wordi, sizeof (char *), alpha_compare); qsort (words, wordi, sizeof (char *), alpha_compare);
@@ -1294,12 +1282,12 @@ static char *
func_and (char *o, char **argv, const char *funcname UNUSED) func_and (char *o, char **argv, const char *funcname UNUSED)
{ {
char *expansion; char *expansion;
int result;
while (1) while (1)
{ {
const char *begp = *argv; const char *begp = *argv;
const char *endp = begp + strlen (*argv) - 1; const char *endp = begp + strlen (*argv) - 1;
int result;
/* An empty condition is always false. */ /* An empty condition is always false. */
strip_whitespace (&begp, &endp); strip_whitespace (&begp, &endp);
@@ -1361,7 +1349,7 @@ func_eval (char *o, char **argv, const char *funcname UNUSED)
install_variable_buffer (&buf, &len); install_variable_buffer (&buf, &len);
eval_buffer (argv[0]); eval_buffer (argv[0], NULL);
restore_variable_buffer (buf, len); restore_variable_buffer (buf, len);
@@ -1377,7 +1365,7 @@ func_value (char *o, char **argv, const char *funcname UNUSED)
/* Copy its value into the output buffer without expanding it. */ /* Copy its value into the output buffer without expanding it. */
if (v) if (v)
o = variable_buffer_output (o, v->value, strlen(v->value)); o = variable_buffer_output (o, v->value, strlen (v->value));
return o; return o;
} }
@@ -1427,7 +1415,7 @@ int shell_function_pid = 0, shell_function_completed;
#include "sub_proc.h" #include "sub_proc.h"
void int
windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp) windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
{ {
SECURITY_ATTRIBUTES saAttr; SECURITY_ATTRIBUTES saAttr;
@@ -1438,6 +1426,10 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
HANDLE hProcess, tmpIn, tmpErr; HANDLE hProcess, tmpIn, tmpErr;
DWORD e; DWORD e;
/* Set status for return. */
pipedes[0] = pipedes[1] = -1;
*pid_p = (pid_t)-1;
saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL; saAttr.lpSecurityDescriptor = NULL;
@@ -1446,100 +1438,104 @@ windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp
INVALID_HANDLE_VALUE if the parent process closed them. If that INVALID_HANDLE_VALUE if the parent process closed them. If that
happens, we open the null device and pass its handle to happens, we open the null device and pass its handle to
process_begin below as the corresponding handle to inherit. */ process_begin below as the corresponding handle to inherit. */
tmpIn = GetStdHandle(STD_INPUT_HANDLE); tmpIn = GetStdHandle (STD_INPUT_HANDLE);
if (DuplicateHandle (GetCurrentProcess(), if (DuplicateHandle (GetCurrentProcess (), tmpIn,
tmpIn, GetCurrentProcess (), &hIn,
GetCurrentProcess(), 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
&hIn, {
0, e = GetLastError ();
TRUE, if (e == ERROR_INVALID_HANDLE)
DUPLICATE_SAME_ACCESS) == FALSE) { {
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) { tmpIn = CreateFile ("NUL", GENERIC_READ,
tmpIn = CreateFile("NUL", GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (tmpIn != INVALID_HANDLE_VALUE if (tmpIn != INVALID_HANDLE_VALUE
&& DuplicateHandle(GetCurrentProcess(), && DuplicateHandle (GetCurrentProcess (), tmpIn,
tmpIn, GetCurrentProcess (), &hIn,
GetCurrentProcess(), 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
&hIn, CloseHandle (tmpIn);
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE)
CloseHandle(tmpIn);
} }
if (hIn == INVALID_HANDLE_VALUE) if (hIn == INVALID_HANDLE_VALUE)
fatal (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e); {
error (NILF, _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
return -1;
} }
tmpErr = GetStdHandle(STD_ERROR_HANDLE); }
if (DuplicateHandle(GetCurrentProcess(), tmpErr = GetStdHandle (STD_ERROR_HANDLE);
tmpErr, if (DuplicateHandle (GetCurrentProcess (), tmpErr,
GetCurrentProcess(), GetCurrentProcess (), &hErr,
&hErr, 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
0, {
TRUE, e = GetLastError ();
DUPLICATE_SAME_ACCESS) == FALSE) { if (e == ERROR_INVALID_HANDLE)
if ((e = GetLastError()) == ERROR_INVALID_HANDLE) { {
tmpErr = CreateFile("NUL", GENERIC_WRITE, tmpErr = CreateFile ("NUL", GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (tmpErr != INVALID_HANDLE_VALUE if (tmpErr != INVALID_HANDLE_VALUE
&& DuplicateHandle(GetCurrentProcess(), && DuplicateHandle (GetCurrentProcess (), tmpErr,
tmpErr, GetCurrentProcess (), &hErr,
GetCurrentProcess(), 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
&hErr, CloseHandle (tmpErr);
0,
TRUE,
DUPLICATE_SAME_ACCESS) == FALSE)
CloseHandle(tmpErr);
} }
if (hErr == INVALID_HANDLE_VALUE) if (hErr == INVALID_HANDLE_VALUE)
fatal (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e); {
error (NILF, _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
return -1;
}
} }
if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError()); {
error (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
return -1;
}
hProcess = process_init_fd(hIn, hChildOutWr, hErr); hProcess = process_init_fd (hIn, hChildOutWr, hErr);
if (!hProcess) if (!hProcess)
fatal (NILF, _("windows32_openpipe(): process_init_fd() failed\n")); {
error (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
return -1;
}
/* make sure that CreateProcess() has Path it needs */ /* make sure that CreateProcess() has Path it needs */
sync_Path_environment(); sync_Path_environment ();
/* 'sync_Path_environment' may realloc 'environ', so take note of /* 'sync_Path_environment' may realloc 'environ', so take note of
the new value. */ the new value. */
envp = environ; envp = environ;
if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) { if (! process_begin (hProcess, command_argv, envp, command_argv[0], NULL))
{
/* register process for wait */ /* register process for wait */
process_register(hProcess); process_register (hProcess);
/* set the pid for returning to caller */ /* set the pid for returning to caller */
*pid_p = (pid_t) hProcess; *pid_p = (pid_t) hProcess;
/* set up to read data from child */ /* set up to read data from child */
pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY); pipedes[0] = _open_osfhandle ((intptr_t) hChildOutRd, O_RDONLY);
/* this will be closed almost right away */ /* this will be closed almost right away */
pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND); pipedes[1] = _open_osfhandle ((intptr_t) hChildOutWr, O_APPEND);
} else { return 0;
}
else
{
/* reap/cleanup the failed process */ /* reap/cleanup the failed process */
process_cleanup(hProcess); process_cleanup (hProcess);
/* close handles which were duplicated, they weren't used */ /* close handles which were duplicated, they weren't used */
if (hIn != INVALID_HANDLE_VALUE) if (hIn != INVALID_HANDLE_VALUE)
CloseHandle(hIn); CloseHandle (hIn);
if (hErr != INVALID_HANDLE_VALUE) if (hErr != INVALID_HANDLE_VALUE)
CloseHandle(hErr); CloseHandle (hErr);
/* close pipe handles, they won't be used */ /* close pipe handles, they won't be used */
CloseHandle(hChildOutRd); CloseHandle (hChildOutRd);
CloseHandle(hChildOutWr); CloseHandle (hChildOutWr);
/* set status for return */ return -1;
pipedes[0] = pipedes[1] = -1;
*pid_p = (pid_t)-1;
} }
} }
#endif #endif
@@ -1613,6 +1609,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
{ {
fprintf (stderr, "This platform does not support shell\n"); fprintf (stderr, "This platform does not support shell\n");
die (EXIT_FAILURE); die (EXIT_FAILURE);
return NULL;
} }
#define func_shell 0 #define func_shell 0
@@ -1623,7 +1620,7 @@ char *
func_shell_base (char *o, char **argv, int trim_newlines) func_shell_base (char *o, char **argv, int trim_newlines)
{ {
char *batch_filename = NULL; char *batch_filename = NULL;
int errfd;
#ifdef __MSDOS__ #ifdef __MSDOS__
FILE *fpipe; FILE *fpipe;
#endif #endif
@@ -1639,9 +1636,9 @@ func_shell_base (char *o, char **argv, int trim_newlines)
are used to run the commands, because we normally refrain from are used to run the commands, because we normally refrain from
creating batch files under -n. */ creating batch files under -n. */
int j_p_f = just_print_flag; int j_p_f = just_print_flag;
just_print_flag = 0; just_print_flag = 0;
#endif #endif
/* Construct the argument list. */ /* Construct the argument list. */
command_argv = construct_command_argv (argv[0], NULL, NULL, 0, command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
&batch_filename); &batch_filename);
@@ -1656,14 +1653,14 @@ func_shell_base (char *o, char **argv, int trim_newlines)
/* Using a target environment for 'shell' loses in cases like: /* Using a target environment for 'shell' loses in cases like:
export var = $(shell echo foobie) export var = $(shell echo foobie)
because target_environment hits a loop trying to expand $(var) bad := $(var)
to put it in the environment. This is even more confusing when because target_environment hits a loop trying to expand $(var) to put it
var was not explicitly exported, but just appeared in the in the environment. This is even more confusing when 'var' was not
calling environment. explicitly exported, but just appeared in the calling environment.
See Savannah bug #10593. See Savannah bug #10593.
envp = target_environment (NILF); envp = target_environment (NULL);
*/ */
envp = environ; envp = environ;
@@ -1678,6 +1675,12 @@ func_shell_base (char *o, char **argv, int trim_newlines)
else else
error_prefix = ""; error_prefix = "";
/* Set up the output in case the shell writes something. */
output_start ();
errfd = (output_context && output_context->err >= 0
? output_context->err : FD_STDERR);
#if defined(__MSDOS__) #if defined(__MSDOS__)
fpipe = msdos_openpipe (pipedes, &pid, argv[0]); fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
if (pipedes[0] < 0) if (pipedes[0] < 0)
@@ -1694,6 +1697,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
{ {
/* Open of the pipe failed, mark as failed execution. */ /* Open of the pipe failed, mark as failed execution. */
shell_function_completed = -1; shell_function_completed = -1;
perror_with_name (error_prefix, "pipe");
return o; return o;
} }
else else
@@ -1709,7 +1713,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
CLOSE_ON_EXEC(pipedes[1]); CLOSE_ON_EXEC(pipedes[1]);
CLOSE_ON_EXEC(pipedes[0]); CLOSE_ON_EXEC(pipedes[0]);
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */ /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
pid = child_execute_job (0, pipedes[1], command_argv, envp); pid = child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
if (pid < 0) if (pid < 0)
perror_with_name (error_prefix, "spawn"); perror_with_name (error_prefix, "spawn");
# else /* ! __EMX__ */ # else /* ! __EMX__ */
@@ -1717,7 +1721,14 @@ func_shell_base (char *o, char **argv, int trim_newlines)
if (pid < 0) if (pid < 0)
perror_with_name (error_prefix, "fork"); perror_with_name (error_prefix, "fork");
else if (pid == 0) else if (pid == 0)
child_execute_job (0, pipedes[1], command_argv, envp); {
# ifdef SET_STACK_SIZE
/* Reset limits, if necessary. */
if (stack_limit.rlim_cur)
setrlimit (RLIMIT_STACK, &stack_limit);
# endif
child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
}
else else
# endif # endif
#endif #endif
@@ -1776,7 +1787,8 @@ func_shell_base (char *o, char **argv, int trim_newlines)
while (shell_function_completed == 0) while (shell_function_completed == 0)
reap_children (1, 0); reap_children (1, 0);
if (batch_filename) { if (batch_filename)
{
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"), DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename)); batch_filename));
remove (batch_filename); remove (batch_filename);
@@ -1844,7 +1856,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
return o; return o;
/* Note the mktemp() is a security hole, but this only runs on Amiga. /* Note the mktemp() is a security hole, but this only runs on Amiga.
Ideally we would use main.c:open_tmpfile(), but this uses a special Ideally we would use output_tmpfile(), but this uses a special
Open(), not fopen(), and I'm not familiar enough with the code to mess Open(), not fopen(), and I'm not familiar enough with the code to mess
with it. */ with it. */
strcpy (tmp_output, "t:MakeshXXXXXXXX"); strcpy (tmp_output, "t:MakeshXXXXXXXX");
@@ -1908,7 +1920,7 @@ func_shell (char *o, char **argv, const char *funcname UNUSED)
#ifdef EXPERIMENTAL #ifdef EXPERIMENTAL
/* /*
equality. Return is string-boolean, ie, the empty string is false. equality. Return is string-boolean, i.e., the empty string is false.
*/ */
static char * static char *
func_eq (char *o, char **argv, char *funcname UNUSED) func_eq (char *o, char **argv, char *funcname UNUSED)
@@ -1937,8 +1949,12 @@ func_not (char *o, char **argv, char *funcname UNUSED)
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
#define IS_ABSOLUTE(n) (n[0] && n[1] == ':') # ifdef __CYGWIN__
#define ROOT_LEN 3 # define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_PATHSEP))
# else
# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
# endif
# define ROOT_LEN 3
#else #else
#define IS_ABSOLUTE(n) (n[0] == '/') #define IS_ABSOLUTE(n) (n[0] == '/')
#define ROOT_LEN 1 #define ROOT_LEN 1
@@ -1968,9 +1984,9 @@ abspath (const char *name, char *apath)
strcpy (apath, starting_directory); strcpy (apath, starting_directory);
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
if (IS_PATHSEP(name[0])) if (STOP_SET (name[0], MAP_PATHSEP))
{ {
if (IS_PATHSEP(name[1])) if (STOP_SET (name[1], MAP_PATHSEP))
{ {
/* A UNC. Don't prepend a drive letter. */ /* A UNC. Don't prepend a drive letter. */
apath[0] = name[0]; apath[0] = name[0];
@@ -1989,13 +2005,17 @@ abspath (const char *name, char *apath)
} }
else else
{ {
#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
if (STOP_SET (name[0], MAP_PATHSEP))
root_len = 1;
#endif
strncpy (apath, name, root_len); strncpy (apath, name, root_len);
apath[root_len] = '\0'; apath[root_len] = '\0';
dest = apath + root_len; dest = apath + root_len;
/* Get past the root, since we already copied it. */ /* Get past the root, since we already copied it. */
name += root_len; name += root_len;
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
if (!IS_PATHSEP(apath[2])) if (! STOP_SET (apath[root_len - 1], MAP_PATHSEP))
{ {
/* Convert d:foo into d:./foo and increase root_len. */ /* Convert d:foo into d:./foo and increase root_len. */
apath[2] = '.'; apath[2] = '.';
@@ -2006,7 +2026,7 @@ abspath (const char *name, char *apath)
name--; name--;
} }
else else
apath[2] = '/'; /* make sure it's a forward slash */ apath[root_len - 1] = '/'; /* make sure it's a forward slash */
#endif #endif
} }
@@ -2015,11 +2035,11 @@ abspath (const char *name, char *apath)
unsigned long len; unsigned long len;
/* Skip sequence of multiple path-separators. */ /* Skip sequence of multiple path-separators. */
while (IS_PATHSEP(*start)) while (STOP_SET (*start, MAP_PATHSEP))
++start; ++start;
/* Find end of path component. */ /* Find end of path component. */
for (end = start; *end != '\0' && !IS_PATHSEP(*end); ++end) for (end = start; ! STOP_SET (*end, MAP_PATHSEP|MAP_NUL); ++end)
; ;
len = end - start; len = end - start;
@@ -2032,11 +2052,12 @@ abspath (const char *name, char *apath)
{ {
/* Back up to previous component, ignore if at root already. */ /* Back up to previous component, ignore if at root already. */
if (dest > apath + root_len) if (dest > apath + root_len)
for (--dest; !IS_PATHSEP(dest[-1]); --dest); for (--dest; ! STOP_SET (dest[-1], MAP_PATHSEP); --dest)
;
} }
else else
{ {
if (!IS_PATHSEP(dest[-1])) if (! STOP_SET (dest[-1], MAP_PATHSEP))
*dest++ = '/'; *dest++ = '/';
if (dest + len >= apath_limit) if (dest + len >= apath_limit)
@@ -2049,7 +2070,7 @@ abspath (const char *name, char *apath)
} }
/* Unless it is root strip trailing separator. */ /* Unless it is root strip trailing separator. */
if (dest > apath + root_len && IS_PATHSEP(dest[-1])) if (dest > apath + root_len && STOP_SET (dest[-1], MAP_PATHSEP))
--dest; --dest;
*dest = '\0'; *dest = '\0';
@@ -2066,24 +2087,30 @@ func_realpath (char *o, char **argv, const char *funcname UNUSED)
const char *path = 0; const char *path = 0;
int doneany = 0; int doneany = 0;
unsigned int len = 0; unsigned int len = 0;
struct stat st;
PATH_VAR (in);
PATH_VAR (out);
while ((path = find_next_token (&p, &len)) != 0) while ((path = find_next_token (&p, &len)) != 0)
{ {
if (len < GET_PATH_MAX) if (len < GET_PATH_MAX)
{ {
char *rp;
struct stat st;
PATH_VAR (in);
PATH_VAR (out);
strncpy (in, path, len); strncpy (in, path, len);
in[len] = '\0'; in[len] = '\0';
if (
#ifdef HAVE_REALPATH #ifdef HAVE_REALPATH
realpath (in, out) ENULLLOOP (rp, realpath (in, out));
#else #else
abspath (in, out) rp = abspath (in, out);
#endif #endif
&& stat (out, &st) == 0)
if (rp)
{
int r;
EINTRLOOP (r, stat (out, &st));
if (r == 0)
{ {
o = variable_buffer_output (o, out, strlen (out)); o = variable_buffer_output (o, out, strlen (out));
o = variable_buffer_output (o, " ", 1); o = variable_buffer_output (o, " ", 1);
@@ -2091,6 +2118,7 @@ func_realpath (char *o, char **argv, const char *funcname UNUSED)
} }
} }
} }
}
/* Kill last space. */ /* Kill last space. */
if (doneany) if (doneany)
@@ -2126,7 +2154,7 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
int l = strlen (argv[1]); int l = strlen (argv[1]);
int nl = (l == 0 || argv[1][l-1] != '\n'); int nl = (l == 0 || argv[1][l-1] != '\n');
if (fputs (argv[1], fp) == EOF || (nl && fputc('\n', fp) == EOF)) if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
fatal (reading_file, _("write: %s: %s"), fn, strerror (errno)); fatal (reading_file, _("write: %s: %s"), fn, strerror (errno));
fclose (fp); fclose (fp);
@@ -2146,13 +2174,14 @@ func_abspath (char *o, char **argv, const char *funcname UNUSED)
const char *path = 0; const char *path = 0;
int doneany = 0; int doneany = 0;
unsigned int len = 0; unsigned int len = 0;
PATH_VAR (in);
PATH_VAR (out);
while ((path = find_next_token (&p, &len)) != 0) while ((path = find_next_token (&p, &len)) != 0)
{ {
if (len < GET_PATH_MAX) if (len < GET_PATH_MAX)
{ {
PATH_VAR (in);
PATH_VAR (out);
strncpy (in, path, len); strncpy (in, path, len);
in[len] = '\0'; in[len] = '\0';
@@ -2186,49 +2215,51 @@ func_abspath (char *o, char **argv, const char *funcname UNUSED)
static char *func_call (char *o, char **argv, const char *funcname); static char *func_call (char *o, char **argv, const char *funcname);
#define FT_ENTRY(_name, _min, _max, _exp, _func) \
{ { (_func) }, STRING_SIZE_TUPLE(_name), (_min), (_max), (_exp), 0 }
static struct function_table_entry function_table_init[] = static struct function_table_entry function_table_init[] =
{ {
/* Name/size */ /* MIN MAX EXP? Function */ /* Name MIN MAX EXP? Function */
{ STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath}, FT_ENTRY ("abspath", 0, 1, 1, func_abspath),
{ STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, FT_ENTRY ("addprefix", 2, 2, 1, func_addsuffix_addprefix),
{ STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, FT_ENTRY ("addsuffix", 2, 2, 1, func_addsuffix_addprefix),
{ STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir}, FT_ENTRY ("basename", 0, 1, 1, func_basename_dir),
{ STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir}, FT_ENTRY ("dir", 0, 1, 1, func_basename_dir),
{ STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix}, FT_ENTRY ("notdir", 0, 1, 1, func_notdir_suffix),
{ STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst}, FT_ENTRY ("subst", 3, 3, 1, func_subst),
{ STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix}, FT_ENTRY ("suffix", 0, 1, 1, func_notdir_suffix),
{ STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout}, FT_ENTRY ("filter", 2, 2, 1, func_filter_filterout),
{ STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout}, FT_ENTRY ("filter-out", 2, 2, 1, func_filter_filterout),
{ STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring}, FT_ENTRY ("findstring", 2, 2, 1, func_findstring),
{ STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword}, FT_ENTRY ("firstword", 0, 1, 1, func_firstword),
{ STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor}, FT_ENTRY ("flavor", 0, 1, 1, func_flavor),
{ STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, FT_ENTRY ("join", 2, 2, 1, func_join),
{ STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword}, FT_ENTRY ("lastword", 0, 1, 1, func_lastword),
{ STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, FT_ENTRY ("patsubst", 3, 3, 1, func_patsubst),
{ STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath}, FT_ENTRY ("realpath", 0, 1, 1, func_realpath),
{ STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, FT_ENTRY ("shell", 0, 1, 1, func_shell),
{ STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, FT_ENTRY ("sort", 0, 1, 1, func_sort),
{ STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip}, FT_ENTRY ("strip", 0, 1, 1, func_strip),
{ STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard}, FT_ENTRY ("wildcard", 0, 1, 1, func_wildcard),
{ STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word}, FT_ENTRY ("word", 2, 2, 1, func_word),
{ STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist}, FT_ENTRY ("wordlist", 3, 3, 1, func_wordlist),
{ STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words}, FT_ENTRY ("words", 0, 1, 1, func_words),
{ STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin}, FT_ENTRY ("origin", 0, 1, 1, func_origin),
{ STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach}, FT_ENTRY ("foreach", 3, 3, 0, func_foreach),
{ STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call}, FT_ENTRY ("call", 1, 0, 1, func_call),
{ STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error}, FT_ENTRY ("info", 0, 1, 1, func_error),
{ STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error}, FT_ENTRY ("error", 0, 1, 1, func_error),
{ STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error}, FT_ENTRY ("warning", 0, 1, 1, func_error),
{ STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if}, FT_ENTRY ("if", 2, 3, 0, func_if),
{ STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or}, FT_ENTRY ("or", 1, 0, 0, func_or),
{ STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and}, FT_ENTRY ("and", 1, 0, 0, func_and),
{ STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value}, FT_ENTRY ("value", 0, 1, 1, func_value),
{ STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval}, FT_ENTRY ("eval", 0, 1, 1, func_eval),
{ STRING_SIZE_TUPLE("file"), 1, 2, 1, func_file}, FT_ENTRY ("file", 1, 2, 1, func_file),
#ifdef EXPERIMENTAL #ifdef EXPERIMENTAL
{ STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq}, FT_ENTRY ("eq", 2, 2, 1, func_eq),
{ STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, FT_ENTRY ("not", 0, 1, 1, func_not),
#endif #endif
}; };
@@ -2241,23 +2272,38 @@ static char *
expand_builtin_function (char *o, int argc, char **argv, expand_builtin_function (char *o, int argc, char **argv,
const struct function_table_entry *entry_p) const struct function_table_entry *entry_p)
{ {
char *p;
if (argc < (int)entry_p->minimum_args) if (argc < (int)entry_p->minimum_args)
fatal (*expanding_var, fatal (*expanding_var,
_("insufficient number of arguments (%d) to function '%s'"), _("insufficient number of arguments (%d) to function '%s'"),
argc, entry_p->name); argc, entry_p->name);
/* I suppose technically some function could do something with no /* I suppose technically some function could do something with no arguments,
arguments, but so far none do, so just test it for all functions here but so far no internal ones do, so just test it for all functions here
rather than in each one. We can change it later if necessary. */ rather than in each one. We can change it later if necessary. */
if (!argc) if (!argc && !entry_p->alloc_fn)
return o; return o;
if (!entry_p->func_ptr) if (!entry_p->fptr.func_ptr)
fatal (*expanding_var, fatal (*expanding_var,
_("unimplemented on this platform: function '%s'"), entry_p->name); _("unimplemented on this platform: function '%s'"), entry_p->name);
return entry_p->func_ptr (o, argv, entry_p->name); if (!entry_p->alloc_fn)
return entry_p->fptr.func_ptr (o, argv, entry_p->name);
/* This function allocates memory and returns it to us.
Write it to the variable buffer, then free it. */
p = entry_p->fptr.alloc_func_ptr (entry_p->name, argc, argv);
if (p)
{
o = variable_buffer_output (o, p, strlen (p));
free (p);
}
return o;
} }
/* Check for a function invocation in *STRINGP. *STRINGP points at the /* Check for a function invocation in *STRINGP. *STRINGP points at the
@@ -2399,7 +2445,7 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
/* There is no way to define a variable with a space in the name, so strip /* There is no way to define a variable with a space in the name, so strip
leading and trailing whitespace as a favor to the user. */ leading and trailing whitespace as a favor to the user. */
fname = argv[0]; fname = argv[0];
while (*fname != '\0' && isspace ((unsigned char)*fname)) while (isspace ((unsigned char)*fname))
++fname; ++fname;
cp = fname + strlen (fname) - 1; cp = fname + strlen (fname) - 1;
@@ -2484,28 +2530,39 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
} }
void void
define_new_function(const struct floc *flocp, define_new_function (const gmk_floc *flocp, const char *name,
const char *name, int min, int max, int expand, unsigned int min, unsigned int max, unsigned int flags,
char *(*func)(char *, char **, const char *)) gmk_func_ptr func)
{ {
size_t len = strlen (name); const char *e = name;
struct function_table_entry *ent = xmalloc (sizeof (struct function_table_entry)); struct function_table_entry *ent;
size_t len;
while (STOP_SET (*e, MAP_USERFUNC))
e++;
len = e - name;
if (len == 0)
fatal (flocp, _("Empty function name\n"));
if (*name == '.' || *e != '\0')
fatal (flocp, _("Invalid function name: %s\n"), name);
if (len > 255) if (len > 255)
fatal (flocp, _("Function name too long: %s\n"), name); fatal (flocp, _("Function name too long: %s\n"), name);
if (min < 0 || min > 255) if (min > 255)
fatal (flocp, _("Invalid minimum argument count (%d) for function %s\n"), fatal (flocp, _("Invalid minimum argument count (%d) for function %s\n"),
min, name); min, name);
if (max < 0 || max > 255 || max < min) if (max > 255 || (max && max < min))
fatal (flocp, _("Invalid maximum argument count (%d) for function %s\n"), fatal (flocp, _("Invalid maximum argument count (%d) for function %s\n"),
max, name); max, name);
ent = xmalloc (sizeof (struct function_table_entry));
ent->name = name; ent->name = name;
ent->len = len; ent->len = len;
ent->minimum_args = min; ent->minimum_args = min;
ent->maximum_args = max; ent->maximum_args = max;
ent->expand_args = expand ? 1 : 0; ent->expand_args = ANY_SET(flags, GMK_FUNC_NOEXPAND) ? 0 : 1;
ent->func_ptr = func; ent->alloc_fn = 1;
ent->fptr.alloc_func_ptr = func;
hash_insert (&function_table, ent); hash_insert (&function_table, ent);
} }

View File

@@ -1,5 +1,5 @@
/* Get the system load averages. /* Get the system load averages.
Copyright (C) 1985-2012 Free Software Foundation, Inc. Copyright (C) 1985-2013 Free Software Foundation, Inc.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software terms of the GNU General Public License as published by the Free Software
@@ -985,7 +985,7 @@ getloadavg (double loadavg[], int nelem)
#endif /* ! HAVE_GETLOADAVG */ #endif /* ! HAVE_GETLOADAVG */
#ifdef TEST #ifdef TEST
#include "make.h" #include "makeint.h"
int int
main (int argc, char **argv) main (int argc, char **argv)

View File

@@ -3,7 +3,7 @@ NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to drepper@gnu.org "Keep this file name-space clean" means, talk to drepper@gnu.org
before changing it! before changing it!
Copyright (C) 1987-2012 Free Software Foundation, Inc. Copyright (C) 1987-2013 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library. NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org. Bugs can be reported to bug-glibc@gnu.org.

View File

@@ -1,5 +1,5 @@
/* Declarations for getopt. /* Declarations for getopt.
Copyright (C) 1989-2012 Free Software Foundation, Inc. Copyright (C) 1989-2013 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library. NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org. Bugs can be reported to bug-glibc@gnu.org.

View File

@@ -1,5 +1,5 @@
/* getopt_long and getopt_long_only entry points for GNU getopt. /* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987-1994, 1996-2012 Free Software Foundation, Inc. Copyright (C) 1987-1994, 1996-2013 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library. NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org. Bugs can be reported to bug-glibc@gnu.org.

View File

@@ -1,5 +1,5 @@
/* Convenience header for conditional use of GNU <libintl.h>. /* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-2012 Free Software Foundation, Inc. Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,2 +0,0 @@
Makefile Makefile.in
.deps

View File

@@ -56,7 +56,7 @@ typedef __SIZE_TYPE__ __size_t;
# else # else
/* This is a guess. */ /* This is a guess. */
/*hb /*hb
* Conflicts with DECCs aready defined type __size_t. * Conflicts with DECCs already defined type __size_t.
* Defining an own type with a name beginning with '__' is no good. * Defining an own type with a name beginning with '__' is no good.
* Anyway if DECC is used and __SIZE_T is defined then __size_t is * Anyway if DECC is used and __SIZE_T is defined then __size_t is
* already defined (and I hope it's exactly the one we need here). * already defined (and I hope it's exactly the one we need here).

View File

@@ -1,5 +1,5 @@
;; Contents of the (gnu make) Guile module ;; Contents of the (gnu make) Guile module
;; Copyright (C) 2011-2012 Free Software Foundation, Inc. ;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
;; This file is part of GNU Make. ;; This file is part of GNU Make.
;; ;;
;; GNU Make is free software; you can redistribute it and/or modify it under ;; GNU Make is free software; you can redistribute it and/or modify it under
@@ -45,10 +45,6 @@
(walk x) (walk x)
(string-join (reverse! acc)))) (string-join (reverse! acc))))
;; eval (GNU make eval) the input string S
(define (gmk-eval s)
(gmk-expand (format #f "$(eval ~a)" (obj-to-str s))))
;; Return the value of the GNU make variable V ;; Return the value of the GNU make variable V
(define (gmk-var v) (define (gmk-var v)
(gmk-expand (format #f "$(~a)" (obj-to-str v)))) (gmk-expand (format #f "$(~a)" (obj-to-str v))))

79
gnumake.h Normal file
View File

@@ -0,0 +1,79 @@
/* External interfaces usable by dynamic objects loaded into GNU Make.
--THIS API IS A "TECHNOLOGY PREVIEW" ONLY. IT IS NOT A STABLE INTERFACE--
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _GNUMAKE_H_
#define _GNUMAKE_H_
/* Specify the location of elements read from makefiles. */
typedef struct
{
const char *filenm;
unsigned long lineno;
} gmk_floc;
typedef char *(*gmk_func_ptr)(const char *nm, unsigned int argc, char **argv);
#ifdef _WIN32
# ifdef GMK_BUILDING_MAKE
# define GMK_EXPORT __declspec(dllexport)
# else
# define GMK_EXPORT __declspec(dllimport)
# endif
#else
# define GMK_EXPORT
#endif
/* Free memory returned by the gmk_expand() function. */
GMK_EXPORT void gmk_free (char *str);
/* Allocate memory in GNU make's context. */
GMK_EXPORT char *gmk_alloc (unsigned int len);
/* Run $(eval ...) on the provided string BUFFER. */
GMK_EXPORT void gmk_eval (const char *buffer, const gmk_floc *floc);
/* Run GNU make expansion on the provided string STR.
Returns an allocated buffer that the caller must free with gmk_free(). */
GMK_EXPORT char *gmk_expand (const char *str);
/* Register a new GNU make function NAME (maximum of 255 chars long).
When the function is expanded in the makefile, FUNC will be invoked with
the appropriate arguments.
The return value of FUNC must be either NULL, in which case it expands to
the empty string, or a pointer to the result of the expansion in a string
created by gmk_alloc(). GNU make will free the memory when it's done.
MIN_ARGS is the minimum number of arguments the function requires.
MAX_ARGS is the maximum number of arguments (or 0 if there's no maximum).
MIN_ARGS and MAX_ARGS may not exceed 255.
The FLAGS value may be GMK_FUNC_DEFAULT, or one or more of the following
flags OR'd together:
GMK_FUNC_NOEXPAND: the arguments to the function will be not be expanded
before FUNC is called.
*/
GMK_EXPORT void gmk_add_function (const char *name, gmk_func_ptr func,
unsigned int min_args, unsigned int max_args,
unsigned int flags);
#define GMK_FUNC_DEFAULT 0x00
#define GMK_FUNC_NOEXPAND 0x01
#endif /* _GNUMAKE_H_ */

65
guile.c
View File

@@ -1,5 +1,5 @@
/* GNU Guile interface for GNU Make. /* GNU Guile interface for GNU Make.
Copyright (C) 2011-2012 Free Software Foundation, Inc. Copyright (C) 2011-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,13 +14,26 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "gnumake.h"
#include "debug.h" #include "debug.h"
#include "filedef.h"
#include "dep.h" #include "dep.h"
#include "variable.h" #include "variable.h"
#include <libguile.h> #include <libguile.h>
/* Pre-2.0 versions of Guile don't have a typedef for gsubr function types. */
#if SCM_MAJOR_VERSION < 2
# define GSUBR_TYPE SCM (*) ()
/* Guile 1.x doesn't really support i18n. */
# define EVAL_STRING(_s) scm_c_eval_string (_s)
#else
# define GSUBR_TYPE scm_t_subr
# define EVAL_STRING(_s) scm_eval_string (scm_from_utf8_string (_s))
#endif
static SCM make_mod = SCM_EOL; static SCM make_mod = SCM_EOL;
static SCM obj_to_str = SCM_EOL; static SCM obj_to_str = SCM_EOL;
@@ -40,7 +53,7 @@ guile_expand_wrapper (SCM obj)
char *res; char *res;
DB (DB_BASIC, (_("guile: Expanding '%s'\n"), str)); DB (DB_BASIC, (_("guile: Expanding '%s'\n"), str));
res = allocated_variable_expand (str); res = gmk_expand (str);
ret = scm_from_locale_string (res); ret = scm_from_locale_string (res);
free (str); free (str);
@@ -49,6 +62,18 @@ guile_expand_wrapper (SCM obj)
return ret; return ret;
} }
/* Perform the GNU make eval function. */
static SCM
guile_eval_wrapper (SCM obj)
{
char *str = cvt_scm_to_str (obj);
DB (DB_BASIC, (_("guile: Evaluating '%s'\n"), str));
gmk_eval (str, 0);
return SCM_BOOL_F;
}
/* Invoked by scm_c_define_module(), in the context of the GNU make module. */ /* Invoked by scm_c_define_module(), in the context of the GNU make module. */
static void static void
guile_define_module (void *data UNUSED) guile_define_module (void *data UNUSED)
@@ -57,7 +82,10 @@ guile_define_module (void *data UNUSED)
#include "gmk-default.h" #include "gmk-default.h"
/* Register a subr for GNU make's eval capability. */ /* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, guile_expand_wrapper); scm_c_define_gsubr ("gmk-expand", 1, 0, 0, (GSUBR_TYPE) guile_expand_wrapper);
/* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, (GSUBR_TYPE) guile_eval_wrapper);
/* Define the rest of the module. */ /* Define the rest of the module. */
scm_c_eval_string (GUILE_module_defn); scm_c_eval_string (GUILE_module_defn);
@@ -82,24 +110,26 @@ guile_init (void *arg UNUSED)
static void * static void *
internal_guile_eval (void *arg) internal_guile_eval (void *arg)
{ {
return cvt_scm_to_str (scm_c_eval_string (arg)); return cvt_scm_to_str (EVAL_STRING (arg));
} }
/* This is the function registered with make */ /* This is the function registered with make */
static char * static char *
func_guile (char *o, char **argv, const char *funcname UNUSED) func_guile (const char *funcname UNUSED, unsigned int argc UNUSED, char **argv)
{ {
if (argv[0] && argv[0][0] != '\0') static int init = 0;
if (! init)
{ {
char *str = scm_with_guile (internal_guile_eval, argv[0]); /* Initialize the Guile interpreter. */
if (str) scm_with_guile (guile_init, NULL);
{ init = 1;
o = variable_buffer_output (o, str, strlen (str));
free (str);
}
} }
return o; if (argv[0] && argv[0][0] != '\0')
return scm_with_guile (internal_guile_eval, argv[0]);
return NULL;
} }
/* ----- Public interface ----- */ /* ----- Public interface ----- */
@@ -107,13 +137,10 @@ func_guile (char *o, char **argv, const char *funcname UNUSED)
/* We could send the flocp to define_new_function(), but since guile is /* We could send the flocp to define_new_function(), but since guile is
"kind of" built-in, that didn't seem so useful. */ "kind of" built-in, that didn't seem so useful. */
int int
guile_gmake_setup (const struct floc *flocp UNUSED) guile_gmake_setup (const gmk_floc *flocp UNUSED)
{ {
/* Initialize the Guile interpreter. */
scm_with_guile (guile_init, NULL);
/* Create a make function "guile". */ /* Create a make function "guile". */
define_new_function (NILF, "guile", 0, 1, 1, func_guile); gmk_add_function ("guile", func_guile, 0, 1, GMK_FUNC_DEFAULT);
return 1; return 1;
} }

4
hash.c
View File

@@ -14,10 +14,10 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "hash.h" #include "hash.h"
#define CALLOC(t, n) ((t *) calloc (sizeof (t), (n))) #define CALLOC(t, n) ((t *) xcalloc (sizeof (t) * (n)))
#define MALLOC(t, n) ((t *) xmalloc (sizeof (t) * (n))) #define MALLOC(t, n) ((t *) xmalloc (sizeof (t) * (n)))
#define REALLOC(o, t, n) ((t *) xrealloc ((o), sizeof (t) * (n))) #define REALLOC(o, t, n) ((t *) xrealloc ((o), sizeof (t) * (n)))
#define CLONE(o, t, n) ((t *) memcpy (MALLOC (t, (n)), (o), sizeof (t) * (n))) #define CLONE(o, t, n) ((t *) memcpy (MALLOC (t, (n)), (o), sizeof (t) * (n)))

View File

@@ -1,5 +1,5 @@
/* Implicit rule searching for GNU Make. /* Implicit rule searching for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "filedef.h" #include "filedef.h"
#include "rule.h" #include "rule.h"
#include "dep.h" #include "dep.h"
@@ -217,13 +217,10 @@ pattern_search (struct file *file, int archive,
struct file *int_file = 0; struct file *int_file = 0;
/* List of dependencies found recursively. */ /* List of dependencies found recursively. */
struct patdeps *deplist unsigned int max_deps = max_pattern_deps;
= xmalloc (max_pattern_deps * sizeof (struct patdeps)); struct patdeps *deplist = xmalloc (max_deps * sizeof (struct patdeps));
struct patdeps *pat = deplist; struct patdeps *pat = deplist;
/* All the prerequisites actually found for a rule, after expansion. */
struct dep *deps;
/* Names of possible dependencies are constructed in this buffer. */ /* Names of possible dependencies are constructed in this buffer. */
char *depname = alloca (namelen + max_pattern_dep_length); char *depname = alloca (namelen + max_pattern_dep_length);
@@ -252,8 +249,6 @@ pattern_search (struct file *file, int archive,
that is not just '%'. */ that is not just '%'. */
int specific_rule_matched = 0; int specific_rule_matched = 0;
struct dep dep_simple;
unsigned int ri; /* uninit checks OK */ unsigned int ri; /* uninit checks OK */
struct rule *rule; struct rule *rule;
@@ -535,11 +530,9 @@ pattern_search (struct file *file, int archive,
/* If we don't need a second expansion, just replace the %. */ /* If we don't need a second expansion, just replace the %. */
if (! dep->need_2nd_expansion) if (! dep->need_2nd_expansion)
{ {
dep_simple = *dep;
dep_simple.next = 0;
p = strchr (nptr, '%'); p = strchr (nptr, '%');
if (p == 0) if (p == 0)
dep_simple.name = nptr; strcpy (depname, nptr);
else else
{ {
char *o = depname; char *o = depname;
@@ -553,13 +546,19 @@ pattern_search (struct file *file, int archive,
memcpy (o, stem_str, stemlen); memcpy (o, stem_str, stemlen);
o += stemlen; o += stemlen;
strcpy (o, p + 1); strcpy (o, p + 1);
dep_simple.name = strcache_add (depname);
} }
dl = &dep_simple;
/* Parse the expanded string. It might have wildcards. */
p = depname;
dl = PARSE_SIMPLE_SEQ (&p, struct dep);
for (d = dl; d != NULL; d = d->next)
{
++deps_found;
d->ignore_mtime = dep->ignore_mtime;
}
/* We've used up this dep, so next time get a new one. */ /* We've used up this dep, so next time get a new one. */
nptr = 0; nptr = 0;
++deps_found;
} }
/* We have to perform second expansion on this prereq. In an /* We have to perform second expansion on this prereq. In an
@@ -575,6 +574,7 @@ pattern_search (struct file *file, int archive,
{ {
int add_dir = 0; int add_dir = 0;
unsigned int len; unsigned int len;
struct dep **dptr;
nptr = get_next_word (nptr, &len); nptr = get_next_word (nptr, &len);
if (nptr == 0) if (nptr == 0)
@@ -617,6 +617,9 @@ pattern_search (struct file *file, int archive,
add_dir = 1; add_dir = 1;
} }
/* Set up for the next word. */
nptr += len;
/* Initialize and set file variables if we haven't already /* Initialize and set file variables if we haven't already
done so. */ done so. */
if (!file_vars_initialized) if (!file_vars_initialized)
@@ -635,32 +638,47 @@ pattern_search (struct file *file, int archive,
/* Perform the 2nd expansion. */ /* Perform the 2nd expansion. */
p = variable_expand_for_file (depname, file); p = variable_expand_for_file (depname, file);
dptr = &dl;
/* Parse the results into a deps list. */
do
{
/* Parse the expanded string. */ /* Parse the expanded string. */
dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? '\0' : '|', struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
add_dir ? dir : NULL, 0); order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, PARSEFS_NONE);
*dptr = dp;
for (d = dl; d != NULL; d = d->next) for (d = dp; d != NULL; d = d->next)
{ {
++deps_found; ++deps_found;
if (order_only) if (order_only)
d->ignore_mtime = 1; d->ignore_mtime = 1;
dptr = &d->next;
} }
/* Set up for the next word. */ /* If we stopped due to an order-only token, note it. */
nptr += len; if (*p == '|')
{
order_only = 1;
++p;
}
}
while (*p != '\0');
} }
/* If there are more than max_pattern_deps prerequisites (due to /* If there are more than max_pattern_deps prerequisites (due to
2nd expansion), reset it and realloc the arrays. */ 2nd expansion), reset it and realloc the arrays. */
if (deps_found > max_pattern_deps) if (deps_found > max_deps)
{ {
unsigned int l = pat - deplist; unsigned int l = pat - deplist;
/* This might have changed due to recursion. */
max_pattern_deps = MAX(max_pattern_deps, deps_found);
max_deps = max_pattern_deps;
deplist = xrealloc (deplist, deplist = xrealloc (deplist,
deps_found * sizeof (struct patdeps)); max_deps * sizeof (struct patdeps));
pat = deplist + l; pat = deplist + l;
max_pattern_deps = deps_found;
} }
/* Go through the nameseq and handle each as a prereq name. */ /* Go through the nameseq and handle each as a prereq name. */
@@ -760,8 +778,8 @@ pattern_search (struct file *file, int archive,
pat->pattern = int_file->name; pat->pattern = int_file->name;
int_file->name = d->name; int_file->name = d->name;
pat->file = int_file; pat->file = int_file;
(pat++)->name = d->name;
int_file = 0; int_file = 0;
(pat++)->name = d->name;
continue; continue;
} }
@@ -782,7 +800,6 @@ pattern_search (struct file *file, int archive,
} }
/* Free the ns chain. */ /* Free the ns chain. */
if (dl != &dep_simple)
free_dep_chain (dl); free_dep_chain (dl);
if (failed) if (failed)
@@ -800,10 +817,7 @@ pattern_search (struct file *file, int archive,
/* This pattern rule does apply. Stop looking for one. */ /* This pattern rule does apply. Stop looking for one. */
break; break;
/* This pattern rule does not apply. If some of its dependencies /* This pattern rule does not apply. Keep looking. */
succeeded, free the data structure describing them. */
/* free_idep_chain (deps); */
deps = 0;
} }
/* If we found an applicable rule without intermediate files, don't try /* If we found an applicable rule without intermediate files, don't try

564
job.c

File diff suppressed because it is too large Load Diff

74
job.h
View File

@@ -1,5 +1,5 @@
/* Definitions for managing subprocesses in GNU Make. /* Definitions for managing subprocesses in GNU Make.
Copyright (C) 1992-2012 Free Software Foundation, Inc. Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,8 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef SEEN_JOB_H #include "output.h"
#define SEEN_JOB_H
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> # include <fcntl.h>
@@ -26,7 +25,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* How to set close-on-exec for a file descriptor. */ /* How to set close-on-exec for a file descriptor. */
#if !defined F_SETFD #if !defined F_SETFD
# ifdef WINDOWS32
# define CLOSE_ON_EXEC(_d) process_noinherit(_d)
# else
# define CLOSE_ON_EXEC(_d) # define CLOSE_ON_EXEC(_d)
# endif
#else #else
# ifndef FD_CLOEXEC # ifndef FD_CLOEXEC
# define FD_CLOEXEC 1 # define FD_CLOEXEC 1
@@ -34,6 +37,51 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC) # define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
#endif #endif
#ifdef NO_OUTPUT_SYNC
# define RECORD_SYNC_MUTEX(m) \
error (NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#else
# ifdef WINDOWS32
/* For emulations in w32/compat/posixfcn.c. */
# define F_GETFD 1
# define F_SETLKW 2
/* Implementation note: None of the values of l_type below can be zero
-- they are compared with a static instance of the struct, so zero
means unknown/invalid, see w32/compat/posixfcn.c. */
# define F_WRLCK 1
# define F_UNLCK 2
struct flock
{
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};
/* This type is actually a HANDLE, but we want to avoid including
windows.h as much as possible. */
typedef intptr_t sync_handle_t;
/* Public functions emulated/provided in posixfcn.c. */
int fcntl (intptr_t fd, int cmd, ...);
intptr_t create_mutex (void);
int same_stream (FILE *f1, FILE *f2);
# define RECORD_SYNC_MUTEX(m) record_sync_mutex(m)
void record_sync_mutex (const char *str);
void prepare_mutex_handle_string (intptr_t hdl);
# else /* !WINDOWS32 */
typedef int sync_handle_t; /* file descriptor */
# define RECORD_SYNC_MUTEX(m) (void)(m)
# endif
#endif /* !NO_OUTPUT_SYNC */
/* Structure describing a running or dead child process. */ /* Structure describing a running or dead child process. */
struct child struct child
@@ -54,6 +102,7 @@ struct child
#endif #endif
unsigned int command_line; /* Index into command_lines. */ unsigned int command_line; /* Index into command_lines. */
struct output output; /* Output for this child. */
pid_t pid; /* Child process's ID number. */ pid_t pid; /* Child process's ID number. */
unsigned int remote:1; /* Nonzero if executing remotely. */ unsigned int remote:1; /* Nonzero if executing remotely. */
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */ unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
@@ -73,17 +122,24 @@ char **construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char** batch_file); int cmd_flags, char** batch_file);
#ifdef VMS #ifdef VMS
int child_execute_job (char *argv, struct child *child); int child_execute_job (char *argv, struct child *child);
#elif defined(__EMX__)
int child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
#else #else
void child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp); # define FD_STDIN (fileno (stdin))
# define FD_STDOUT (fileno (stdout))
# define FD_STDERR (fileno (stderr))
# if defined(__EMX__)
int child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp);
# else
void child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp) __attribute__ ((noreturn));
# endif
#endif #endif
#ifdef _AMIGA #ifdef _AMIGA
void exec_command (char **argv); void exec_command (char **argv) __attribute__ ((noreturn));
#elif defined(__EMX__) #elif defined(__EMX__)
int exec_command (char **argv, char **envp); int exec_command (char **argv, char **envp);
#else #else
void exec_command (char **argv, char **envp); void exec_command (char **argv, char **envp) __attribute__ ((noreturn));
#endif #endif
extern unsigned int job_slots_used; extern unsigned int job_slots_used;
@@ -101,5 +157,3 @@ extern int fatal_signal_mask;
#endif #endif
extern unsigned int jobserver_tokens; extern unsigned int jobserver_tokens;
#endif /* SEEN_JOB_H */

215
load.c
View File

@@ -1,5 +1,5 @@
/* Loading dynamic objects for GNU Make. /* Loading dynamic objects for GNU Make.
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#if MAKE_LOAD #if MAKE_LOAD
@@ -24,76 +24,121 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
#define SYMBOL_EXTENSION "_gmake_setup" #define SYMBOL_EXTENSION "_gmk_setup"
static void *global_dl = NULL;
#include "debug.h" #include "debug.h"
#include "filedef.h" #include "filedef.h"
#include "variable.h" #include "variable.h"
static int struct load_list
init_symbol (const struct floc *flocp, const char *ldname, load_func_t symp) {
{ struct load_list *next;
int r; const char *name;
const char *p; void *dlp;
int nmlen = strlen (ldname); };
char *loaded = allocated_variable_expand("$(.LOADED)");
static struct load_list *loaded_syms = NULL;
/* If it's already been loaded don't do it again. */
p = strstr (loaded, ldname); static load_func_t
r = p && (p==loaded || p[-1]==' ') && (p[nmlen]=='\0' || p[nmlen]==' '); load_object (const gmk_floc *flocp, int noerror,
free (loaded); const char *ldname, const char *symname)
if (r)
return 1;
/* Now invoke the symbol. */
r = (*symp) (flocp);
/* If it succeeded, add the symbol to the loaded variable. */
if (r > 0)
do_variable_definition (flocp, ".LOADED", ldname, o_default, f_append, 0);
return r;
}
int
load_file (const struct floc *flocp, const char *ldname, int noerror)
{ {
static void *global_dl = NULL;
load_func_t symp; load_func_t symp;
const char *fp;
char *symname = NULL;
char *new = alloca (strlen (ldname) + CSTRLEN (SYMBOL_EXTENSION) + 1);
if (! global_dl) if (! global_dl)
{ {
global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL); global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
if (! global_dl) if (! global_dl)
fatal (flocp, _("Failed to open global symbol table: %s"), dlerror()); fatal (flocp, _("Failed to open global symbol table: %s"), dlerror ());
} }
/* If a symbol name was provided, use it. */ symp = (load_func_t) dlsym (global_dl, symname);
fp = strchr (ldname, '('); if (! symp)
{
struct load_list *new;
void *dlp = NULL;
/* If the path has no "/", try the current directory first. */
if (! strchr (ldname, '/')
#ifdef HAVE_DOS_PATHS
&& ! strchr (ldname, '\\')
#endif
)
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
/* If we haven't opened it yet, try the default search path. */
if (! dlp)
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
/* Still no? Then fail. */
if (! dlp)
{
if (noerror)
DB (DB_BASIC, ("%s", dlerror ()));
else
error (flocp, "%s", dlerror ());
return NULL;
}
/* Assert that the GPL license symbol is defined. */
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
ldname);
symp = (load_func_t) dlsym (dlp, symname);
if (! symp)
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, dlerror ());
/* Add this symbol to a trivial lookup table. This is not efficient but
it's highly unlikely we'll be loading lots of objects, and we only
need it to look them up on unload, if we rebuild them. */
new = xmalloc (sizeof (struct load_list));
new->name = xstrdup (ldname);
new->dlp = dlp;
new->next = loaded_syms;
loaded_syms = new;
}
return symp;
}
int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
{
int nmlen = strlen (*ldname);
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
char *symname = NULL;
char *loaded;
const char *fp;
int r;
load_func_t symp;
/* Break the input into an object file name and a symbol name. If no symbol
name was provided, compute one from the object file name. */
fp = strchr (*ldname, '(');
if (fp) if (fp)
{ {
const char *ep; const char *ep;
/* If there's an open paren, see if there's a close paren: if so use /* There's an open paren, so see if there's a close paren: if so use
that as the symbol name. We can't have whitespace: it would have that as the symbol name. We can't have whitespace: it would have
been chopped up before this function is called. */ been chopped up before this function is called. */
ep = strchr (fp+1, ')'); ep = strchr (fp+1, ')');
if (ep && ep[1] == '\0') if (ep && ep[1] == '\0')
{ {
int l = fp - ldname;; int l = fp - *ldname;;
++fp; ++fp;
if (fp == ep) if (fp == ep)
fatal (flocp, _("Empty symbol name for load: %s"), ldname); fatal (flocp, _("Empty symbol name for load: %s"), *ldname);
/* Make a copy of the ldname part. */ /* Make a copy of the ldname part. */
memcpy (new, ldname, l); memcpy (new, *ldname, l);
new[l] = '\0'; new[l] = '\0';
ldname = new; *ldname = new;
/* Make a copy of the symbol name part. */ /* Make a copy of the symbol name part. */
symname = new + l + 1; symname = new + l + 1;
@@ -102,14 +147,39 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
} }
} }
/* Add this name to the string cache so it can be reused later. */
*ldname = strcache_add (*ldname);
/* If this object has been loaded, we're done. */
loaded = allocated_variable_expand ("$(.LOADED)");
fp = strstr (loaded, *ldname);
r = fp && (fp==loaded || fp[-1]==' ') && (fp[nmlen]=='\0' || fp[nmlen]==' ');
free (loaded);
if (r)
return 1;
/* If we didn't find a symbol name yet, construct it from the ldname. */ /* If we didn't find a symbol name yet, construct it from the ldname. */
if (! symname) if (! symname)
{ {
char *p = new; char *p = new;
fp = strrchr (ldname, '/'); fp = strrchr (*ldname, '/');
#ifdef HAVE_DOS_PATHS
if (fp)
{
const char *fp2 = strchr (fp, '\\');
if (fp2 > fp)
fp = fp2;
}
else
fp = strrchr (*ldname, '\\');
/* The (improbable) case of d:foo. */
if (fp && *fp && fp[1] == ':')
fp++;
#endif
if (!fp) if (!fp)
fp = ldname; fp = *ldname;
else else
++fp; ++fp;
while (isalnum (*fp) || *fp == '_') while (isalnum (*fp) || *fp == '_')
@@ -118,35 +188,42 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
symname = new; symname = new;
} }
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, ldname)); DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname));
/* See if it's already defined. */ /* Load it! */
symp = (load_func_t) dlsym (global_dl, symname); symp = load_object (flocp, noerror, *ldname, symname);
if (! symp) {
void *dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
if (! dlp)
{
if (noerror)
DB (DB_BASIC, ("%s", dlerror()));
else
error (flocp, "%s", dlerror());
return 0;
}
symp = dlsym (dlp, symname);
if (! symp) if (! symp)
fatal (flocp, _("Failed to load symbol %s from %s: %s"), return 0;
symname, ldname, dlerror());
}
/* Invoke the symbol to initialize the loaded object. */ /* Invoke the symbol. */
return init_symbol(flocp, ldname, symp); r = (*symp) (flocp);
/* If it succeeded, add the load file to the loaded variable. */
if (r > 0)
do_variable_definition (flocp, ".LOADED", *ldname, o_default, f_append, 0);
return r;
}
void
unload_file (const char *name)
{
struct load_list *d;
for (d = loaded_syms; d != NULL; d = d->next)
if (streq (d->name, name) && d->dlp)
{
if (dlclose (d->dlp))
perror_with_name ("dlclose", d->name);
d->dlp = NULL;
break;
}
} }
#else #else
int int
load_file (const struct floc *flocp, const char *ldname, int noerror) load_file (const gmk_floc *flocp, const char **ldname, int noerror)
{ {
if (! noerror) if (! noerror)
fatal (flocp, _("The 'load' operation is not supported on this platform.")); fatal (flocp, _("The 'load' operation is not supported on this platform."));
@@ -154,4 +231,10 @@ load_file (const struct floc *flocp, const char *ldname, int noerror)
return 0; return 0;
} }
void
unload_file (const char *name)
{
fatal (NILF, "INTERNAL: Cannot unload when load is not supported!");
}
#endif /* MAKE_LOAD */ #endif /* MAKE_LOAD */

61
loadapi.c Normal file
View File

@@ -0,0 +1,61 @@
/* API for GNU Make dynamic objects.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
#include "variable.h"
#include "dep.h"
/* Allocate a buffer in our context, so we can free it. */
char *
gmk_alloc (unsigned int len)
{
return xmalloc (len);
}
/* Free a buffer returned by gmk_expand(). */
void
gmk_free (char *s)
{
free (s);
}
/* Evaluate a buffer as make syntax.
Ideally eval_buffer() will take const char *, but not yet. */
void
gmk_eval (const char *buffer, const gmk_floc *floc)
{
char *s = xstrdup (buffer);
eval_buffer (s, floc);
free (s);
}
/* Expand a string and return an allocated buffer.
Caller must call gmk_free() with this buffer. */
char *
gmk_expand (const char *ref)
{
return allocated_variable_expand (ref);
}
/* Register a function to be called from makefiles. */
void
gmk_add_function (const char *name, gmk_func_ptr func,
unsigned int min, unsigned int max, unsigned int flags)
{
define_new_function (reading_file, name, min, max, flags, func);
}

1122
main.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,9 @@
# Maintainer-only makefile segment. This contains things that are relevant # Maintainer-only makefile segment. This contains things that are relevant
# only if you have the full copy of the GNU make sources from the CVS # only if you have the full copy of the GNU make sources from the Git
# tree, not a dist copy. # tree, not a dist copy.
GPG_FINGERPRINT := 6338B6D4
# We like mondo-warnings! # We like mondo-warnings!
AM_CFLAGS += -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast AM_CFLAGS += -Wall -Wextra -Wdeclaration-after-statement -Wshadow -Wpointer-arith -Wbad-function-cast
@@ -83,31 +85,18 @@ DEP_FILES := $(wildcard $(DEPDIR)/*.Po)
< $$f; \ < $$f; \
done) > $@ done) > $@
# Get rid of everything "else". # Cleaning
#
maintFILES = configure aclocal.m4 config.h.in Makefile.in stamp-h.in
CVS-CLEAN-FILES += $(maintFILES) $(TEMPLATES) $(MTEMPLATES) NMakefile \ GIT := git
build.sh.in .deps .dep_segment ABOUT-NLS \
ansi2knr.*
# This rule tries to clean the tree right down to how it looks when you do a # git-clean: Clean all "ignored" files. Leave untracked files.
# virgin CVS checkout. # git-very-clean: Clean all files that aren't stored in source control.
# This target is potentially dangerous since it removes _ANY FILE_ that .PHONY: git-clean git-very-clean
# is not in CVS. Including files you might mean to add to CVS but git-clean:
# haven't yet... I only use this in subdirectories where it's unlikely -$(GIT) clean -fdX
# we have any new files. Still... be careful!! git-very-clean: git-clean
-$(GIT) clean -fd
cvsclean = $(PERL) -e '$$k{CVS} = 1; open(E,"< CVS/Entries") || die "CVS/Entries: $$!\n"; while (defined ($$_ = <E>)) { m%^/([^/]*)% or next; $$k{$$1} = 1; } close(E) || die "CVS/Entries: $$!\n"; opendir(D, ".") || die ".: $$!\n"; while (defined ($$_ = readdir(D))) { -f $$_ && ! exists $$k{$$_} && unlink($$_); } closedir(D) || die ".: $$!\n";'
.PHONY: cvs-clean
cvs-clean: maintainer-clean
-rm -rf *~ $(CVS-CLEAN-FILES)
-cd config && $(cvsclean)
-cd po && $(cvsclean)
-cd doc && $(cvsclean)
-cd glob && $(cvsclean)
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@@ -197,11 +186,42 @@ scm-update: get-config/texinfo.tex get-config/config.guess get-config/config.sub
update: po-update scm-update update: po-update scm-update
# ---------------------------------- #
# Alternative configuration checks. #
# ---------------------------------- #
.PHONY: check-alt-config
check-alt-config: \
checkcfg.--disable-job-server \
checkcfg.--disable-load \
checkcfg.--without-guile \
checkcfg.CPPFLAGS^-DNO_OUTPUT_SYNC \
checkcfg.CPPFLAGS^-DNO_ARCHIVES
checkcfg.%: distdir
@ rm -rf $(distdir)/_build \
&& mkdir $(distdir)/_build \
&& cd $(distdir)/_build \
&& echo "Testing configure with $(subst ^,=,$*)" \
&& ../configure --srcdir=.. $(subst ^,=,$*) \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
CFLAGS='$(AM_CFLAGS)' \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) check
.PHONY: update
update: po-update scm-update
## --------------- ## ## --------------- ##
## Sanity checks. ## ## Sanity checks. ##
## --------------- ## ## --------------- ##
# Checks that don't require cvs. Run 'changelog-check' last as # Before we build a distribution be sure we run our local checks
#distdir: local-check
# Checks that don't require Git. Run 'changelog-check' last as
# previous test may reveal problems requiring new ChangeLog entries. # previous test may reveal problems requiring new ChangeLog entries.
local-check: po-check changelog-check local-check: po-check changelog-check
@@ -216,15 +236,26 @@ changelog-check:
fi fi
# Verify that all source files using _() are listed in po/POTFILES.in. # Verify that all source files using _() are listed in po/POTFILES.in.
# Ignore make.h; it defines _(). # Ignore makeint.h; it defines _().
po-check: po-check:
if test -f po/POTFILES.in; then \ if test -f po/POTFILES.in; then \
grep '^[^#]' po/POTFILES.in | sort > $@-1; \ grep '^[^#]' po/POTFILES.in | sort > $@-1; \
$(PERL) -wn -e 'if (/\b_\(/) { $$ARGV eq "make.h" || print "$$ARGV\n" and close ARGV }' *.c *.h | sort > $@-2; \ $(PERL) -wn -e 'if (/\b_\(/) { $$ARGV eq "makeint.h" || print "$$ARGV\n" and close ARGV }' *.c *.h | sort > $@-2; \
diff -u $@-1 $@-2 || exit 1; \ diff -u $@-1 $@-2 || exit 1; \
rm -f $@-1 $@-2; \ rm -f $@-1 $@-2; \
fi fi
## ------------------------- ##
## Make release targets. ##
## ------------------------- ##
tag-release:
case '$(VERSION)' in \
(*.*.9*) message=" candidate" ;; \
(*) message= ;; \
esac; \
$(GIT) tag -m "GNU Make release$$message $(VERSION)" -u '$(GPG_FINGERPRINT)' '$(VERSION)'
## ------------------------- ## ## ------------------------- ##
## GNU FTP upload artifacts. ## ## GNU FTP upload artifacts. ##
## ------------------------- ## ## ------------------------- ##
@@ -234,7 +265,7 @@ po-check:
# you're SOL! :) # you're SOL! :)
GPG = gpg GPG = gpg
GPGFLAGS = -u 6338B6D4 GPGFLAGS = -u $(GPG_FINGERPRINT)
DIST_ARCHIVES_SIG = $(addsuffix .sig,$(DIST_ARCHIVES)) DIST_ARCHIVES_SIG = $(addsuffix .sig,$(DIST_ARCHIVES))
DIST_ARCHIVES_DIRECTIVE = $(addsuffix .directive.asc,$(DIST_ARCHIVES)) DIST_ARCHIVES_DIRECTIVE = $(addsuffix .directive.asc,$(DIST_ARCHIVES))
@@ -271,7 +302,7 @@ $(UPLOADS): $(DIST_ARCHIVES) $(DIST_ARCHIVES_SIG) $(DIST_ARCHIVES_DIRECTIVE)
$(FTPPUT) "$(gnu-upload-host)" "$(gnu-upload-dir)/$(@:upload-%=%)" $^ $(FTPPUT) "$(gnu-upload-host)" "$(gnu-upload-dir)/$(@:upload-%=%)" $^
# Copyright (C) 1997-2012 Free Software Foundation, Inc. # Copyright (C) 1997-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under

32
make.1
View File

@@ -143,7 +143,9 @@ for showing implicit rules,
.I j .I j
for details on invocation of commands, and for details on invocation of commands, and
.I m .I m
for debugging while remaking makefiles. for debugging while remaking makefiles. Use
.I n
to disable all previous debugging flags.
.TP 0.5i .TP 0.5i
\fB\-e\fR, \fB\-\-environment\-overrides\fR \fB\-e\fR, \fB\-\-environment\-overrides\fR
Give variables taken from the environment precedence Give variables taken from the environment precedence
@@ -220,6 +222,28 @@ on account of changes in
.IR file . .IR file .
Essentially the file is treated as very old and its rules are ignored. Essentially the file is treated as very old and its rules are ignored.
.TP 0.5i .TP 0.5i
\fB\-O\fR[\fItype\fR], \fB\-\-output\-sync\fR[=\fItype\fR]
When running multiple jobs in parallel with \fB-j\fR, ensure the output of
each job is collected together rather than interspersed with output from
other jobs. If
.I type
is not specified or is
.B target
the output from the entire recipe for each target is grouped together. If
.I type
is
.B line
the output from each command line within a recipe is grouped together.
If
.I type
is
.B recurse
output from an entire recursive make is grouped together. If
.I type
is
.B none
output synchronization is disabled.
.TP 0.5i
\fB\-p\fR, \fB\-\-print\-data\-base\fR \fB\-p\fR, \fB\-\-print\-data\-base\fR
Print the data base (rules and variable values) that results from Print the data base (rules and variable values) that results from
reading the makefiles; then execute as usual or as otherwise reading the makefiles; then execute as usual or as otherwise
@@ -268,8 +292,8 @@ future invocations of
.BR make . .BR make .
.TP 0.5i .TP 0.5i
.B \-\-trace .B \-\-trace
Print information about the commands invoked by Information about the disposition of each target is printed (why the target is
.BR make. being rebuilt and what commands are run to rebuild it).
.TP 0.5i .TP 0.5i
\fB\-v\fR, \fB\-\-version\fR \fB\-v\fR, \fB\-\-version\fR
Print the version of the Print the version of the
@@ -339,7 +363,7 @@ This manual page contributed by Dennis Morse of Stanford University.
Further updates contributed by Mike Frysinger. It has been reworked by Roland Further updates contributed by Mike Frysinger. It has been reworked by Roland
McGrath. Maintained by Paul Smith. McGrath. Maintained by Paul Smith.
.SH "COPYRIGHT" .SH "COPYRIGHT"
Copyright \(co 1992-1993, 1996-2012 Free Software Foundation, Inc. Copyright \(co 1992-1993, 1996-2013 Free Software Foundation, Inc.
This file is part of This file is part of
.IR "GNU make" . .IR "GNU make" .
.LP .LP

View File

@@ -1,4 +1,4 @@
FROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o"+"hash.o"+"strcache.o" FROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o"+"hash.o"+"strcache.o"+"output.o"
TO "make.new" TO "make.new"
LIB glob/glob.lib LIB:sc.lib LIB:amiga.lib LIB glob/glob.lib LIB:sc.lib LIB:amiga.lib
QUIET QUIET

View File

@@ -171,6 +171,12 @@
<File <File
RelativePath=".\job.c"> RelativePath=".\job.c">
</File> </File>
<File
RelativePath=".\load.c">
</File>
<File
RelativePath=".\output.c">
</File>
<File <File
RelativePath=".\main.c"> RelativePath=".\main.c">
</File> </File>
@@ -207,6 +213,9 @@
<File <File
RelativePath=".\w32\compat\dirent.c"> RelativePath=".\w32\compat\dirent.c">
</File> </File>
<File
RelativePath=".\w32\compat\posixfcn.c">
</File>
<File <File
RelativePath=".\w32\subproc\misc.c"> RelativePath=".\w32\subproc\misc.c">
<FileConfiguration <FileConfiguration
@@ -278,7 +287,10 @@
RelativePath=".\job.h"> RelativePath=".\job.h">
</File> </File>
<File <File
RelativePath=".\make.h"> RelativePath=".\output.h">
</File>
<File
RelativePath=".\makeint.h">
</File> </File>
<File <File
RelativePath=".\rule.h"> RelativePath=".\rule.h">

View File

@@ -67,8 +67,8 @@ $ then
$ gosub check_cc_qual $ gosub check_cc_qual
$ endif $ endif
$ filelist = "alloca ar arscan commands default dir expand file function " + - $ filelist = "alloca ar arscan commands default dir expand file function " + -
"hash implicit job main misc read remake remote-stub rule " + - "hash implicit job load main misc read remake remote-stub rule " + -
"signame variable version vmsfunctions vmsify vpath " + - "output signame variable version vmsfunctions vmsify vpath " + -
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache" "[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
$ copy config.h-vms config.h $ copy config.h-vms config.h
$ n=0 $ n=0
@@ -138,7 +138,7 @@ $ exit
$ endsubroutine : compileit $ endsubroutine : compileit
$! $!
$!----------------------------------------------------------------------------- $!-----------------------------------------------------------------------------
$!Copyright (C) 1996-2012 Free Software Foundation, Inc. $!Copyright (C) 1996-2013 Free Software Foundation, Inc.
$!This file is part of GNU Make. $!This file is part of GNU Make.
$! $!
$!GNU Make is free software; you can redistribute it and/or modify it under $!GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,6 +1,6 @@
# -*-Makefile-*- to build GNU make on VMS # -*-Makefile-*- to build GNU make on VMS
# #
# Copyright (C) 1996-2012 Free Software Foundation, Inc. # Copyright (C) 1996-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -20,7 +20,7 @@
# Klaus Kämpf (kkaempf@rmi.de) # Klaus Kämpf (kkaempf@rmi.de)
# Modified for version 3.78.1 by Hartmut.Becker@compaq.com. # Modified for version 3.78.1 by Hartmut.Becker@compaq.com.
# Modified for version 3.80 by zinser@decus.de # Modified for version 3.80 by zinser@decus.de
# Modified for version 3.81 by Hartmut Becker # Modified for versions 3.81, 3.99.90 by Hartmut Becker
CC = cc CC = cc
CP = copy CP = copy
@@ -90,17 +90,17 @@ manext = 1
#guile = ,guile.obj #guile = ,guile.obj
objs = commands.obj,job.obj,dir.obj,file.obj,misc.obj,hash.obj,\ objs = commands.obj,job.obj,output.obj,dir.obj,file.obj,misc.obj,hash.obj,\
main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\ load.obj,main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\
default.obj,variable.obj,expand.obj,function.obj,strcache.obj,\ default.obj,variable.obj,expand.obj,function.obj,strcache.obj,\
vpath.obj,version.obj\ vpath.obj,version.obj\
$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)$(guile) $(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)$(guile)
srcs = commands.c job.c dir.c file.c misc.c guile.c hash.c \ srcs = commands.c job.c output.c dir.c file.c misc.c guile.c hash.c \
main.c read.c remake.c rule.c implicit.c \ load.c main.c read.c remake.c rule.c implicit.c \
default.c variable.c expand.c function.c strcache.c \ default.c variable.c expand.c function.c strcache.c \
vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \ vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \
commands.h dep.h filedef.h job.h make.h rule.h variable.h commands.h dep.h filedef.h job.h output.h makeint.h rule.h variable.h
.PHONY: all doc .PHONY: all doc
@@ -114,40 +114,44 @@ make.exe: $(objs)
.PHONY: clean realclean .PHONY: clean realclean
clean: clean:
$$ purge [...] -purge [...]
-$(RM) make.exe;,*.obj; -$(RM) make.exe;,*.obj;
-$(RM) [.glob]*.obj; -$(RM) [.glob]*.obj;
# Automatically generated dependencies. # Automatically generated dependencies.
commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h # makeint.h: config.h gnumake.h gettext.h
job.obj: job.c vmsjobs.c make.h commands.h job.h filedef.h variable.h # filedef.h: hash.h
dir.obj: dir.c make.h ar.obj: ar.c makeint.h filedef.h dep.h [.glob]fnmatch.h
file.obj: file.c make.h commands.h dep.h filedef.h variable.h arscan.obj: arscan.c makeint.h
misc.obj: misc.c make.h dep.h commands.obj: commands.c makeint.h dep.h commands.h filedef.h variable.h job.h
hash.obj: hash.c make.h hash.h default.obj: default.c makeint.h rule.h dep.h job.h filedef.h commands.h variable.h
strcache.obj: strcache.c make.h hash.h dir.obj: dir.c makeint.h hash.h [.glob]glob.h
main.obj: main.c make.h commands.h dep.h filedef.h variable.h job.h expand.obj: expand.c makeint.h commands.h filedef.h job.h rule.h variable.h
guile.obj: guile.c make.h debug.h dep.h gmk-default.h file.obj: file.c makeint.h commands.h dep.h filedef.h variable.h job.h debug.h
read.obj: read.c make.h commands.h dep.h filedef.h variable.h function.obj: function.c makeint.h variable.h dep.h commands.h filedef.h debug.h job.h
remake.obj: remake.c make.h commands.h job.h dep.h filedef.h getopt.obj: getopt.c getopt.h config.h gettext.h
rule.obj: rule.c make.h commands.h dep.h filedef.h variable.h rule.h getopt1.obj: getopt1.c getopt.h config.h
implicit.obj: implicit.c make.h rule.h dep.h filedef.h guile.obj: guile.c makeint.h debug.h dep.h gmk-default.h
default.obj: default.c make.h rule.h dep.h filedef.h commands.h variable.h hash.obj: hash.c makeint.h hash.h
variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h implicit.obj: implicit.c makeint.h rule.h dep.h filedef.h debug.h variable.h job.h commands.h
expand.obj: expand.c make.h commands.h filedef.h variable.h job.obj: job.c vmsjobs.c makeint.h commands.h job.h filedef.h variable.h debug.h
function.obj: function.c make.h variable.h dep.h commands.h job.h output.obj: output.c vmsjobs.c makeint.h output.h filedef.h debug.h
vpath.obj: vpath.c make.h filedef.h variable.h load.obj: load.c makeint.h debug.h filedef.h variable.h
main.obj: main.c makeint.h commands.h dep.h filedef.h variable.h job.h rule.h debug.h getopt.h
misc.obj: misc.c makeint.h dep.h debug.h
read.obj: read.c makeint.h commands.h dep.h filedef.h variable.h [.glob]glob.h debug.h rule.h job.h
remake.obj: remake.c makeint.h commands.h job.h dep.h filedef.h variable.h debug.h
remote-stub.obj: remote-stub.c makeint.h filedef.h job.h commands.h
rule.obj: rule.c makeint.h commands.h dep.h filedef.h variable.h rule.h job.h
signame.obj: signame.c makeint.h
strcache.obj: strcache.c makeint.h hash.h
variable.obj: variable.c makeint.h commands.h variable.h dep.h filedef.h job.h rule.h
version.obj: version.c config.h version.obj: version.c config.h
arscan.obj: arscan.c vmsfunctions.obj: vmsfunctions.c makeint.h vmsdir.h debug.h job.h
ar.obj: ar.c make.h filedef.h vmsify.obj: vmsify.c
signame.obj: signame.c vpath.obj: vpath.c makeint.h filedef.h variable.h
remote-stub.obj: remote-stub.c [.glob]fnmatch.obj: [.glob]fnmatch.c [.glob]fnmatch.h config.h
[.glob]glob.obj: [.glob]glob.c [.glob]glob.obj: [.glob]glob.c [.glob]glob.h [.glob]fnmatch.h config.h
[.glob]fnmatch.obj: [.glob]fnmatch.c
getopt.obj: getopt.c
getopt1.obj: getopt1.c
vmsfunctions.obj: vmsfunctions.c make.h vmsdir.h
vmsify.obj: vmsify.c make.h
config.h: config.h-vms config.h: config.h-vms
$(CP) $< $@ $(CP) $< $@

View File

@@ -1,5 +1,5 @@
/* Miscellaneous global declarations and portability cruft for GNU Make. /* Miscellaneous global declarations and portability cruft for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -16,7 +16,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* We use <config.h> instead of "config.h" so that a compilation /* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because make.h was found in $srcdir). */ (which it would do because makeint.h was found in $srcdir). */
#include <config.h> #include <config.h>
#undef HAVE_CONFIG_H #undef HAVE_CONFIG_H
#define HAVE_CONFIG_H 1 #define HAVE_CONFIG_H 1
@@ -47,6 +47,14 @@ char *alloca ();
# define NDEBUG 1 # define NDEBUG 1
#endif #endif
/* Include the externally-visible content.
Be sure to use the local one, and not one installed on the system.
Define GMK_BUILDING_MAKE for proper selection of dllexport/dllimport
declarations for MS-Windows. */
#ifdef WINDOWS32
# define GMK_BUILDING_MAKE
#endif
#include "gnumake.h"
#ifdef CRAY #ifdef CRAY
/* This must happen before #include <signal.h> so /* This must happen before #include <signal.h> so
@@ -165,6 +173,9 @@ unsigned int get_path_max (void);
(! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)) (! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))
#define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t)) #define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t))
/* The maximum number of digits needed to represent the largest integer. */
#define INTEGER_LENGTH sizeof("18446744073709551616")
#ifndef CHAR_MAX #ifndef CHAR_MAX
# define CHAR_MAX INTEGER_TYPE_MAXIMUM (char) # define CHAR_MAX INTEGER_TYPE_MAXIMUM (char)
#endif #endif
@@ -186,6 +197,7 @@ unsigned int get_path_max (void);
#endif #endif
#ifdef VMS #ifdef VMS
# include <fcntl.h>
# include <types.h> # include <types.h>
# include <unixlib.h> # include <unixlib.h>
# include <unixio.h> # include <unixio.h>
@@ -341,10 +353,17 @@ char *strsignal (int signum);
# include <malloc.h> # include <malloc.h>
# define pipe(_p) _pipe((_p), 512, O_BINARY) # define pipe(_p) _pipe((_p), 512, O_BINARY)
# define kill(_pid,_sig) w32_kill((_pid),(_sig)) # define kill(_pid,_sig) w32_kill((_pid),(_sig))
/* MSVC doesn't have ftruncate. */
# ifdef _MSC_VER
# define ftruncate(_fd,_len) _chsize(_fd,_len)
# endif
/* MinGW64 doesn't have _S_ISDIR. */
# ifndef _S_ISDIR
# define _S_ISDIR(m) S_ISDIR(m)
# endif
void sync_Path_environment (void); void sync_Path_environment (void);
int w32_kill (pid_t pid, int sig); int w32_kill (pid_t pid, int sig);
char *end_of_token_w32 (const char *s, char stopchar);
int find_and_set_default_shell (const char *token); int find_and_set_default_shell (const char *token);
/* indicates whether or not we have Bourne shell */ /* indicates whether or not we have Bourne shell */
@@ -352,8 +371,46 @@ extern int no_default_sh_exe;
/* is default_shell unixy? */ /* is default_shell unixy? */
extern int unixy_shell; extern int unixy_shell;
/* We don't have a preferred fixed value for LOCALEDIR. */
# ifndef LOCALEDIR
# define LOCALEDIR NULL
# endif
/* Include only the minimal stuff from windows.h. */
#define WIN32_LEAN_AND_MEAN
#endif /* WINDOWS32 */ #endif /* WINDOWS32 */
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
#define NONE_SET(_v,_m) (! ANY_SET ((_v),(_m)))
#define MAP_NUL 0x0001
#define MAP_BLANK 0x0002
#define MAP_SPACE 0x0004
#define MAP_COMMENT 0x0008
#define MAP_SEMI 0x0010
#define MAP_EQUALS 0x0020
#define MAP_COLON 0x0040
#define MAP_PERCENT 0x0080
#define MAP_PIPE 0x0100
#define MAP_DOT 0x0200
#define MAP_COMMA 0x0400
/* These are the valid characters for a user-defined function. */
#define MAP_USERFUNC 0x2000
/* This means not only a '$', but skip the variable reference. */
#define MAP_VARIABLE 0x4000
/* The set of characters which are path separators is OS-specific. */
#define MAP_PATHSEP 0x8000
#ifdef VMS
# define MAP_VMSCOMMA MAP_COMMA
#else
# define MAP_VMSCOMMA 0x0000
#endif
#define STOP_SET(_v,_m) ANY_SET (stopchar_map[(int)(_v)],(_m))
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) #if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
# define SET_STACK_SIZE # define SET_STACK_SIZE
#endif #endif
@@ -362,45 +419,24 @@ extern int unixy_shell;
extern struct rlimit stack_limit; extern struct rlimit stack_limit;
#endif #endif
struct floc #define NILF ((gmk_floc *)0)
{
const char *filenm;
unsigned long lineno;
};
#define NILF ((struct floc *)0)
#define CSTRLEN(_s) (sizeof (_s)-1) #define CSTRLEN(_s) (sizeof (_s)-1)
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s) #define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
/* We have to have stdarg.h or varargs.h AND v*printf or doprnt to use
variadic versions of these functions. */
#if HAVE_STDARG_H || HAVE_VARARGS_H
# if HAVE_VPRINTF || HAVE_DOPRNT
# define USE_VARIADIC 1
# endif
#endif
#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
const char *concat (unsigned int, ...); const char *concat (unsigned int, ...);
void message (int prefix, const char *fmt, ...) void message (int prefix, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
void error (const struct floc *flocp, const char *fmt, ...) void error (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
void fatal (const struct floc *flocp, const char *fmt, ...) void fatal (const gmk_floc *flocp, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 2, 3))); __attribute__ ((noreturn, __format__ (__printf__, 2, 3)));
#else
const char *concat ();
void message ();
void error ();
void fatal ();
#endif
void die (int) __attribute__ ((noreturn)); void die (int) __attribute__ ((noreturn));
void log_working_directory (int);
void pfatal_with_name (const char *) __attribute__ ((noreturn)); void pfatal_with_name (const char *) __attribute__ ((noreturn));
void perror_with_name (const char *, const char *); void perror_with_name (const char *, const char *);
#define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s))
void *xmalloc (unsigned int); void *xmalloc (unsigned int);
void *xcalloc (unsigned int); void *xcalloc (unsigned int);
void *xrealloc (void *, unsigned int); void *xrealloc (void *, unsigned int);
@@ -415,7 +451,6 @@ int alpha_compare (const void *, const void *);
void print_spaces (unsigned int); void print_spaces (unsigned int);
char *find_percent (char *); char *find_percent (char *);
const char *find_percent_cached (const char **); const char *find_percent_cached (const char **);
FILE *open_tmpfile (char **, const char *);
#ifndef NO_ARCHIVES #ifndef NO_ARCHIVES
int ar_name (const char *); int ar_name (const char *);
@@ -443,6 +478,7 @@ const char *dir_name (const char *);
void hash_init_directories (void); void hash_init_directories (void);
void define_default_variables (void); void define_default_variables (void);
void undefine_default_variables (void);
void set_default_suffixes (void); void set_default_suffixes (void);
void install_default_suffix_rules (void); void install_default_suffix_rules (void);
void install_default_implicit_rules (void); void install_default_implicit_rules (void);
@@ -459,8 +495,6 @@ void user_access (void);
void make_access (void); void make_access (void);
void child_access (void); void child_access (void);
void close_stdout (void);
char *strip_whitespace (const char **begpp, const char **endpp); char *strip_whitespace (const char **begpp, const char **endpp);
/* String caching */ /* String caching */
@@ -473,16 +507,13 @@ int strcache_setbufsize (unsigned int size);
/* Guile support */ /* Guile support */
#ifdef HAVE_GUILE #ifdef HAVE_GUILE
int guile_gmake_setup (const struct floc *flocp); int guile_gmake_setup (const gmk_floc *flocp);
#endif #endif
/* Loadable object support */ /* Loadable object support. Sets to the strcached name of the loaded file. */
typedef int (*load_func_t)(const struct floc *flocp); typedef int (*load_func_t)(const gmk_floc *flocp);
int load_file (const struct floc *flocp, const char *filename, int noerror); int load_file (const gmk_floc *flocp, const char **filename, int noerror);
void unload_file (const char *name);
#ifdef HAVE_VFORK_H
# include <vfork.h>
#endif
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION, /* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
because such systems often declare them in header files anyway. */ because such systems often declare them in header files anyway. */
@@ -527,18 +558,25 @@ int strncasecmp (const char *s1, const char *s2, int n);
# endif # endif
#endif #endif
extern const struct floc *reading_file; #define OUTPUT_SYNC_NONE 0
extern const struct floc **expanding_var; #define OUTPUT_SYNC_LINE 1
#define OUTPUT_SYNC_TARGET 2
#define OUTPUT_SYNC_RECURSE 3
extern const gmk_floc *reading_file;
extern const gmk_floc **expanding_var;
extern char **environ; extern char **environ;
extern unsigned short stopchar_map[];
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag; extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
extern int print_data_base_flag, question_flag, touch_flag, always_make_flag; extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag; extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
extern int print_version_flag, print_directory_flag, check_symlink_flag; extern int print_version_flag, print_directory_flag, check_symlink_flag;
extern int warn_undefined_variables_flag, trace_flag, posix_pedantic; extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
extern int not_parallel, second_expansion, clock_skew_detected; extern int not_parallel, second_expansion, clock_skew_detected;
extern int rebuilding_makefiles, one_shell; extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
/* can we run commands via 'sh -c xxx' or must we use batch files? */ /* can we run commands via 'sh -c xxx' or must we use batch files? */
extern int batch_mode_shell; extern int batch_mode_shell;

265
misc.c
View File

@@ -1,5 +1,5 @@
/* Miscellaneous generic support functions for GNU Make. /* Miscellaneous generic support functions for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,42 +14,21 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "filedef.h"
#include "dep.h" #include "dep.h"
#include "debug.h" #include "debug.h"
/* Variadic functions. We go through contortions to allow proper function /* GNU make no longer supports pre-ANSI89 environments. */
prototypes for both ANSI and pre-ANSI C compilers, and also for those
which support stdarg.h vs. varargs.h, and finally those which have
vfprintf(), etc. and those who have _doprnt... or nothing.
This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and #include <stdarg.h>
VA_END macros used here since we have multiple print functions. */
#if USE_VARIADIC #ifdef HAVE_FCNTL_H
# if HAVE_STDARG_H # include <fcntl.h>
# include <stdarg.h>
# define VA_START(args, lastarg) va_start(args, lastarg)
# else
# include <varargs.h>
# define VA_START(args, lastarg) va_start(args)
# endif
# if HAVE_VPRINTF
# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
# else
# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
# endif
# define VA_END(args) va_end(args)
#else #else
/* We can't use any variadic interface! */ # include <sys/file.h>
# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
# define VA_START(args, lastarg)
# define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
# define VA_END(args)
#endif #endif
/* Compare strings *S1 and *S2. /* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater, Return negative if the first is less, positive if it is greater,
zero if they are equal. */ zero if they are equal. */
@@ -72,9 +51,7 @@ alpha_compare (const void *v1, const void *v2)
void void
collapse_continuations (char *line) collapse_continuations (char *line)
{ {
register char *in, *out, *p; char *in, *out, *p;
register int backslash;
register unsigned int bs_write;
in = strchr (line, '\n'); in = strchr (line, '\n');
if (in == 0) if (in == 0)
@@ -89,8 +66,8 @@ collapse_continuations (char *line)
/* BS_WRITE gets the number of quoted backslashes at /* BS_WRITE gets the number of quoted backslashes at
the end just before IN, and BACKSLASH gets nonzero the end just before IN, and BACKSLASH gets nonzero
if the next character is quoted. */ if the next character is quoted. */
backslash = 0; unsigned int backslash = 0;
bs_write = 0; unsigned int bs_write = 0;
for (p = in - 1; p >= line && *p == '\\'; --p) for (p = in - 1; p >= line && *p == '\\'; --p)
{ {
if (backslash) if (backslash)
@@ -164,28 +141,19 @@ print_spaces (unsigned int n)
This string lives in static, re-used memory. */ This string lives in static, re-used memory. */
const char * const char *
#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
concat (unsigned int num, ...) concat (unsigned int num, ...)
#else
concat (num, va_alist)
unsigned int num;
va_dcl
#endif
{ {
static unsigned int rlen = 0; static unsigned int rlen = 0;
static char *result = NULL; static char *result = NULL;
unsigned int ri = 0; unsigned int ri = 0;
#if USE_VARIADIC
va_list args; va_list args;
#endif
VA_START (args, num); va_start (args, num);
while (num-- > 0) while (num-- > 0)
{ {
const char *s = va_arg (args, const char *); const char *s = va_arg (args, const char *);
unsigned int l = s ? strlen (s) : 0; unsigned int l = xstrlen (s);
if (l == 0) if (l == 0)
continue; continue;
@@ -200,7 +168,7 @@ concat (num, va_alist)
ri += l; ri += l;
} }
VA_END (args); va_end (args);
/* Get some more memory if we don't have enough space for the /* Get some more memory if we don't have enough space for the
terminating '\0'. */ terminating '\0'. */
@@ -215,113 +183,9 @@ concat (num, va_alist)
return result; return result;
} }
/* Print a message on stdout. */
void
#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
message (int prefix, const char *fmt, ...)
#else
message (prefix, fmt, va_alist)
int prefix;
const char *fmt;
va_dcl
#endif
{
#if USE_VARIADIC
va_list args;
#endif
log_working_directory (1);
if (fmt != 0)
{
if (prefix)
{
if (makelevel == 0)
printf ("%s: ", program);
else
printf ("%s[%u]: ", program, makelevel);
}
VA_START (args, fmt);
VA_PRINTF (stdout, fmt, args);
VA_END (args);
putchar ('\n');
}
fflush (stdout);
}
/* Print an error message. */
void
#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
error (const struct floc *flocp, const char *fmt, ...)
#else
error (flocp, fmt, va_alist)
const struct floc *flocp;
const char *fmt;
va_dcl
#endif
{
#if USE_VARIADIC
va_list args;
#endif
log_working_directory (1);
if (flocp && flocp->filenm)
fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fprintf (stderr, "%s: ", program);
else
fprintf (stderr, "%s[%u]: ", program, makelevel);
VA_START(args, fmt);
VA_PRINTF (stderr, fmt, args);
VA_END (args);
putc ('\n', stderr);
fflush (stderr);
}
/* Print an error message and exit. */
void
#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
fatal (const struct floc *flocp, const char *fmt, ...)
#else
fatal (flocp, fmt, va_alist)
const struct floc *flocp;
const char *fmt;
va_dcl
#endif
{
#if USE_VARIADIC
va_list args;
#endif
log_working_directory (1);
if (flocp && flocp->filenm)
fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fprintf (stderr, "%s: *** ", program);
else
fprintf (stderr, "%s[%u]: *** ", program, makelevel);
VA_START(args, fmt);
VA_PRINTF (stderr, fmt, args);
VA_END (args);
fputs (_(". Stop.\n"), stderr);
die (2);
}
#ifndef HAVE_STRERROR #ifndef HAVE_STRERROR
#undef strerror #undef strerror
char * char *
strerror (int errnum) strerror (int errnum)
{ {
@@ -338,24 +202,6 @@ strerror (int errnum)
return buf; return buf;
} }
#endif #endif
/* Print an error message from errno. */
void
perror_with_name (const char *str, const char *name)
{
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
}
/* Print an error message from errno and exit. */
void
pfatal_with_name (const char *name)
{
fatal (NILF, _("%s: %s"), name, strerror (errno));
/* NOTREACHED */
}
/* Like malloc but get fatal error if memory is exhausted. */ /* Like malloc but get fatal error if memory is exhausted. */
/* Don't bother if we're using dmalloc; it provides these for us. */ /* Don't bother if we're using dmalloc; it provides these for us. */
@@ -468,41 +314,11 @@ lindex (const char *s, const char *limit, int c)
char * char *
end_of_token (const char *s) end_of_token (const char *s)
{ {
while (*s != '\0' && !isblank ((unsigned char)*s)) while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
++s; ++s;
return (char *)s; return (char *)s;
} }
#ifdef WINDOWS32
/*
* Same as end_of_token, but take into account a stop character
*/
char *
end_of_token_w32 (const char *s, char stopchar)
{
const char *p = s;
int backslash = 0;
while (*p != '\0' && *p != stopchar
&& (backslash || !isblank ((unsigned char)*p)))
{
if (*p++ == '\\')
{
backslash = !backslash;
while (*p == '\\')
{
backslash = !backslash;
++p;
}
}
else
backslash = 0;
}
return (char *)p;
}
#endif
/* Return the address of the first nonwhitespace or null in the string S. */ /* Return the address of the first nonwhitespace or null in the string S. */
char * char *
@@ -590,7 +406,6 @@ free_ns_chain (struct nameseq *ns)
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI #if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
/* If we don't have strcasecmp() (from POSIX), or anything that can substitute /* If we don't have strcasecmp() (from POSIX), or anything that can substitute
for it, define our own version. */ for it, define our own version. */
@@ -616,7 +431,6 @@ strcasecmp (const char *s1, const char *s2)
#endif #endif
#if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI #if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
/* If we don't have strncasecmp() (from POSIX), or anything that can /* If we don't have strncasecmp() (from POSIX), or anything that can
substitute for it, define our own version. */ substitute for it, define our own version. */
@@ -891,7 +705,7 @@ child_access (void)
#endif /* GETLOADAVG_PRIVILEGED */ #endif /* GETLOADAVG_PRIVILEGED */
} }
#ifdef NEED_GET_PATH_MAX #ifdef NEED_GET_PATH_MAX
unsigned int unsigned int
get_path_max (void) get_path_max (void)
@@ -910,50 +724,3 @@ get_path_max (void)
return value; return value;
} }
#endif #endif
/* This code is stolen from gnulib.
If/when we abandon the requirement to work with K&R compilers, we can
remove this (and perhaps other parts of GNU make!) and migrate to using
gnulib directly.
This is called only through atexit(), which means die() has already been
invoked. So, call exit() here directly. Apparently that works...?
*/
/* Close standard output, exiting with status 'exit_failure' on failure.
If a program writes *anything* to stdout, that program should close
stdout and make sure that it succeeds before exiting. Otherwise,
suppose that you go to the extreme of checking the return status
of every function that does an explicit write to stdout. The last
printf can succeed in writing to the internal stream buffer, and yet
the fclose(stdout) could still fail (due e.g., to a disk full error)
when it tries to write out that buffered data. Thus, you would be
left with an incomplete output file and the offending program would
exit successfully. Even calling fflush is not always sufficient,
since some file systems (NFS and CODA) buffer written/flushed data
until an actual close call.
Besides, it's wasteful to check the return value from every call
that writes to stdout -- just let the internal stream state record
the failure. That's what the ferror test is checking below.
It's important to detect such failures and exit nonzero because many
tools (most notably 'make' and other build-management systems) depend
on being able to detect failure in other tools via their exit status. */
void
close_stdout (void)
{
int prev_fail = ferror (stdout);
int fclose_fail = fclose (stdout);
if (prev_fail || fclose_fail)
{
if (fclose_fail)
error (NILF, _("write error: %s"), strerror (errno));
else
error (NILF, _("write error"));
exit (EXIT_FAILURE);
}
}

762
output.c Normal file
View File

@@ -0,0 +1,762 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "job.h"
/* GNU make no longer supports pre-ANSI89 environments. */
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#else
# include <sys/file.h>
#endif
#ifdef WINDOWS32
# include <windows.h>
# include <io.h>
# include "sub_proc.h"
#endif /* WINDOWS32 */
struct output *output_context = NULL;
unsigned int stdio_traced = 0;
#define OUTPUT_NONE (-1)
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
#ifdef HAVE_FCNTL
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#else
# define STREAM_OK(_s) 1
#endif
/* I really want to move to gnulib. However, this is a big undertaking
especially for non-UNIX platforms: how to get bootstrapping to work, etc.
I don't want to take the time to do it right now. Use a hack to get a
useful version of vsnprintf() for Windows. */
#ifdef __VMS
# define va_copy(_d, _s) ((_d) = (_s))
#endif
#ifdef _MSC_VER
# define va_copy(_d, _s) ((_d) = (_s))
# define snprintf msc_vsnprintf
static int
msc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
int len = -1;
if (size > 0)
len = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
if (len == -1)
len = _vscprintf (format, ap);
return len;
}
#endif
/* Write a string to the current STDOUT or STDERR. */
static void
_outputs (struct output *out, int is_err, const char *msg)
{
if (! out || ! out->syncout)
{
FILE *f = is_err ? stderr : stdout;
fputs (msg, f);
fflush (f);
}
else
{
int fd = is_err ? out->err : out->out;
int len = strlen (msg);
int r;
EINTRLOOP (r, lseek (fd, 0, SEEK_END));
while (1)
{
EINTRLOOP (r, write (fd, msg, len));
if (r == len || r <= 0)
break;
len -= r;
msg += r;
}
}
}
/* Write a message indicating that we've just entered or
left (according to ENTERING) the current directory. */
static int
log_working_directory (int entering)
{
static char *buf = NULL;
static unsigned int len = 0;
unsigned int need;
const char *fmt;
char *p;
/* Get enough space for the longest possible output. */
need = strlen (program) + INTEGER_LENGTH + 2 + 1;
if (starting_directory)
need += strlen (starting_directory);
/* Use entire sentences to give the translators a fighting chance. */
if (makelevel == 0)
if (starting_directory == 0)
if (entering)
fmt = _("%s: Entering an unknown directory\n");
else
fmt = _("%s: Leaving an unknown directory\n");
else
if (entering)
fmt = _("%s: Entering directory '%s'\n");
else
fmt = _("%s: Leaving directory '%s'\n");
else
if (starting_directory == 0)
if (entering)
fmt = _("%s[%u]: Entering an unknown directory\n");
else
fmt = _("%s[%u]: Leaving an unknown directory\n");
else
if (entering)
fmt = _("%s[%u]: Entering directory '%s'\n");
else
fmt = _("%s[%u]: Leaving directory '%s'\n");
need += strlen (fmt);
if (need > len)
{
buf = xrealloc (buf, need);
len = need;
}
p = buf;
if (print_data_base_flag)
{
*(p++) = '#';
*(p++) = ' ';
}
if (makelevel == 0)
if (starting_directory == 0)
sprintf (p, fmt , program);
else
sprintf (p, fmt, program, starting_directory);
else if (starting_directory == 0)
sprintf (p, fmt, program, makelevel);
else
sprintf (p, fmt, program, makelevel, starting_directory);
_outputs (NULL, 0, buf);
return 1;
}
/* Set a file descriptor to be in O_APPEND mode.
If it fails, just ignore it. */
static void
set_append_mode (int fd)
{
#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
int flags = fcntl (fd, F_GETFL, 0);
if (flags >= 0)
fcntl (fd, F_SETFL, flags | O_APPEND);
#endif
}
#ifndef NO_OUTPUT_SYNC
/* Semaphore for use in -j mode with output_sync. */
static sync_handle_t sync_handle = -1;
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
/* Set up the sync handle. Disables output_sync on error. */
static int
sync_init ()
{
int combined_output = 0;
#ifdef WINDOWS32
if ((!STREAM_OK (stdout) && !STREAM_OK (stderr))
|| (sync_handle = create_mutex ()) == -1)
{
perror_with_name ("output-sync suppressed: ", "stderr");
output_sync = 0;
}
else
{
combined_output = same_stream (stdout, stderr);
prepare_mutex_handle_string (sync_handle);
}
#else
if (STREAM_OK (stdout))
{
struct stat stbuf_o, stbuf_e;
sync_handle = fileno (stdout);
combined_output = (fstat (fileno (stdout), &stbuf_o) == 0
&& fstat (fileno (stderr), &stbuf_e) == 0
&& stbuf_o.st_dev == stbuf_e.st_dev
&& stbuf_o.st_ino == stbuf_e.st_ino);
}
else if (STREAM_OK (stderr))
sync_handle = fileno (stderr);
else
{
perror_with_name ("output-sync suppressed: ", "stderr");
output_sync = 0;
}
#endif
return combined_output;
}
/* Support routine for output_sync() */
static void
pump_from_tmp (int from, FILE *to)
{
static char buffer[8192];
#ifdef WINDOWS32
int prev_mode;
/* "from" is opened by open_tmpfd, which does it in binary mode, so
we need the mode of "to" to match that. */
prev_mode = _setmode (fileno (to), _O_BINARY);
#endif
if (lseek (from, 0, SEEK_SET) == -1)
perror ("lseek()");
while (1)
{
int len;
EINTRLOOP (len, read (from, buffer, sizeof (buffer)));
if (len < 0)
perror ("read()");
if (len <= 0)
break;
if (fwrite (buffer, len, 1, to) < 1)
perror ("fwrite()");
}
#ifdef WINDOWS32
/* Switch "to" back to its original mode, so that log messages by
Make have the same EOL format as without --output-sync. */
_setmode (fileno (to), prev_mode);
#endif
}
/* Obtain the lock for writing output. */
static void *
acquire_semaphore (void)
{
static struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if (fcntl (sync_handle, F_SETLKW, &fl) != -1)
return &fl;
perror ("fcntl()");
return NULL;
}
/* Release the lock for writing output. */
static void
release_semaphore (void *sem)
{
struct flock *flp = (struct flock *)sem;
flp->l_type = F_UNLCK;
if (fcntl (sync_handle, F_SETLKW, flp) == -1)
perror ("fcntl()");
}
/* Returns a file descriptor to a temporary file. The file is automatically
closed/deleted on exit. Don't use a FILE* stream. */
int
output_tmpfd ()
{
int fd = -1;
FILE *tfile = tmpfile ();
if (! tfile)
pfatal_with_name ("tmpfile");
/* Create a duplicate so we can close the stream. */
fd = dup (fileno (tfile));
if (fd < 0)
pfatal_with_name ("dup");
fclose (tfile);
set_append_mode (fd);
return fd;
}
/* Adds file descriptors to the child structure to support output_sync; one
for stdout and one for stderr as long as they are open. If stdout and
stderr share a device they can share a temp file too.
Will reset output_sync on error. */
static void
setup_tmpfile (struct output *out)
{
/* Is make's stdout going to the same place as stderr? */
static int combined_output = -1;
if (combined_output < 0)
combined_output = sync_init ();
if (STREAM_OK (stdout))
{
int fd = output_tmpfd ();
if (fd < 0)
goto error;
CLOSE_ON_EXEC (fd);
out->out = fd;
}
if (STREAM_OK (stderr))
{
if (out->out != OUTPUT_NONE && combined_output)
out->err = out->out;
else
{
int fd = output_tmpfd ();
if (fd < 0)
goto error;
CLOSE_ON_EXEC (fd);
out->err = fd;
}
}
return;
/* If we failed to create a temp file, disable output sync going forward. */
error:
output_close (out);
output_sync = 0;
}
/* Synchronize the output of jobs in -j mode to keep the results of
each job together. This is done by holding the results in temp files,
one for stdout and potentially another for stderr, and only releasing
them to "real" stdout/stderr when a semaphore can be obtained. */
void
output_dump (struct output *out)
{
int outfd_not_empty = FD_NOT_EMPTY (out->out);
int errfd_not_empty = FD_NOT_EMPTY (out->err);
if (outfd_not_empty || errfd_not_empty)
{
int traced = 0;
/* Try to acquire the semaphore. If it fails, dump the output
unsynchronized; still better than silently discarding it.
We want to keep this lock for as little time as possible. */
void *sem = acquire_semaphore ();
/* Log the working directory for this dump. */
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
traced = log_working_directory (1);
if (outfd_not_empty)
pump_from_tmp (out->out, stdout);
if (errfd_not_empty && out->err != out->out)
pump_from_tmp (out->err, stderr);
if (traced)
log_working_directory (0);
/* Exit the critical section. */
if (sem)
release_semaphore (sem);
/* Truncate and reset the output, in case we use it again. */
if (out->out != OUTPUT_NONE)
{
int e;
lseek (out->out, 0, SEEK_SET);
EINTRLOOP (e, ftruncate (out->out, 0));
}
if (out->err != OUTPUT_NONE && out->err != out->out)
{
int e;
lseek (out->err, 0, SEEK_SET);
EINTRLOOP (e, ftruncate (out->err, 0));
}
}
}
#endif /* NO_OUTPUT_SYNC */
/* Provide support for temporary files. */
#ifndef HAVE_STDLIB_H
# ifdef HAVE_MKSTEMP
int mkstemp (char *template);
# else
char *mktemp (char *template);
# endif
#endif
FILE *
output_tmpfile (char **name, const char *template)
{
#ifdef HAVE_FDOPEN
int fd;
#endif
#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
# define TEMPLATE_LEN strlen (template)
#else
# define TEMPLATE_LEN L_tmpnam
#endif
*name = xmalloc (TEMPLATE_LEN + 1);
strcpy (*name, template);
#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
/* It's safest to use mkstemp(), if we can. */
fd = mkstemp (*name);
if (fd == -1)
return 0;
return fdopen (fd, "w");
#else
# ifdef HAVE_MKTEMP
(void) mktemp (*name);
# else
(void) tmpnam (*name);
# endif
# ifdef HAVE_FDOPEN
/* Can't use mkstemp(), but guard against a race condition. */
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
if (fd == -1)
return 0;
return fdopen (fd, "w");
# else
/* Not secure, but what can we do? */
return fopen (*name, "w");
# endif
#endif
}
/* This code is stolen from gnulib.
If/when we abandon the requirement to work with K&R compilers, we can
remove this (and perhaps other parts of GNU make!) and migrate to using
gnulib directly.
This is called only through atexit(), which means die() has already been
invoked. So, call exit() here directly. Apparently that works...?
*/
/* Close standard output, exiting with status 'exit_failure' on failure.
If a program writes *anything* to stdout, that program should close
stdout and make sure that it succeeds before exiting. Otherwise,
suppose that you go to the extreme of checking the return status
of every function that does an explicit write to stdout. The last
printf can succeed in writing to the internal stream buffer, and yet
the fclose(stdout) could still fail (due e.g., to a disk full error)
when it tries to write out that buffered data. Thus, you would be
left with an incomplete output file and the offending program would
exit successfully. Even calling fflush is not always sufficient,
since some file systems (NFS and CODA) buffer written/flushed data
until an actual close call.
Besides, it's wasteful to check the return value from every call
that writes to stdout -- just let the internal stream state record
the failure. That's what the ferror test is checking below.
It's important to detect such failures and exit nonzero because many
tools (most notably 'make' and other build-management systems) depend
on being able to detect failure in other tools via their exit status. */
static void
close_stdout (void)
{
int prev_fail = ferror (stdout);
int fclose_fail = fclose (stdout);
if (prev_fail || fclose_fail)
{
if (fclose_fail)
error (NILF, _("write error: %s"), strerror (errno));
else
error (NILF, _("write error"));
exit (EXIT_FAILURE);
}
}
void
output_init (struct output *out)
{
if (out)
{
out->out = out->err = OUTPUT_NONE;
out->syncout = !!output_sync;
return;
}
/* Configure this instance of make. Be sure stdout is line-buffered. */
#ifdef HAVE_SETVBUF
# ifdef SETVBUF_REVERSED
setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ);
# else /* setvbuf not reversed. */
/* Some buggy systems lose if we pass 0 instead of allocating ourselves. */
setvbuf (stdout, 0, _IOLBF, BUFSIZ);
# endif /* setvbuf reversed. */
#elif HAVE_SETLINEBUF
setlinebuf (stdout);
#endif /* setlinebuf missing. */
/* Force stdout/stderr into append mode. This ensures parallel jobs won't
lose output due to overlapping writes. */
set_append_mode (fileno (stdout));
set_append_mode (fileno (stderr));
#ifdef HAVE_ATEXIT
if (STREAM_OK (stdout))
atexit (close_stdout);
#endif
}
void
output_close (struct output *out)
{
if (! out)
{
if (stdio_traced)
log_working_directory (0);
return;
}
#ifndef NO_OUTPUT_SYNC
output_dump (out);
#endif
if (out->out >= 0)
close (out->out);
if (out->err >= 0 && out->err != out->out)
close (out->err);
output_init (out);
}
/* We're about to generate output: be sure it's set up. */
void
output_start ()
{
#ifndef NO_OUTPUT_SYNC
/* If we're syncing output make sure the temporary file is set up. */
if (output_context && output_context->syncout)
if (! OUTPUT_ISSET(output_context))
setup_tmpfile (output_context);
#endif
/* If we're not syncing this output per-line or per-target, make sure we emit
the "Entering..." message where appropriate. */
if (output_sync == OUTPUT_SYNC_NONE || output_sync == OUTPUT_SYNC_RECURSE)
if (! stdio_traced && print_directory_flag)
stdio_traced = log_working_directory (1);
}
void
outputs (int is_err, const char *msg)
{
if (! msg || *msg == '\0')
return;
output_start ();
_outputs (output_context, is_err, msg);
}
/* Return formatted string buffers.
If we move to gnulib we can use vasnprintf() etc. to make this simpler.
Note these functions use a static buffer, so each call overwrites the
results of the previous call. */
static struct fmtstring
{
char *buffer;
unsigned int size;
unsigned int len;
} fmtbuf = { NULL, 0, 0 };
/* Concatenate a formatted string onto the format buffer. */
static const char *
vfmtconcat (const char *fmt, va_list args)
{
va_list vcopy;
int tot;
int unused = fmtbuf.size - fmtbuf.len;
va_copy (vcopy, args);
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, args);
assert (tot >= 0);
if (tot >= unused)
{
fmtbuf.size += tot * 2;
fmtbuf.buffer = xrealloc (fmtbuf.buffer, fmtbuf.size);
unused = fmtbuf.size - fmtbuf.len;
tot = vsnprintf (&fmtbuf.buffer[fmtbuf.len], unused, fmt, vcopy);
}
va_end (vcopy);
fmtbuf.len += tot;
return fmtbuf.buffer;
}
static const char *
fmtconcat (const char *fmt, ...)
{
const char *p;
va_list args;
va_start (args, fmt);
p = vfmtconcat (fmt, args);
va_end (args);
return p;
}
/* Print a message on stdout. */
void
message (int prefix, const char *fmt, ...)
{
va_list args;
assert (fmt != NULL);
fmtbuf.len = 0;
if (prefix)
{
if (makelevel == 0)
fmtconcat ("%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
}
va_start (args, fmt);
vfmtconcat (fmt, args);
va_end (args);
fmtconcat ("\n");
outputs (0, fmtbuf.buffer);
}
/* Print an error message. */
void
error (const gmk_floc *flocp, const char *fmt, ...)
{
va_list args;
assert (fmt != NULL);
fmtbuf.len = 0;
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fmtconcat ("%s: ", program);
else
fmtconcat ("%s[%u]: ", program, makelevel);
va_start (args, fmt);
vfmtconcat (fmt, args);
va_end (args);
fmtconcat ("\n");
outputs (1, fmtbuf.buffer);
}
/* Print an error message and exit. */
void
fatal (const gmk_floc *flocp, const char *fmt, ...)
{
va_list args;
assert (fmt != NULL);
fmtbuf.len = 0;
if (flocp && flocp->filenm)
fmtconcat ("%s:%lu: *** ", flocp->filenm, flocp->lineno);
else if (makelevel == 0)
fmtconcat ("%s: *** ", program);
else
fmtconcat ("%s[%u]: *** ", program, makelevel);
va_start (args, fmt);
vfmtconcat (fmt, args);
va_end (args);
fmtconcat (_(". Stop.\n"));
outputs (1, fmtbuf.buffer);
die (2);
}
/* Print an error message from errno. */
void
perror_with_name (const char *str, const char *name)
{
error (NILF, _("%s%s: %s"), str, name, strerror (errno));
}
/* Print an error message from errno and exit. */
void
pfatal_with_name (const char *name)
{
fatal (NILF, _("%s: %s"), name, strerror (errno));
/* NOTREACHED */
}

51
output.h Normal file
View File

@@ -0,0 +1,51 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
struct output
{
int out;
int err;
unsigned int syncout:1; /* True if we want to synchronize output. */
};
extern struct output *output_context;
extern unsigned int stdio_traced;
#define OUTPUT_SET(_new) do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
#define OUTPUT_UNSET() do{ output_context = NULL; }while(0)
#define OUTPUT_TRACED() do{ stdio_traced = 1; }while(0)
#define OUTPUT_IS_TRACED() (!!stdio_traced)
FILE *output_tmpfile (char **, const char *);
/* Initialize and close a child output structure: if NULL do this program's
output (this should only be done once). */
void output_init (struct output *out);
void output_close (struct output *out);
/* In situations where output may be about to be displayed but we're not
sure if we've set it up yet, call this. */
void output_start (void);
/* Show a message on stdout or stderr. Will start the output if needed. */
void outputs (int is_err, const char *msg);
#ifndef NO_OUTPUT_SYNC
int output_tmpfd (void);
/* Dump any child output content to stdout, and reset it. */
void output_dump (struct output *out);
#endif

View File

@@ -1,6 +0,0 @@
*.gmo *.mo *.pot *.po
Makefile Makefile.in Makefile.in.in Makevars.template
Rules-quot stamp-po
*.sed *.sin *.header
POTFILES

15
po/.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
Makefile.in.in
Makevars.template
POTFILES
Rules-quot
boldquot.sed
en@boldquot.header
en@quot.header
insert-header.sin
make.pot
quot.sed
remove-potcdate.sin
remove-potcdate.sed
stamp-po
*.gmo
*.po

View File

@@ -77,7 +77,7 @@
* POTFILES.in, LINGUAS, Makevars: Created. * POTFILES.in, LINGUAS, Makevars: Created.
Copyright (C) 2002-2012 Free Software Foundation, Inc. Copyright (C) 2002-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,5 +1,5 @@
# This is a -*-Makefile-*- # This is a -*-Makefile-*-
# Copyright (C) 2002-2012 Free Software Foundation, Inc. # Copyright (C) 2002-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,5 +1,5 @@
# List of source files containing translatable strings. # List of source files containing translatable strings.
# Copyright (C) 2000-2012 Free Software Foundation, Inc. # Copyright (C) 2000-2013 Free Software Foundation, Inc.
# This file is part of GNU Make. # This file is part of GNU Make.
# #
# GNU Make is free software; you can redistribute it and/or modify it under # GNU Make is free software; you can redistribute it and/or modify it under
@@ -27,9 +27,11 @@ guile.c
hash.c hash.c
implicit.c implicit.c
job.c job.c
job.h
load.c load.c
main.c main.c
misc.c misc.c
output.c
read.c read.c
remake.c remake.c
remote-cstms.c remote-cstms.c

View File

@@ -1,5 +1,5 @@
@echo off @echo off
@echo Windows32 CVS build preparation of config.h.W32 and NMakefile. @echo Windows32 SCM build preparation of config.h.W32 and NMakefile.
if not exist config.h.W32 copy config.h.W32.template config.h.W32 if not exist config.h.W32 copy config.h.W32.template config.h.W32
if not exist config.h copy config.h.W32 config.h if not exist config.h copy config.h.W32 config.h
if not exist NMakefile copy NMakefile.template NMakefile if not exist NMakefile copy NMakefile.template NMakefile

248
read.c
View File

@@ -1,5 +1,5 @@
/* Reading and parsing of makefiles for GNU Make. /* Reading and parsing of makefiles for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,14 +14,14 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <assert.h> #include <assert.h>
#include <glob.h> #include <glob.h>
#include "dep.h"
#include "filedef.h" #include "filedef.h"
#include "dep.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
#include "variable.h" #include "variable.h"
@@ -30,7 +30,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "hash.h" #include "hash.h"
#ifndef WINDOWS32 #ifdef WINDOWS32
#include <windows.h>
#include "sub_proc.h"
#else /* !WINDOWS32 */
#ifndef _AMIGA #ifndef _AMIGA
#ifndef VMS #ifndef VMS
#include <pwd.h> #include <pwd.h>
@@ -51,7 +54,7 @@ struct ebuffer
char *bufstart; /* Start of the entire buffer. */ char *bufstart; /* Start of the entire buffer. */
unsigned int size; /* Malloc'd size of buffer. */ unsigned int size; /* Malloc'd size of buffer. */
FILE *fp; /* File, or NULL if this is an internal buffer. */ FILE *fp; /* File, or NULL if this is an internal buffer. */
struct floc floc; /* Info on the file in fp (if any). */ gmk_floc floc; /* Info on the file in fp (if any). */
}; };
/* Track the modifiers we can have on variable assignments */ /* Track the modifiers we can have on variable assignments */
@@ -125,11 +128,11 @@ static unsigned int max_incl_len;
/* The filename and pointer to line number of the /* The filename and pointer to line number of the
makefile currently being read in. */ makefile currently being read in. */
const struct floc *reading_file = 0; const gmk_floc *reading_file = 0;
/* The chain of makefiles read by read_makefile. */ /* The chain of files read by read_all_makefiles. */
static struct dep *read_makefiles = 0; static struct dep *read_files = 0;
static int eval_makefile (const char *filename, int flags); static int eval_makefile (const char *filename, int flags);
static void eval (struct ebuffer *buffer, int flags); static void eval (struct ebuffer *buffer, int flags);
@@ -139,21 +142,20 @@ static void do_undefine (char *name, enum variable_origin origin,
struct ebuffer *ebuf); struct ebuffer *ebuf);
static struct variable *do_define (char *name, enum variable_origin origin, static struct variable *do_define (char *name, enum variable_origin origin,
struct ebuffer *ebuf); struct ebuffer *ebuf);
static int conditional_line (char *line, int len, const struct floc *flocp); static int conditional_line (char *line, int len, const gmk_floc *flocp);
static void record_files (struct nameseq *filenames, const char *pattern, static void record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr, const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands, unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon, unsigned int commands_idx, int two_colon,
char prefix, const struct floc *flocp); char prefix, const gmk_floc *flocp);
static void record_target_var (struct nameseq *filenames, char *defn, static void record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin, enum variable_origin origin,
struct vmodifiers *vmod, struct vmodifiers *vmod,
const struct floc *flocp); const gmk_floc *flocp);
static enum make_word_type get_next_mword (char *buffer, char *delim, static enum make_word_type get_next_mword (char *buffer, char *delim,
char **startp, unsigned int *length); char **startp, unsigned int *length);
static void remove_comments (char *line); static void remove_comments (char *line);
static char *find_char_unquote (char *string, int stop1, int stop2, static char *find_char_unquote (char *string, int map);
int blank, int ignorevars);
static char *unescape_char (char *string, int c); static char *unescape_char (char *string, int c);
@@ -163,7 +165,7 @@ static char *unescape_char (char *string, int c);
#define word1eq(s) (wlen == CSTRLEN (s) && strneq (s, p, CSTRLEN (s))) #define word1eq(s) (wlen == CSTRLEN (s) && strneq (s, p, CSTRLEN (s)))
/* Read in all the makefiles and return the chain of their names. */ /* Read in all the makefiles and return a chain of targets to rebuild. */
struct dep * struct dep *
read_all_makefiles (const char **makefiles) read_all_makefiles (const char **makefiles)
@@ -215,18 +217,18 @@ read_all_makefiles (const char **makefiles)
if (makefiles != 0) if (makefiles != 0)
while (*makefiles != 0) while (*makefiles != 0)
{ {
struct dep *tail = read_makefiles; struct dep *tail = read_files;
register struct dep *d; struct dep *d;
if (! eval_makefile (*makefiles, 0)) if (! eval_makefile (*makefiles, 0))
perror_with_name ("", *makefiles); perror_with_name ("", *makefiles);
/* Find the right element of read_makefiles. */ /* Find the first element eval_makefile() added to read_files. */
d = read_makefiles; d = read_files;
while (d->next != tail) while (d->next != tail)
d = d->next; d = d->next;
/* Use the storage read_makefile allocates. */ /* Reuse the storage allocated for the read_file. */
*makefiles = dep_name (d); *makefiles = dep_name (d);
++num_makefiles; ++num_makefiles;
++makefiles; ++makefiles;
@@ -259,8 +261,8 @@ read_all_makefiles (const char **makefiles)
else else
{ {
/* No default makefile was found. Add the default makefiles to the /* No default makefile was found. Add the default makefiles to the
'read_makefiles' chain so they will be updated if possible. */ 'read_files' chain so they will be updated if possible. */
struct dep *tail = read_makefiles; struct dep *tail = read_files;
/* Add them to the tail, after any MAKEFILES variable makefiles. */ /* Add them to the tail, after any MAKEFILES variable makefiles. */
while (tail != 0 && tail->next != 0) while (tail != 0 && tail->next != 0)
tail = tail->next; tail = tail->next;
@@ -273,7 +275,7 @@ read_all_makefiles (const char **makefiles)
made, and main not to die if we can't make this file. */ made, and main not to die if we can't make this file. */
d->changed = RM_DONTCARE; d->changed = RM_DONTCARE;
if (tail == 0) if (tail == 0)
read_makefiles = d; read_files = d;
else else
tail->next = d; tail->next = d;
tail = d; tail = d;
@@ -283,7 +285,7 @@ read_all_makefiles (const char **makefiles)
} }
} }
return read_makefiles; return read_files;
} }
/* Install a new conditional and return the previous one. */ /* Install a new conditional and return the previous one. */
@@ -319,7 +321,7 @@ eval_makefile (const char *filename, int flags)
{ {
struct dep *deps; struct dep *deps;
struct ebuffer ebuf; struct ebuffer ebuf;
const struct floc *curfile; const gmk_floc *curfile;
char *expanded = 0; char *expanded = 0;
int makefile_errno; int makefile_errno;
@@ -351,10 +353,24 @@ eval_makefile (const char *filename, int flags)
filename = expanded; filename = expanded;
} }
ebuf.fp = fopen (filename, "r"); ENULLLOOP (ebuf.fp, fopen (filename, "r"));
/* Save the error code so we print the right message later. */ /* Save the error code so we print the right message later. */
makefile_errno = errno; makefile_errno = errno;
/* Check for unrecoverable errors: out of mem or FILE slots. */
switch (makefile_errno)
{
#ifdef EMFILE
case EMFILE:
#endif
#ifdef ENFILE
case ENFILE:
#endif
case ENOMEM:
fatal (reading_file, "%s", strerror (makefile_errno));
}
/* If the makefile wasn't found and it's either a makefile from /* If the makefile wasn't found and it's either a makefile from
the 'MAKEFILES' variable or an included makefile, the 'MAKEFILES' variable or an included makefile,
search the included makefile search path for this makefile. */ search the included makefile search path for this makefile. */
@@ -380,8 +396,8 @@ eval_makefile (const char *filename, int flags)
/* Add FILENAME to the chain of read makefiles. */ /* Add FILENAME to the chain of read makefiles. */
deps = alloc_dep (); deps = alloc_dep ();
deps->next = read_makefiles; deps->next = read_files;
read_makefiles = deps; read_files = deps;
deps->file = lookup_file (filename); deps->file = lookup_file (filename);
if (deps->file == 0) if (deps->file == 0)
deps->file = enter_file (filename); deps->file = enter_file (filename);
@@ -435,12 +451,12 @@ eval_makefile (const char *filename, int flags)
} }
void void
eval_buffer (char *buffer) eval_buffer (char *buffer, const gmk_floc *floc)
{ {
struct ebuffer ebuf; struct ebuffer ebuf;
struct conditionals *saved; struct conditionals *saved;
struct conditionals new; struct conditionals new;
const struct floc *curfile; const gmk_floc *curfile;
/* Evaluate the buffer */ /* Evaluate the buffer */
@@ -448,10 +464,15 @@ eval_buffer (char *buffer)
ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer; ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer;
ebuf.fp = NULL; ebuf.fp = NULL;
if (reading_file) if (floc)
ebuf.floc = *floc;
else if (reading_file)
ebuf.floc = *reading_file; ebuf.floc = *reading_file;
else else
{
ebuf.floc.filenm = NULL; ebuf.floc.filenm = NULL;
ebuf.floc.lineno = 1;
}
curfile = reading_file; curfile = reading_file;
reading_file = &ebuf.floc; reading_file = &ebuf.floc;
@@ -564,8 +585,8 @@ eval (struct ebuffer *ebuf, int set_default)
char prefix = cmd_prefix; char prefix = cmd_prefix;
const char *pattern = 0; const char *pattern = 0;
const char *pattern_percent; const char *pattern_percent;
struct floc *fstart; gmk_floc *fstart;
struct floc fi; gmk_floc fi;
#define record_waiting_files() \ #define record_waiting_files() \
do \ do \
@@ -700,7 +721,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* See if this is a variable assignment. We need to do this early, to /* See if this is a variable assignment. We need to do this early, to
allow variables with names like 'ifdef', 'export', 'private', etc. */ allow variables with names like 'ifdef', 'export', 'private', etc. */
p = parse_var_assignment(p, &vmod); p = parse_var_assignment (p, &vmod);
if (vmod.assign_v) if (vmod.assign_v)
{ {
struct variable *v; struct variable *v;
@@ -750,7 +771,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (in_ignored_define) if (in_ignored_define)
{ {
/* See if this is an endef line (plus optional comment). */ /* See if this is an endef line (plus optional comment). */
if (word1eq ("endef") && (*p2 == '\0' || *p2 == '#')) if (word1eq ("endef") && STOP_SET (*p2, MAP_COMMENT|MAP_NUL))
in_ignored_define = 0; in_ignored_define = 0;
continue; continue;
@@ -864,7 +885,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Parse the list of file names. Don't expand archive references! */ /* Parse the list of file names. Don't expand archive references! */
p2 = p; p2 = p;
files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, files = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL,
PARSEFS_NOAR); PARSEFS_NOAR);
free (p); free (p);
@@ -922,8 +943,8 @@ eval (struct ebuffer *ebuf, int set_default)
/* Parse the list of file names. /* Parse the list of file names.
Don't expand archive references or strip "./" */ Don't expand archive references or strip "./" */
p2 = p; p2 = p;
files = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, files = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_NUL, NULL,
PARSEFS_NOAR|PARSEFS_NOSTRIP); PARSEFS_NOAR);
free (p); free (p);
/* Load each file. */ /* Load each file. */
@@ -931,12 +952,29 @@ eval (struct ebuffer *ebuf, int set_default)
{ {
struct nameseq *next = files->next; struct nameseq *next = files->next;
const char *name = files->name; const char *name = files->name;
struct dep *deps;
int r;
/* Load the file. 0 means failure. */
r = load_file (&ebuf->floc, &name, noerror);
if (! r && ! noerror)
fatal (&ebuf->floc, _("%s: failed to load"), name);
free_ns (files); free_ns (files);
files = next; files = next;
if (! load_file (&ebuf->floc, name, noerror) && ! noerror) /* Return of -1 means a special load: don't rebuild it. */
fatal (&ebuf->floc, _("%s: failed to load"), name); if (r == -1)
continue;
/* It succeeded, so add it to the list "to be rebuilt". */
deps = alloc_dep ();
deps->next = read_files;
read_files = deps;
deps->file = lookup_file (name);
if (deps->file == 0)
deps->file = enter_file (name);
deps->file->loaded = 1;
} }
continue; continue;
@@ -946,7 +984,7 @@ eval (struct ebuffer *ebuf, int set_default)
was no preceding target, and the line might have been usable as a was no preceding target, and the line might have been usable as a
variable definition. But now we know it is definitely lossage. */ variable definition. But now we know it is definitely lossage. */
if (line[0] == cmd_prefix) if (line[0] == cmd_prefix)
fatal(fstart, _("recipe commences before first target")); fatal (fstart, _("recipe commences before first target"));
/* This line describes some target files. This is complicated by /* This line describes some target files. This is complicated by
the existence of target-specific variables, because we can't the existence of target-specific variables, because we can't
@@ -972,7 +1010,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Search the line for an unquoted ; that is not after an /* Search the line for an unquoted ; that is not after an
unquoted #. */ unquoted #. */
cmdleft = find_char_unquote (line, ';', '#', 0, 1); cmdleft = find_char_unquote (line, MAP_SEMI|MAP_COMMENT|MAP_VARIABLE);
if (cmdleft != 0 && *cmdleft == '#') if (cmdleft != 0 && *cmdleft == '#')
{ {
/* We found a comment before a semicolon. */ /* We found a comment before a semicolon. */
@@ -990,12 +1028,12 @@ eval (struct ebuffer *ebuf, int set_default)
variable we don't want to expand it. So, walk from the variable we don't want to expand it. So, walk from the
beginning, expanding as we go, and looking for "interesting" beginning, expanding as we go, and looking for "interesting"
chars. The first word is always expandable. */ chars. The first word is always expandable. */
wtype = get_next_mword(line, NULL, &lb_next, &wlen); wtype = get_next_mword (line, NULL, &lb_next, &wlen);
switch (wtype) switch (wtype)
{ {
case w_eol: case w_eol:
if (cmdleft != 0) if (cmdleft != 0)
fatal(fstart, _("missing rule before recipe")); fatal (fstart, _("missing rule before recipe"));
/* This line contained something but turned out to be nothing /* This line contained something but turned out to be nothing
but whitespace (a comment?). */ but whitespace (a comment?). */
continue; continue;
@@ -1011,7 +1049,7 @@ eval (struct ebuffer *ebuf, int set_default)
break; break;
} }
p2 = variable_expand_string(NULL, lb_next, wlen); p2 = variable_expand_string (NULL, lb_next, wlen);
while (1) while (1)
{ {
@@ -1019,13 +1057,13 @@ eval (struct ebuffer *ebuf, int set_default)
if (cmdleft == 0) if (cmdleft == 0)
{ {
/* Look for a semicolon in the expanded line. */ /* Look for a semicolon in the expanded line. */
cmdleft = find_char_unquote (p2, ';', 0, 0, 0); cmdleft = find_char_unquote (p2, MAP_SEMI);
if (cmdleft != 0) if (cmdleft != 0)
{ {
unsigned long p2_off = p2 - variable_buffer; unsigned long p2_off = p2 - variable_buffer;
unsigned long cmd_off = cmdleft - variable_buffer; unsigned long cmd_off = cmdleft - variable_buffer;
char *pend = p2 + strlen(p2); char *pend = p2 + strlen (p2);
/* Append any remnants of lb, then cut the line short /* Append any remnants of lb, then cut the line short
at the semicolon. */ at the semicolon. */
@@ -1035,18 +1073,18 @@ eval (struct ebuffer *ebuf, int set_default)
here, but merely copy, since now you're beyond a ";" here, but merely copy, since now you're beyond a ";"
and into a command script. However, the old parser and into a command script. However, the old parser
expanded the whole line, so we continue that for expanded the whole line, so we continue that for
backwards-compatiblity. Also, it wouldn't be backwards-compatibility. Also, it wouldn't be
entirely consistent, since we do an unconditional entirely consistent, since we do an unconditional
expand below once we know we don't have a expand below once we know we don't have a
target-specific variable. */ target-specific variable. */
(void)variable_expand_string(pend, lb_next, (long)-1); (void)variable_expand_string (pend, lb_next, (long)-1);
lb_next += strlen(lb_next); lb_next += strlen (lb_next);
p2 = variable_buffer + p2_off; p2 = variable_buffer + p2_off;
cmdleft = variable_buffer + cmd_off + 1; cmdleft = variable_buffer + cmd_off + 1;
} }
} }
colonp = find_char_unquote(p2, ':', 0, 0, 0); colonp = find_char_unquote (p2, MAP_COLON);
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
/* The drive spec brain-damage strikes again... */ /* The drive spec brain-damage strikes again... */
/* Note that the only separators of targets in this context /* Note that the only separators of targets in this context
@@ -1055,18 +1093,18 @@ eval (struct ebuffer *ebuf, int set_default)
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') && while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
colonp > p2 && isalpha ((unsigned char)colonp[-1]) && colonp > p2 && isalpha ((unsigned char)colonp[-1]) &&
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0)) (colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
colonp = find_char_unquote(colonp + 1, ':', 0, 0, 0); colonp = find_char_unquote (colonp + 1, MAP_COLON);
#endif #endif
if (colonp != 0) if (colonp != 0)
break; break;
wtype = get_next_mword(lb_next, NULL, &lb_next, &wlen); wtype = get_next_mword (lb_next, NULL, &lb_next, &wlen);
if (wtype == w_eol) if (wtype == w_eol)
break; break;
p2 += strlen(p2); p2 += strlen (p2);
*(p2++) = ' '; *(p2++) = ' ';
p2 = variable_expand_string(p2, lb_next, wlen); p2 = variable_expand_string (p2, lb_next, wlen);
/* We don't need to worry about cmdleft here, because if it was /* We don't need to worry about cmdleft here, because if it was
found in the variable_buffer the entire buffer has already found in the variable_buffer the entire buffer has already
been expanded... we'll never get here. */ been expanded... we'll never get here. */
@@ -1091,7 +1129,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Make the colon the end-of-string so we know where to stop /* Make the colon the end-of-string so we know where to stop
looking for targets. Start there again once we're done. */ looking for targets. Start there again once we're done. */
*colonp = '\0'; *colonp = '\0';
filenames = PARSE_FILE_SEQ (&p2, struct nameseq, '\0', NULL, 0); filenames = PARSE_SIMPLE_SEQ (&p2, struct nameseq);
*colonp = ':'; *colonp = ':';
p2 = colonp; p2 = colonp;
@@ -1146,7 +1184,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* This is a normal target, _not_ a target-specific variable. /* This is a normal target, _not_ a target-specific variable.
Unquote any = in the dependency list. */ Unquote any = in the dependency list. */
find_char_unquote (lb_next, '=', 0, 0, 0); find_char_unquote (lb_next, MAP_EQUALS);
/* Remember the command prefix for this target. */ /* Remember the command prefix for this target. */
prefix = cmd_prefix; prefix = cmd_prefix;
@@ -1164,7 +1202,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Look for a semicolon in the expanded line. */ /* Look for a semicolon in the expanded line. */
if (cmdleft == 0) if (cmdleft == 0)
{ {
cmdleft = find_char_unquote (p2, ';', 0, 0, 0); cmdleft = find_char_unquote (p2, MAP_SEMI);
if (cmdleft != 0) if (cmdleft != 0)
*(cmdleft++) = '\0'; *(cmdleft++) = '\0';
} }
@@ -1218,7 +1256,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (p != 0) if (p != 0)
{ {
struct nameseq *target; struct nameseq *target;
target = PARSE_FILE_SEQ (&p2, struct nameseq, ':', NULL, target = PARSE_FILE_SEQ (&p2, struct nameseq, MAP_COLON, NULL,
PARSEFS_NOGLOB); PARSEFS_NOGLOB);
++p2; ++p2;
if (target == 0) if (target == 0)
@@ -1281,14 +1319,13 @@ eval (struct ebuffer *ebuf, int set_default)
if (set_default && default_goal_var->value[0] == '\0') if (set_default && default_goal_var->value[0] == '\0')
{ {
const char *name;
struct dep *d; struct dep *d;
struct nameseq *t = filenames; struct nameseq *t = filenames;
for (; t != 0; t = t->next) for (; t != 0; t = t->next)
{ {
int reject = 0; int reject = 0;
name = t->name; const char *name = t->name;
/* We have nothing to do if this is an implicit rule. */ /* We have nothing to do if this is an implicit rule. */
if (strchr (name, '%') != 0) if (strchr (name, '%') != 0)
@@ -1370,7 +1407,7 @@ remove_comments (char *line)
{ {
char *comment; char *comment;
comment = find_char_unquote (line, '#', 0, 0, 0); comment = find_char_unquote (line, MAP_COMMENT);
if (comment != 0) if (comment != 0)
/* Cut off the line at the #. */ /* Cut off the line at the #. */
@@ -1409,7 +1446,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
{ {
struct variable *v; struct variable *v;
struct variable var; struct variable var;
struct floc defstart; gmk_floc defstart;
int nlevels = 1; int nlevels = 1;
unsigned int length = 100; unsigned int length = 100;
char *definition = xmalloc (length); char *definition = xmalloc (length);
@@ -1525,7 +1562,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
1 if following text should be ignored. */ 1 if following text should be ignored. */
static int static int
conditional_line (char *line, int len, const struct floc *flocp) conditional_line (char *line, int len, const gmk_floc *flocp)
{ {
char *cmdname; char *cmdname;
enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype; enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype;
@@ -1549,7 +1586,7 @@ conditional_line (char *line, int len, const struct floc *flocp)
/* Found one: skip past it and any whitespace after it. */ /* Found one: skip past it and any whitespace after it. */
line = next_token (line + len); line = next_token (line + len);
#define EXTRANEOUS() error (flocp, _("Extraneous text after '%s' directive"), cmdname) #define EXTRANEOUS() error (flocp, _("extraneous text after '%s' directive"), cmdname)
/* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */ /* An 'endif' cannot contain extra text, and reduces the if-depth by 1 */
if (cmdtype == c_endif) if (cmdtype == c_endif)
@@ -1603,7 +1640,7 @@ conditional_line (char *line, int len, const struct floc *flocp)
and cannot be an 'else' or 'endif'. */ and cannot be an 'else' or 'endif'. */
/* Find the length of the next word. */ /* Find the length of the next word. */
for (p = line+1; *p != '\0' && !isspace ((unsigned char)*p); ++p) for (p = line+1; ! STOP_SET (*p, MAP_SPACE|MAP_NUL); ++p)
; ;
len = p - line; len = p - line;
@@ -1794,7 +1831,7 @@ conditional_line (char *line, int len, const struct floc *flocp)
static void static void
record_target_var (struct nameseq *filenames, char *defn, record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin, struct vmodifiers *vmod, enum variable_origin origin, struct vmodifiers *vmod,
const struct floc *flocp) const gmk_floc *flocp)
{ {
struct nameseq *nextf; struct nameseq *nextf;
struct variable_set_list *global; struct variable_set_list *global;
@@ -1866,7 +1903,7 @@ record_target_var (struct nameseq *filenames, char *defn,
if (v->origin != o_override) if (v->origin != o_override)
{ {
struct variable *gv; struct variable *gv;
int len = strlen(v->name); int len = strlen (v->name);
gv = lookup_variable (v->name, len); gv = lookup_variable (v->name, len);
if (gv && v != gv if (gv && v != gv
@@ -1899,7 +1936,7 @@ record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr, const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands, unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon, unsigned int commands_idx, int two_colon,
char prefix, const struct floc *flocp) char prefix, const gmk_floc *flocp)
{ {
struct commands *cmds; struct commands *cmds;
struct dep *deps; struct dep *deps;
@@ -2035,7 +2072,7 @@ record_files (struct nameseq *filenames, const char *pattern,
} }
else if (streq (name, ".SECONDEXPANSION")) else if (streq (name, ".SECONDEXPANSION"))
second_expansion = 1; second_expansion = 1;
#if !defined(WINDOWS32) && !defined (__MSDOS__) && !defined (__EMX__) #if !defined (__MSDOS__) && !defined (__EMX__)
else if (streq (name, ".ONESHELL")) else if (streq (name, ".ONESHELL"))
one_shell = 1; one_shell = 1;
#endif #endif
@@ -2065,7 +2102,7 @@ record_files (struct nameseq *filenames, const char *pattern,
more than once. Just give a warning since this is harmless. */ more than once. Just give a warning since this is harmless. */
if (cmds != 0 && cmds == f->cmds) if (cmds != 0 && cmds == f->cmds)
error (flocp, error (flocp,
_("target '%s' given more than once in the same rule."), _("target '%s' given more than once in the same rule"),
f->name); f->name);
/* Check for two single-colon entries both with commands. /* Check for two single-colon entries both with commands.
@@ -2194,37 +2231,24 @@ record_files (struct nameseq *filenames, const char *pattern,
STOPCHAR _cannot_ be '$' if IGNOREVARS is true. */ STOPCHAR _cannot_ be '$' if IGNOREVARS is true. */
static char * static char *
find_char_unquote (char *string, int stop1, int stop2, int blank, find_char_unquote (char *string, int map)
int ignorevars)
{ {
unsigned int string_len = 0; unsigned int string_len = 0;
char *p = string; char *p = string;
if (ignorevars) /* Always stop on NUL. */
ignorevars = '$'; map |= MAP_NUL;
while (1) while (1)
{ {
if (stop2 && blank) while (! STOP_SET (*p, map))
while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2
&& ! isblank ((unsigned char) *p))
++p;
else if (stop2)
while (*p != '\0' && *p != ignorevars && *p != stop1 && *p != stop2)
++p;
else if (blank)
while (*p != '\0' && *p != ignorevars && *p != stop1
&& ! isblank ((unsigned char) *p))
++p;
else
while (*p != '\0' && *p != ignorevars && *p != stop1)
++p; ++p;
if (*p == '\0') if (*p == '\0')
break; break;
/* If we stopped due to a variable reference, skip over its contents. */ /* If we stopped due to a variable reference, skip over its contents. */
if (*p == ignorevars) if (STOP_SET (*p, MAP_VARIABLE))
{ {
char openparen = p[1]; char openparen = p[1];
@@ -2332,7 +2356,7 @@ unescape_char (char *string, int c)
char * char *
find_percent (char *pattern) find_percent (char *pattern)
{ {
return find_char_unquote (pattern, '%', 0, 0, 0); return find_char_unquote (pattern, MAP_PERCENT);
} }
/* Search STRING for an unquoted % and handle quoting. Returns a pointer to /* Search STRING for an unquoted % and handle quoting. Returns a pointer to
@@ -2355,7 +2379,7 @@ find_percent_cached (const char **string)
while (1) while (1)
{ {
while (*p != '\0' && *p != '%') while (! STOP_SET (*p, MAP_PERCENT|MAP_NUL))
++p; ++p;
if (*p == '\0') if (*p == '\0')
@@ -2525,7 +2549,7 @@ readline (struct ebuffer *ebuf)
if ((p - start) > 1 && p[-2] == '\r') if ((p - start) > 1 && p[-2] == '\r')
{ {
--p; --p;
p[-1] = '\n'; memmove (p-1, p, strlen (p) + 1);
} }
#endif #endif
@@ -2970,7 +2994,7 @@ tilde_expand (const char *name)
*/ */
void * void *
parse_file_seq (char **stringp, unsigned int size, int stopchar, parse_file_seq (char **stringp, unsigned int size, int stopmap,
const char *prefix, int flags) const char *prefix, int flags)
{ {
extern void dir_setup_glob (glob_t *glob); extern void dir_setup_glob (glob_t *glob);
@@ -2978,9 +3002,8 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* tmp points to tmpbuf after the prefix, if any. /* tmp points to tmpbuf after the prefix, if any.
tp is the end of the buffer. */ tp is the end of the buffer. */
static char *tmpbuf = NULL; static char *tmpbuf = NULL;
static int tmpbuf_len = 0;
int cachep = (! (flags & PARSEFS_NOCACHE)); int cachep = NONE_SET (flags, PARSEFS_NOCACHE);
struct nameseq *new = 0; struct nameseq *new = 0;
struct nameseq **newp = &new; struct nameseq **newp = &new;
@@ -2995,20 +3018,18 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
glob_t gl; glob_t gl;
char *tp; char *tp;
#ifdef VMS /* Always stop on NUL. */
# define VMS_COMMA ',' stopmap |= MAP_NUL;
#else
# define VMS_COMMA 0
#endif
if (size < sizeof (struct nameseq)) if (size < sizeof (struct nameseq))
size = sizeof (struct nameseq); size = sizeof (struct nameseq);
if (! (flags & PARSEFS_NOGLOB)) if (NONE_SET (flags, PARSEFS_NOGLOB))
dir_setup_glob (&gl); dir_setup_glob (&gl);
/* Get enough temporary space to construct the largest possible target. */ /* Get enough temporary space to construct the largest possible target. */
{ {
static int tmpbuf_len = 0;
int l = strlen (*stringp) + 1; int l = strlen (*stringp) + 1;
if (l > tmpbuf_len) if (l > tmpbuf_len)
{ {
@@ -3036,39 +3057,39 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */ /* Skip whitespace; at the end of the string or STOPCHAR we're done. */
p = next_token (p); p = next_token (p);
if (*p == '\0' || *p == stopchar) if (STOP_SET (*p, stopmap))
break; break;
/* There are names left, so find the end of the next name. /* There are names left, so find the end of the next name.
Throughout this iteration S points to the start. */ Throughout this iteration S points to the start. */
s = p; s = p;
p = find_char_unquote (p, stopchar, VMS_COMMA, 1, 0); p = find_char_unquote (p, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#ifdef VMS #ifdef VMS
/* convert comma separated list to space separated */ /* convert comma separated list to space separated */
if (p && *p == ',') if (p && *p == ',')
*p =' '; *p =' ';
#endif #endif
#ifdef _AMIGA #ifdef _AMIGA
if (stopchar == ':' && p && *p == ':' if (p && STOP_SET (*p, stopmap & MAP_COLON)
&& !(isspace ((unsigned char)p[1]) || !p[1] && !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1]))) || isspace ((unsigned char)p[-1])))
p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1, 0); p = find_char_unquote (p+1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif #endif
#ifdef HAVE_DOS_PATHS #ifdef HAVE_DOS_PATHS
/* For DOS paths, skip a "C:\..." or a "C:/..." until we find the /* For DOS paths, skip a "C:\..." or a "C:/..." until we find the
first colon which isn't followed by a slash or a backslash. first colon which isn't followed by a slash or a backslash.
Note that tokens separated by spaces should be treated as separate Note that tokens separated by spaces should be treated as separate
tokens since make doesn't allow path names with spaces */ tokens since make doesn't allow path names with spaces */
if (stopchar == ':') if (stopmap | MAP_COLON)
while (p != 0 && !isspace ((unsigned char)*p) && while (p != 0 && !isspace ((unsigned char)*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1])) (p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
p = find_char_unquote (p + 1, stopchar, VMS_COMMA, 1, 0); p = find_char_unquote (p + 1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif #endif
if (p == 0) if (p == 0)
p = s + strlen (s); p = s + strlen (s);
/* Strip leading "this directory" references. */ /* Strip leading "this directory" references. */
if (! (flags & PARSEFS_NOSTRIP)) if (NONE_SET (flags, PARSEFS_NOSTRIP))
#ifdef VMS #ifdef VMS
/* Skip leading '[]'s. */ /* Skip leading '[]'s. */
while (p - s > 2 && s[0] == '[' && s[1] == ']') while (p - s > 2 && s[0] == '[' && s[1] == ']')
@@ -3142,7 +3163,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
Finally, note that archive groups must end with ')' as the last Finally, note that archive groups must end with ')' as the last
character, so ensure there's some word ending like that before character, so ensure there's some word ending like that before
considering this an archive group. */ considering this an archive group. */
if (! (flags & PARSEFS_NOAR) if (NONE_SET (flags, PARSEFS_NOAR)
&& tp == tmpbuf && tp[0] != '(' && tp[nlen-1] != ')') && tp == tmpbuf && tp[0] != '(' && tp[nlen-1] != ')')
{ {
char *n = strchr (tp, '('); char *n = strchr (tp, '(');
@@ -3158,8 +3179,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* Find the end of this word. We don't want to unquote and /* Find the end of this word. We don't want to unquote and
we don't care about quoting since we're looking for the we don't care about quoting since we're looking for the
last char in the word. */ last char in the word. */
while (*e != '\0' && *e != stopchar && *e != VMS_COMMA while (! STOP_SET (*e, stopmap|MAP_BLANK|MAP_VMSCOMMA))
&& ! isblank ((unsigned char) *e))
++e; ++e;
/* If we didn't move, we're done now. */ /* If we didn't move, we're done now. */
if (e == o) if (e == o)
@@ -3208,7 +3228,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* If we're not globbing we're done: add it to the end of the chain. /* If we're not globbing we're done: add it to the end of the chain.
Go to the next item in the string. */ Go to the next item in the string. */
if (flags & PARSEFS_NOGLOB) if (ANY_SET (flags, PARSEFS_NOGLOB))
{ {
NEWELT (concat (2, prefix, tmpbuf)); NEWELT (concat (2, prefix, tmpbuf));
continue; continue;
@@ -3231,7 +3251,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
/* If NAME is an archive member reference replace it with the archive /* If NAME is an archive member reference replace it with the archive
file name, and save the member name in MEMNAME. We will glob on the file name, and save the member name in MEMNAME. We will glob on the
archive name and then reattach MEMNAME later. */ archive name and then reattach MEMNAME later. */
if (! (flags & PARSEFS_NOAR) && ar_name (name)) if (NONE_SET (flags, PARSEFS_NOAR) && ar_name (name))
{ {
ar_parse_name (name, &arname, &memname); ar_parse_name (name, &arname, &memname);
name = arname; name = arname;
@@ -3239,7 +3259,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
#endif /* !NO_ARCHIVES */ #endif /* !NO_ARCHIVES */
/* glob() is expensive: don't call it unless we need to. */ /* glob() is expensive: don't call it unless we need to. */
if (!(flags & PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL) if (NONE_SET (flags, PARSEFS_EXISTS) && strpbrk (name, "?*[") == NULL)
{ {
globme = 0; globme = 0;
i = 1; i = 1;
@@ -3259,7 +3279,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopchar,
case GLOB_NOMATCH: case GLOB_NOMATCH:
/* If we want only existing items, skip this one. */ /* If we want only existing items, skip this one. */
if (flags & PARSEFS_EXISTS) if (ANY_SET (flags, PARSEFS_EXISTS))
{ {
i = 0; i = 0;
break; break;

118
remake.c
View File

@@ -1,5 +1,5 @@
/* Basic dependency engine for GNU Make. /* Basic dependency engine for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "filedef.h" #include "filedef.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
@@ -41,7 +41,7 @@ extern int try_implicit_rule (struct file *file, unsigned int depth);
/* The test for circular dependencies is based on the 'updating' bit in /* The test for circular dependencies is based on the 'updating' bit in
'struct file'. However, double colon targets have seperate 'struct 'struct file'. However, double colon targets have separate 'struct
file's; make sure we always use the base of the double colon chain. */ file's; make sure we always use the base of the double colon chain. */
#define start_updating(_f) (((_f)->double_colon ? (_f)->double_colon : (_f))\ #define start_updating(_f) (((_f)->double_colon ? (_f)->double_colon : (_f))\
@@ -62,7 +62,7 @@ static int update_file (struct file *file, unsigned int depth);
static int update_file_1 (struct file *file, unsigned int depth); static int update_file_1 (struct file *file, unsigned int depth);
static int check_dep (struct file *file, unsigned int depth, static int check_dep (struct file *file, unsigned int depth,
FILE_TIMESTAMP this_mtime, int *must_make_ptr); FILE_TIMESTAMP this_mtime, int *must_make_ptr);
static int touch_file (struct file *file); static enum update_status touch_file (struct file *file);
static void remake_file (struct file *file); static void remake_file (struct file *file);
static FILE_TIMESTAMP name_mtime (const char *name); static FILE_TIMESTAMP name_mtime (const char *name);
static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr); static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
@@ -76,11 +76,11 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
targets, and we should only make one goal at a time and return as soon as targets, and we should only make one goal at a time and return as soon as
one goal whose 'changed' member is nonzero is successfully made. */ one goal whose 'changed' member is nonzero is successfully made. */
int enum update_status
update_goal_chain (struct dep *goals) update_goal_chain (struct dep *goals)
{ {
int t = touch_flag, q = question_flag, n = just_print_flag; int t = touch_flag, q = question_flag, n = just_print_flag;
int status = -1; enum update_status status = us_none;
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \ #define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
: file_mtime (file)) : file_mtime (file))
@@ -130,7 +130,7 @@ update_goal_chain (struct dep *goals)
file = file->prev) file = file->prev)
{ {
unsigned int ocommands_started; unsigned int ocommands_started;
int x; int fail;
file->dontcare = g->dontcare; file->dontcare = g->dontcare;
@@ -152,7 +152,7 @@ update_goal_chain (struct dep *goals)
actually run. */ actually run. */
ocommands_started = commands_started; ocommands_started = commands_started;
x = update_file (file, rebuilding_makefiles ? 1 : 0); fail = update_file (file, rebuilding_makefiles ? 1 : 0);
check_renamed (file); check_renamed (file);
/* Set the goal's 'changed' flag if any commands were started /* Set the goal's 'changed' flag if any commands were started
@@ -166,9 +166,9 @@ update_goal_chain (struct dep *goals)
STATUS as it is if no updating was done. */ STATUS as it is if no updating was done. */
stop = 0; stop = 0;
if ((x != 0 || file->updated) && status < 1) if ((fail || file->updated) && status < us_question)
{ {
if (file->update_status != 0) if (file->update_status != us_success)
{ {
/* Updating failed, or -q triggered. The STATUS value /* Updating failed, or -q triggered. The STATUS value
tells our caller which. */ tells our caller which. */
@@ -195,7 +195,7 @@ update_goal_chain (struct dep *goals)
enter an infinite loop. */ enter an infinite loop. */
if (!rebuilding_makefiles if (!rebuilding_makefiles
|| (!just_print_flag && !question_flag)) || (!just_print_flag && !question_flag))
status = 0; status = us_success;
if (rebuilding_makefiles && file->dontcare) if (rebuilding_makefiles && file->dontcare)
/* This is a default makefile; stop remaking. */ /* This is a default makefile; stop remaking. */
stop = 1; stop = 1;
@@ -222,10 +222,10 @@ update_goal_chain (struct dep *goals)
print a message saying nothing needs doing. */ print a message saying nothing needs doing. */
if (!rebuilding_makefiles if (!rebuilding_makefiles
/* If the update_status is zero, we updated successfully /* If the update_status is success, we updated successfully
or not at all. G->changed will have been set above if or not at all. G->changed will have been set above if
any commands were actually started for this goal. */ any commands were actually started for this goal. */
&& file->update_status == 0 && !g->changed && file->update_status == us_success && !g->changed
/* Never give a message under -s or -q. */ /* Never give a message under -s or -q. */
&& !silent_flag && !question_flag) && !silent_flag && !question_flag)
message (1, ((file->phony || file->cmds == 0) message (1, ((file->phony || file->cmds == 0)
@@ -271,7 +271,7 @@ update_goal_chain (struct dep *goals)
} }
/* If FILE is not up to date, execute the commands for it. /* If FILE is not up to date, execute the commands for it.
Return 0 if successful, 1 if unsuccessful; Return 0 if successful, non-0 if unsuccessful;
but with some flag settings, just call 'exit' if unsuccessful. but with some flag settings, just call 'exit' if unsuccessful.
DEPTH is the depth in recursions of this function. DEPTH is the depth in recursions of this function.
@@ -285,7 +285,7 @@ update_goal_chain (struct dep *goals)
static int static int
update_file (struct file *file, unsigned int depth) update_file (struct file *file, unsigned int depth)
{ {
register int status = 0; int status = 0;
register struct file *f; register struct file *f;
f = file->double_colon ? file->double_colon : file; f = file->double_colon ? file->double_colon : file;
@@ -297,9 +297,10 @@ update_file (struct file *file, unsigned int depth)
if (f->considered == considered) if (f->considered == considered)
{ {
/* Check for the case where a target has been tried and failed but /* Check for the case where a target has been tried and failed but
the diagnostics hasn't been issued. If we need the diagnostics the diagnostics haven't been issued. If we need the diagnostics
then we will have to continue. */ then we will have to continue. */
if (!(f->updated && f->update_status > 0 && !f->dontcare && f->no_diag)) if (!(f->updated && f->update_status > us_none
&& !f->dontcare && f->no_diag))
{ {
DBF (DB_VERBOSE, _("Pruning file '%s'.\n")); DBF (DB_VERBOSE, _("Pruning file '%s'.\n"));
return f->command_state == cs_finished ? f->update_status : 0; return f->command_state == cs_finished ? f->update_status : 0;
@@ -363,7 +364,7 @@ complain (struct file *file)
for (d = file->deps; d != 0; d = d->next) for (d = file->deps; d != 0; d = d->next)
{ {
if (d->file->updated && d->file->update_status > 0 && file->no_diag) if (d->file->updated && d->file->update_status > us_none && file->no_diag)
{ {
complain (d->file); complain (d->file);
break; break;
@@ -395,7 +396,8 @@ complain (struct file *file)
} }
} }
/* Consider a single 'struct file' and update it as appropriate. */ /* Consider a single 'struct file' and update it as appropriate.
Return 0 on success, or non-0 on failure. */
static int static int
update_file_1 (struct file *file, unsigned int depth) update_file_1 (struct file *file, unsigned int depth)
@@ -412,7 +414,7 @@ update_file_1 (struct file *file, unsigned int depth)
if (file->updated) if (file->updated)
{ {
if (file->update_status > 0) if (file->update_status > us_none)
{ {
DBF (DB_VERBOSE, DBF (DB_VERBOSE,
_("Recently tried and failed to update file '%s'.\n")); _("Recently tried and failed to update file '%s'.\n"));
@@ -577,7 +579,7 @@ update_file_1 (struct file *file, unsigned int depth)
while (f != 0); while (f != 0);
} }
if (dep_status != 0 && !keep_going_flag) if (dep_status && !keep_going_flag)
break; break;
if (!running) if (!running)
@@ -638,7 +640,7 @@ update_file_1 (struct file *file, unsigned int depth)
while (f != 0); while (f != 0);
} }
if (dep_status != 0 && !keep_going_flag) if (dep_status && !keep_going_flag)
break; break;
if (!running) if (!running)
@@ -664,7 +666,7 @@ update_file_1 (struct file *file, unsigned int depth)
if (dep_status != 0) if (dep_status != 0)
{ {
file->update_status = dep_status; file->update_status = us_failed;
notice_finished_file (file); notice_finished_file (file);
--depth; --depth;
@@ -803,7 +805,7 @@ update_file_1 (struct file *file, unsigned int depth)
/* It needs to be remade. If it's VPATH and not reset via GPATH, toss the /* It needs to be remade. If it's VPATH and not reset via GPATH, toss the
VPATH. */ VPATH. */
if (!streq(file->name, file->hname)) if (!streq (file->name, file->hname))
{ {
DB (DB_BASIC, (_(" Ignoring VPATH name '%s'.\n"), file->hname)); DB (DB_BASIC, (_(" Ignoring VPATH name '%s'.\n"), file->hname));
file->ignore_vpath = 1; file->ignore_vpath = 1;
@@ -820,17 +822,16 @@ update_file_1 (struct file *file, unsigned int depth)
switch (file->update_status) switch (file->update_status)
{ {
case 2: case us_failed:
DBF (DB_BASIC, _("Failed to remake target file '%s'.\n")); DBF (DB_BASIC, _("Failed to remake target file '%s'.\n"));
break; break;
case 0: case us_success:
DBF (DB_BASIC, _("Successfully remade target file '%s'.\n")); DBF (DB_BASIC, _("Successfully remade target file '%s'.\n"));
break; break;
case 1: case us_question:
DBF (DB_BASIC, _("Target file '%s' needs remade under -q.\n")); DBF (DB_BASIC, _("Target file '%s' needs to be remade under -q.\n"));
break; break;
default: case us_none:
assert (file->update_status >= 0 && file->update_status <= 2);
break; break;
} }
@@ -842,7 +843,7 @@ update_file_1 (struct file *file, unsigned int depth)
files listed in its 'also_make' member. Under -t, this function also files listed in its 'also_make' member. Under -t, this function also
touches FILE. touches FILE.
On return, FILE->update_status will no longer be -1 if it was. */ On return, FILE->update_status will no longer be us_none if it was. */
void void
notice_finished_file (struct file *file) notice_finished_file (struct file *file)
@@ -856,12 +857,12 @@ notice_finished_file (struct file *file)
if (touch_flag if (touch_flag
/* The update status will be: /* The update status will be:
-1 if this target was not remade; us_success if 0 or more commands (+ or ${MAKE}) were run and won;
0 if 0 or more commands (+ or ${MAKE}) were run and won; us_none if this target was not remade;
1 if some commands were run and lost. >us_none if some commands were run and lost.
We touch the target if it has commands which either were not run We touch the target if it has commands which either were not run
or won when they ran (i.e. status is 0). */ or won when they ran (i.e. status is 0). */
&& file->update_status == 0) && file->update_status == us_success)
{ {
if (file->cmds != 0 && file->cmds->any_recurse) if (file->cmds != 0 && file->cmds->any_recurse)
{ {
@@ -876,7 +877,7 @@ notice_finished_file (struct file *file)
{ {
have_nonrecursing: have_nonrecursing:
if (file->phony) if (file->phony)
file->update_status = 0; file->update_status = us_success;
/* According to POSIX, -t doesn't affect targets with no cmds. */ /* According to POSIX, -t doesn't affect targets with no cmds. */
else if (file->cmds != 0) else if (file->cmds != 0)
{ {
@@ -950,7 +951,7 @@ notice_finished_file (struct file *file)
f->last_mtime = max_mtime; f->last_mtime = max_mtime;
} }
if (ran && file->update_status != -1) if (ran && file->update_status != us_none)
/* We actually tried to update FILE, which has /* We actually tried to update FILE, which has
updated its also_make's as well (if it worked). updated its also_make's as well (if it worked).
If it didn't work, it wouldn't work again for them. If it didn't work, it wouldn't work again for them.
@@ -968,10 +969,10 @@ notice_finished_file (struct file *file)
never be done because the target is already updated. */ never be done because the target is already updated. */
f_mtime (d->file, 0); f_mtime (d->file, 0);
} }
else if (file->update_status == -1) else if (file->update_status == us_none)
/* Nothing was done for FILE, but it needed nothing done. /* Nothing was done for FILE, but it needed nothing done.
So mark it now as "succeeded". */ So mark it now as "succeeded". */
file->update_status = 0; file->update_status = us_success;
} }
/* Check whether another file (whose mtime is THIS_MTIME) needs updating on /* Check whether another file (whose mtime is THIS_MTIME) needs updating on
@@ -1046,7 +1047,14 @@ check_dep (struct file *file, unsigned int depth,
fresh. It could be it was checked as part of an order-only fresh. It could be it was checked as part of an order-only
prerequisite and so wasn't rebuilt then, but should be now. */ prerequisite and so wasn't rebuilt then, but should be now. */
if (file->command_state != cs_running) if (file->command_state != cs_running)
{
/* If the target was waiting for a dependency it has to be
reconsidered, as that dependency might have finished. */
if (file->command_state == cs_deps_running)
file->considered = !considered;
set_command_state (file, cs_not_started); set_command_state (file, cs_not_started);
}
ld = 0; ld = 0;
d = file->deps; d = file->deps;
@@ -1105,11 +1113,12 @@ check_dep (struct file *file, unsigned int depth,
return dep_status; return dep_status;
} }
/* Touch FILE. Return zero if successful, one if not. */ /* Touch FILE. Return us_success if successful, us_failed if not. */
#define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1) #define TOUCH_ERROR(call) do{ perror_with_name ((call), file->name); \
return us_failed; }while(0)
static int static enum update_status
touch_file (struct file *file) touch_file (struct file *file)
{ {
if (!silent_flag) if (!silent_flag)
@@ -1117,11 +1126,11 @@ touch_file (struct file *file)
/* Print-only (-n) takes precedence over touch (-t). */ /* Print-only (-n) takes precedence over touch (-t). */
if (just_print_flag) if (just_print_flag)
return 0; return us_success;
#ifndef NO_ARCHIVES #ifndef NO_ARCHIVES
if (ar_name (file->name)) if (ar_name (file->name))
return ar_touch (file->name); return ar_touch (file->name) ? us_failed : us_success;
else else
#endif #endif
{ {
@@ -1158,7 +1167,7 @@ touch_file (struct file *file)
} }
} }
return 0; return us_success;
} }
/* Having checked and updated the dependencies of FILE, /* Having checked and updated the dependencies of FILE,
@@ -1172,17 +1181,17 @@ remake_file (struct file *file)
{ {
if (file->phony) if (file->phony)
/* Phony target. Pretend it succeeded. */ /* Phony target. Pretend it succeeded. */
file->update_status = 0; file->update_status = us_success;
else if (file->is_target) else if (file->is_target)
/* This is a nonexistent target file we cannot make. /* This is a nonexistent target file we cannot make.
Pretend it was successfully remade. */ Pretend it was successfully remade. */
file->update_status = 0; file->update_status = us_success;
else else
{ {
/* This is a dependency file we cannot remake. Fail. */ /* This is a dependency file we cannot remake. Fail. */
if (!rebuilding_makefiles || !file->dontcare) if (!rebuilding_makefiles || !file->dontcare)
complain (file); complain (file);
file->update_status = 2; file->update_status = us_failed;
} }
} }
else else
@@ -1197,7 +1206,7 @@ remake_file (struct file *file)
} }
/* This tells notice_finished_file it is ok to touch the file. */ /* This tells notice_finished_file it is ok to touch the file. */
file->update_status = 0; file->update_status = us_success;
} }
/* This does the touching under -t. */ /* This does the touching under -t. */
@@ -1249,7 +1258,7 @@ f_mtime (struct file *file, int search)
arlen = strlen (arfile->hname); arlen = strlen (arfile->hname);
memlen = strlen (memname); memlen = strlen (memname);
name = xmalloc (arlen + 1 + memlen + 2); name = alloca (arlen + 1 + memlen + 2);
memcpy (name, arfile->hname, arlen); memcpy (name, arfile->hname, arlen);
name[arlen] = '('; name[arlen] = '(';
memcpy (name + arlen + 1, memname, memlen); memcpy (name + arlen + 1, memname, memlen);
@@ -1259,9 +1268,9 @@ f_mtime (struct file *file, int search)
/* If the archive was found with GPATH, make the change permanent; /* If the archive was found with GPATH, make the change permanent;
otherwise defer it until later. */ otherwise defer it until later. */
if (arfile->name == arfile->hname) if (arfile->name == arfile->hname)
rename_file (file, name); rename_file (file, strcache_add (name));
else else
rehash_file (file, name); rehash_file (file, strcache_add (name));
check_renamed (file); check_renamed (file);
} }
@@ -1300,7 +1309,7 @@ f_mtime (struct file *file, int search)
/* If we found it in VPATH, see if it's in GPATH too; if so, /* If we found it in VPATH, see if it's in GPATH too; if so,
change the name right now; if not, defer until after the change the name right now; if not, defer until after the
dependencies are updated. */ dependencies are updated. */
if (gpath_search (name, strlen(name) - strlen(file->name) - 1)) if (gpath_search (name, strlen (name) - strlen (file->name) - 1))
{ {
rename_file (file, name); rename_file (file, name);
check_renamed (file); check_renamed (file);
@@ -1393,7 +1402,6 @@ f_mtime (struct file *file, int search)
started. So, turn off the intermediate bit so make doesn't started. So, turn off the intermediate bit so make doesn't
delete it, since it didn't create it. */ delete it, since it didn't create it. */
if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started
&& file->command_state == cs_not_started
&& !file->tried_implicit && file->intermediate) && !file->tried_implicit && file->intermediate)
file->intermediate = 0; file->intermediate = 0;
@@ -1628,7 +1636,7 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
std_dirs++; std_dirs++;
} }
buflen = strlen (libbuf); buflen = strlen (libbuf);
buf = xmalloc(libdir_maxlen + buflen + 2); buf = xmalloc (libdir_maxlen + buflen + 2);
} }
else if (buflen < strlen (libbuf)) else if (buflen < strlen (libbuf))
{ {

View File

@@ -3,7 +3,7 @@
Please do not send bug reports or questions about it to Please do not send bug reports or questions about it to
the Make maintainers. the Make maintainers.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -18,8 +18,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "job.h"
#include "filedef.h" #include "filedef.h"
#include "commands.h" #include "commands.h"
#include "job.h" #include "job.h"
@@ -80,7 +79,7 @@ start_remote_job_p (int first_p)
make_access (); make_access ();
if (ISDB (DB_JOBS)) if (ISDB (DB_JOBS))
Rpc_Debug(1); Rpc_Debug (1);
/* Ping the daemon once to see if it is there. */ /* Ping the daemon once to see if it is there. */
inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1; inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1;
@@ -188,10 +187,10 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
sin.sin_addr = permit.addr; sin.sin_addr = permit.addr;
status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT, status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
len, (Rpc_Opaque) waybill, len, (Rpc_Opaque) waybill,
sizeof(msg), (Rpc_Opaque) msg, sizeof (msg), (Rpc_Opaque) msg,
1, &timeout); 1, &timeout);
host = gethostbyaddr((char *)&permit.addr, sizeof(permit.addr), AF_INET); host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
if (status != RPC_SUCCESS) if (status != RPC_SUCCESS)
{ {
@@ -221,11 +220,11 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
fflush (stdout); fflush (stdout);
fflush (stderr); fflush (stderr);
pid = vfork (); pid = fork ();
if (pid < 0) if (pid < 0)
{ {
/* The fork failed! */ /* The fork failed! */
perror_with_name ("vfork", ""); perror_with_name ("fork", "");
return 1; return 1;
} }
else if (pid == 0) else if (pid == 0)

View File

@@ -1,5 +1,5 @@
/* Template for the remote job exportation interface to GNU Make. /* Template for the remote job exportation interface to GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include "filedef.h" #include "filedef.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"

12
rule.c
View File

@@ -1,5 +1,5 @@
/* Pattern and suffix rule internals for GNU Make. /* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,12 +14,12 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <assert.h> #include <assert.h>
#include "dep.h"
#include "filedef.h" #include "filedef.h"
#include "dep.h"
#include "job.h" #include "job.h"
#include "commands.h" #include "commands.h"
#include "variable.h" #include "variable.h"
@@ -70,7 +70,7 @@ count_implicit_rule_limits (void)
{ {
char *name; char *name;
int namelen; int namelen;
struct rule *rule, *lastrule; struct rule *rule;
num_pattern_rules = max_pattern_targets = max_pattern_deps = 0; num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
max_pattern_dep_length = 0; max_pattern_dep_length = 0;
@@ -78,7 +78,6 @@ count_implicit_rule_limits (void)
name = 0; name = 0;
namelen = 0; namelen = 0;
rule = pattern_rules; rule = pattern_rules;
lastrule = 0;
while (rule != 0) while (rule != 0)
{ {
unsigned int ndeps = 0; unsigned int ndeps = 0;
@@ -138,7 +137,6 @@ count_implicit_rule_limits (void)
if (ndeps > max_pattern_deps) if (ndeps > max_pattern_deps)
max_pattern_deps = ndeps; max_pattern_deps = ndeps;
lastrule = rule;
rule = next; rule = next;
} }
@@ -375,7 +373,7 @@ install_pattern_rule (struct pspec *p, int terminal)
++r->suffixes[0]; ++r->suffixes[0];
ptr = p->dep; ptr = p->dep;
r->deps = PARSE_FILE_SEQ (&ptr, struct dep, '\0', NULL, 0); r->deps = PARSE_SIMPLE_SEQ (&ptr, struct dep);
if (new_pattern_rule (r, 0)) if (new_pattern_rule (r, 0))
{ {

2
rule.h
View File

@@ -1,5 +1,5 @@
/* Definitions for using pattern rules in GNU Make. /* Definitions for using pattern rules in GNU Make.
Copyright (C) 1988-2012 Free Software Foundation, Inc. Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -1,5 +1,5 @@
/* Convert between signal names and numbers. /* Convert between signal names and numbers.
Copyright (C) 1990-2012 Free Software Foundation, Inc. Copyright (C) 1990-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
/* If the system provides strsignal, we don't need it. */ /* If the system provides strsignal, we don't need it. */
@@ -192,10 +192,10 @@ signame_init (void)
init_sig (SIGURG, "URG", _("Urgent I/O condition")); init_sig (SIGURG, "URG", _("Urgent I/O condition"));
#endif #endif
#if defined (SIGIO) #if defined (SIGIO)
/* "I/O pending" has also been suggested. A disadvantage is /* "I/O pending" has also been suggested. A disadvantage is that signal
that signal only happens when the process has only happens when the process has asked for it, not every time I/O is
asked for it, not everytime I/O is pending. Another disadvantage pending. Another disadvantage is the confusion from giving it a
is the confusion from giving it a different name than under Unix. */ different name than under Unix. */
init_sig (SIGIO, "IO", _("I/O possible")); init_sig (SIGIO, "IO", _("I/O possible"));
#endif #endif
#if defined (SIGWIND) #if defined (SIGWIND)
@@ -244,7 +244,7 @@ strsignal (int sig)
# endif # endif
#endif #endif
if (sig > 0 || sig < NSIG) if (sig > 0 && sig < NSIG)
return (char *) sys_siglist[sig]; return (char *) sys_siglist[sig];
sprintf (buf, "Signal %d", sig); sprintf (buf, "Signal %d", sig);

View File

@@ -1,5 +1,5 @@
/* Constant string caching for GNU Make. /* Constant string caching for GNU Make.
Copyright (C) 2006-2012 Free Software Foundation, Inc. Copyright (C) 2006-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -14,7 +14,7 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "make.h" #include "makeint.h"
#include <stddef.h> #include <stddef.h>
#include <assert.h> #include <assert.h>
@@ -57,7 +57,7 @@ static unsigned long total_size = 0;
that this doesn't seem to be much of an issue in practice. that this doesn't seem to be much of an issue in practice.
*/ */
static struct strcache * static struct strcache *
new_cache() new_cache ()
{ {
struct strcache *new; struct strcache *new;
new = xmalloc (bufsize + CACHE_BUFFER_OFFSET); new = xmalloc (bufsize + CACHE_BUFFER_OFFSET);
@@ -208,7 +208,7 @@ strcache_add_len (const char *str, unsigned int len)
} }
int int
strcache_setbufsize(unsigned int size) strcache_setbufsize (unsigned int size)
{ {
if (size > bufsize) if (size > bufsize)
bufsize = size; bufsize = size;
@@ -233,7 +233,7 @@ strcache_print_stats (const char *prefix)
if (! strcache) if (! strcache)
{ {
printf(_("\n%s No strcache buffers\n"), prefix); printf (_("\n%s No strcache buffers\n"), prefix);
return; return;
} }

View File

@@ -1,5 +1,5 @@
@echo off @echo off
rem Copyright (C) 1996-2012 Free Software Foundation, Inc. rem Copyright (C) 1996-2013 Free Software Foundation, Inc.
rem This file is part of GNU Make. rem This file is part of GNU Make.
rem rem
rem GNU Make is free software; you can redistribute it and/or modify it under rem GNU Make is free software; you can redistribute it and/or modify it under

View File

@@ -1,3 +0,0 @@
work
.*gdbinit
.gdb_history

1
tests/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
work

View File

@@ -1,3 +1,210 @@
2013-10-09 Paul Smith <psmith@gnu.org>
* scripts/features/patspecific_vars: Typo fixes.
2013-10-05 Paul Smith <psmith@gnu.org>
* test_driver.pl (run_all_tests): Rewrite to be more clear.
* scripts/features/jobserver: Avoid using $ENV{HOME} as it doesn't
exist everywhere.
* scripts/features/default_names: End with 1;
* scripts/features/loadapi: Use new calling signatures. Verify
the NOEXPAND flag works. Test with all valid function name
characters.
2013-09-29 Paul Smith <psmith@gnu.org>
* scripts/variables/SHELL: Solaris /bin/sh can't handle options in
multiple words; skip that test.
* scripts/targets/ONESHELL: Ditto.
* scripts/variables/GNUMAKEFLAGS: Verify that GNUMAKEFLAGS is
cleared and options are not duplicated.
2013-09-23 Paul Smith <psmith@gnu.org>
* scripts/options/print-directory: Rename dash-w to
print-directory to avoid conflicts with dash-W on case-insensitive
filesystems.
2013-09-22 Paul Smith <psmith@gnu.org>
* scripts/features/se_implicit: Verify that order-only tokens
inside second expansion are parsed correctly.
Test for Savannah bug #31155.
* run_make_tests.pl (set_more_defaults): If we can't find
gnumake.h based on the make program we might be running from a
remote build directory. Parse the Makefile for the right path.
Fix some test issues on Solaris.
* scripts/features/archives: Determine what output ar gives when
adding and replacing objects and compare with that.
* scripts/features/escape: Solaris /bin/sh doesn't properly handle
backslashes inside single quotes, so don't rely on it.
* scripts/features/output-sync: false(1) gives different exit
codes on different systems; use "exit 1" instead.
* scripts/features/parallelism: Increase the timeout for slower systems.
2013-09-21 Paul Smith <psmith@gnu.org>
* scripts/features/archives: Some versions of ar (MacOSX) generate
different output when creating archives. Run it and verify the
real output.
* scripts/features/default_names: MacOSX is, like Windows,
case-preserving / case-insensitive. Redo the test to avoid
checking for "UNIX".
* test_driver.pl (attach_default_output): Don't dup stdout into
stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
* scripts/features/se_explicit: Fix a test that behaves
differently with/without archive capability enabled.
* scripts/features/output-sync: Don't test output-sync if it's not
enabled. We also skip it if parallelism is not enabled, although
strictly speaking some of the output-sync tests are valid even
without parallelism.
* scripts/features/jobserver: Move some tests that require the
jobserver from features/parallelism to a separate suite. Only run
this if jobserver mode is enabled.
* scripts/features/output-sync: Test shell functions writing to
stderr in recipes: ensure it's captured via output-sync. Test
output generated while reading makefiles and make sure it's
captured via output-sync. Make sure that fatal errors dump the
output so it's not lost.
* scripts/options/dash-w: Add a test for -w flag.
2013-09-15 Paul Smith <psmith@gnu.org>
* scripts/misc/fopen-fail: Check for failure on infinite recursion.
* run_make_tests.pl (run_make_test): Allow the answer string to be
undef, which means that we shouldn't compare it at all. Only the
exit code matters in this case.
* test_driver.pl (compare_output): Ditto.
Test for Savannah bug #27374.
* scripts/features/parallelism: Test broken jobserver on recursion.
Test for Savannah bug #39934.
* scripts/options/eval: Verify --eval during restart.
Test for Savannah bug #39203.
2013-09-14 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync: Verify -Orecurse properly.
2013-09-12 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync: Modify for output sync behavior.
* scripts/variables/MAKE_RESTARTS: Ditto.
* scripts/variables/MAKEFLAGS: Remove mode for --trace.
* scripts/variables/GNUMAKEFLAGS: Ditto.
2013-07-22 Paul Smith <psmith@gnu.org>
* scripts/features/rule_glob: Add tests for wildcards in rules.
Test for Savannah bug #39310.
2013-07-09 Paul Smith <psmith@gnu.org>
* scripts/features/se_implicit: Add a test for SE rules depending
on other SE rules to be built.
2013-05-26 Paul Smith <psmith@gnu.org>
* scripts/features/archives: Test for Savannah bug #38442.
* scripts/misc/bs-nl: Test for Savannah bug #39035.
Add a test for Savannah bug #38945.
2013-05-22 Paul Smith <psmith@gnu.org>
* scripts/options/dash-n: Fix results after MAKEFLAGS fixes.
* scripts/variables/MAKEFLAGS: Ditto.
* scripts/variables/GNUMAKEFLAGS: Ditto.
2013-05-14 Paul Smith <psmith@gnu.org>
* scripts/features/loadapi: Add plugin_is_GPL_compatible symbol.
* scripts/features/load: Ditto.
2013-05-13 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync (output_sync_set): Update for new
--trace behavior.
2013-05-05 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync (output_sync_set): Remove
extraneous enter/leave lines, which are no longer printed.
Add tests for syncing command line printing.
(output_sync_set): Rename options: "job"->"line"; "make"->"recurse"
2013-05-04 Paul Smith <psmith@gnu.org>
* scripts/features/loadapi: Use the new alloc functions.
* scripts/features/output-sync (output_sync_set): New test for
ordered recursive output for -Ojob / -Otarget.
2013-05-03 Eli Zaretskii <eliz@gnu.org>
* scripts/features/load: Fix signatures of testload_gmk_setup and
explicit_setup, to bring them in line with the documentation.
2013-04-28 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync (output_sync_set): Add tests for
the per-job syntax mode.
(output_sync_set): Test improved error message location.
2013-04-15 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync (output_sync_set): New arg syntax.
2013-04-14 Paul Smith <psmith@gnu.org>
* scripts/features/output-sync: Rewrite to be more reliable.
* test_driver.pl (_run_command): Don't set SIGALRM until after we
start the child. Print errors to the top-level output, which will
be stderr.
(attach_default_output): Use a list of file handles as the stack.
(detach_default_output): Ditto.
* scripts/features/output-sync: Add a test for output-sync.
2013-02-25 Paul Smith <psmith@gnu.org>
* run_make_tests.pl (valid_option): Support the -srcdir flag.
(set_more_defaults): Set up $srcdir if it's not set yet.
* scripts/functions/guile: Verify gmk-eval doesn't expand twice.
* scripts/features/load: Rework to test just the load capability.
* scripts/features/loadapi: New set of tests for the load API.
2013-01-19 Paul Smith <psmith@gnu.org>
* scripts/features/load: Test loaded files with and without "./"
prefix. Add tests for automatically rebuilding loaded files if
they are out of date or non-existent.
2013-01-13 Paul Smith <psmith@gnu.org>
* scripts/features/archives: Add a check targets that have parens,
but are not archives. See Savannah bug #37878.
* scripts/options/dash-n: Verify -n is preserved after recursive /
re-exec. See Savannah bug #38051.
2013-01-12 Paul Smith <psmith@gnu.org>
* scripts/features/parallelism: Change rule so it doesn't depend
on invocation order, etc.
2012-10-29 Paul Smith <psmith@gnu.org> 2012-10-29 Paul Smith <psmith@gnu.org>
* scripts/features/load: New test suite for the "load" directive. * scripts/features/load: New test suite for the "load" directive.
@@ -443,7 +650,7 @@
* test_driver.pl (toplevel): Skip all hidden files/directories (ones * test_driver.pl (toplevel): Skip all hidden files/directories (ones
beginning with "."). beginning with ".").
* scripts/functions/andor: Tests for $(and ..) and $(or ...) * scripts/functions/andor: Tests for $(and ...) and $(or ...)
functions. functions.
2006-02-08 Boris Kolpackov <boris@kolpackov.net> 2006-02-08 Boris Kolpackov <boris@kolpackov.net>
@@ -530,9 +737,9 @@
2005-08-13 Boris Kolpackov <boris@kolpackov.net> 2005-08-13 Boris Kolpackov <boris@kolpackov.net>
* scripts/functions/wildcard: Wrap calls to $(wildcard ) with * scripts/functions/wildcard: Wrap calls to $(wildcard) with
$(sort) so that the resulting order is no longer filesystem- $(sort) so that the resulting order is no longer filesystem-
dependant. dependent.
2005-08-10 Boris Kolpackov <boris@kolpackov.net> 2005-08-10 Boris Kolpackov <boris@kolpackov.net>
@@ -623,7 +830,7 @@
2005-05-02 Paul D. Smith <psmith@gnu.org> 2005-05-02 Paul D. Smith <psmith@gnu.org>
* scripts/features/parallelism: Add a test for exporting recursive * scripts/features/parallelism: Add a test for exporting recursive
variables containing $(shell ) calls. Rewrite this script to use variables containing $(shell) calls. Rewrite this script to use
run_make_test() everywhere. run_make_test() everywhere.
2005-04-07 Paul D. Smith <psmith@gnu.org> 2005-04-07 Paul D. Smith <psmith@gnu.org>
@@ -1206,7 +1413,7 @@
ChangeLog file for the test suite created. ChangeLog file for the test suite created.
Copyright (C) 1992-2012 Free Software Foundation, Inc. Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -72,7 +72,7 @@ Changes from 0.4.4 to 0.4.5 (April 29, 1995):
Also, some tests and stuff still haven't made it in because I Also, some tests and stuff still haven't made it in because I
haven't had time to write the test scripts for them. But they, haven't had time to write the test scripts for them. But they,
too, will get in eventually. Contributions of scripts (ie, tests too, will get in eventually. Contributions of scripts (i.e., tests
that I can just drop in) are particularly welcome and will be that I can just drop in) are particularly welcome and will be
incorporated immediately. incorporated immediately.
@@ -162,7 +162,7 @@ Changes from 0.1 to 0.2 (5-4-92):
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 1992-2012 Free Software Foundation, Inc. Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the

View File

@@ -7,7 +7,7 @@ This entire test suite, including all test files, are copyright and
distributed under the following terms: distributed under the following terms:
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
Copyright (C) 1992-2012 Free Software Foundation, Inc. Copyright (C) 1992-2013 Free Software Foundation, Inc.
This file is part of GNU Make. This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the GNU Make is free software; you can redistribute it and/or modify it under the
@@ -38,7 +38,7 @@ To run the test suite on Windows NT or DOS systems, use
"perl.exe ./run_make-tests.pl". "perl.exe ./run_make-tests.pl".
By default, the test engine picks up the first executable called "make" By default, the test engine picks up the first executable called "make"
that it finds in your path. You may use the -make_path option (ie, that it finds in your path. You may use the -make_path option (i.e.,
"perl run_make_tests -make_path /usr/local/src/make-3.78/make") if "perl run_make_tests -make_path /usr/local/src/make-3.78/make") if
you want to run a particular copy. This now works correctly with you want to run a particular copy. This now works correctly with
relative paths and when make is called something other than "make" (like relative paths and when make is called something other than "make" (like
@@ -58,7 +58,7 @@ The options/dash-l test will not really test anything if the copy of
make you are using can't obtain the system load. Some systems require make you are using can't obtain the system load. Some systems require
make to be setgid sys or kmem for this; if you don't want to install make to be setgid sys or kmem for this; if you don't want to install
make just to test it, make it setgid to kmem or whatever group /dev/kmem make just to test it, make it setgid to kmem or whatever group /dev/kmem
is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the is (i.e., "chgrp kmem make;chmod g+s make" as root). In any case, the
options/dash-l test should no longer *fail* because make can't read options/dash-l test should no longer *fail* because make can't read
/dev/kmem. /dev/kmem.

Some files were not shown because too many files have changed in this diff Show More