Merge branch 'development' into upstream

Signed-off-by: Manoj Srivastava <srivasta@debian.org>
This commit is contained in:
Manoj Srivastava 2018-02-12 15:01:27 -08:00
commit 3a6e2c4eda
No known key found for this signature in database
GPG key ID: 36BD720F6F576472
146 changed files with 6793 additions and 2963 deletions

View file

@ -72,7 +72,7 @@ With suggestions/comments/bug reports from a cast of ... well ...
hundreds, anyway :)
-------------------------------------------------------------------------------
Copyright (C) 1997-2014 Free Software Foundation, Inc.
Copyright (C) 1997-2016 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

View file

@ -1,7 +1,7 @@
# -*-Makefile-*- template for DJGPP
# Makefile.in generated automatically by automake 1.2 from Makefile.am
#
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# Copyright (C) 1994-2016 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

View file

@ -1,6 +1,6 @@
# This is a -*-Makefile-*-, or close enough
#
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
# Copyright (C) 1997-2016 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
@ -16,8 +16,8 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = 1.8 dist-bzip2 check-news
ACLOCAL_AMFLAGS = -I config
AUTOMAKE_OPTIONS = dist-bzip2 silent-rules std-options
ACLOCAL_AMFLAGS = -I config
MAKE_HOST = @MAKE_HOST@
@ -26,6 +26,9 @@ if WINDOWSENV
MAYBE_W32 = w32
W32INC = -I $(top_srcdir)/w32/include
W32LIB = -Lw32 -lw32
ossrc =
else
ossrc = posixos.c
endif
SUBDIRS = glob config po $(MAYBE_W32)
@ -41,14 +44,14 @@ endif
make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \
function.c getopt.c getopt1.c guile.c implicit.c job.c load.c \
loadapi.c main.c misc.c output.c read.c remake.c rule.c \
signame.c strcache.c variable.c version.c vpath.c hash.c \
$(remote)
loadapi.c main.c misc.c $(ossrc) output.c read.c remake.c \
rule.c signame.c strcache.c variable.c version.c vpath.c \
hash.c $(remote)
EXTRA_make_SOURCES = vmsjobs.c remote-stub.c remote-cstms.c
noinst_HEADERS = commands.h dep.h filedef.h job.h makeint.h rule.h variable.h \
debug.h getopt.h gettext.h hash.h output.h
debug.h getopt.h gettext.h hash.h output.h os.h
make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ \
$(GUILE_LIBS)
@ -71,7 +74,7 @@ endif
# Extra stuff to include in the distribution.
EXTRA_DIST = README build.sh.in $(man_MANS) \
EXTRA_DIST = ChangeLog README build.sh.in $(man_MANS) \
README.customs README.OS2 \
SCOPTIONS SMakefile \
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h \
@ -79,7 +82,8 @@ EXTRA_DIST = README build.sh.in $(man_MANS) \
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat \
make_msvc_net2003.sln make_msvc_net2003.vcproj \
README.VMS makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c \
vmsdir.h vmsfunctions.c vmsify.c vms_exit.c vms_progname.c \
vms_export_symbol.c vms_export_symbol_test.com \
gmk-default.scm gmk-default.h
# This is built during configure, but behind configure's back
@ -125,8 +129,8 @@ guile.$(OBJEXT): gmk-default.h
gmk-default.h: $(srcdir)/gmk-default.scm
(echo 'static const char *const GUILE_module_defn = " '\\ \
&& sed -e 's/;.*//' -e '/^[ \t]*$$/d' -e 's/"/\\"/g' -e 's/$$/ \\/' \
$(srcdir)/gmk-default.scm \
&& echo '";') > $@
$(srcdir)/gmk-default.scm \
&& echo '";') > $@
# --------------- Local DIST Section
@ -174,6 +178,7 @@ MAKETESTFLAGS =
check-regression: tests/config-flags.pm
@if test -f '$(srcdir)/tests/run_make_tests'; then \
ulimit -n 128; \
if $(PERL) -v >/dev/null 2>&1; then \
case `cd '$(srcdir)'; pwd` in `pwd`) : ;; \
*) test -d tests || mkdir tests; \
@ -188,9 +193,9 @@ check-regression: tests/config-flags.pm
else \
echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \
fi; \
else \
else \
echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \
fi
fi
# --------------- Maintainer's Section

View file

@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile, run
# 'build.sh' instead.
#
# Copyright (C) 1995-2014 Free Software Foundation, Inc.
# Copyright (C) 1995-2016 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

313
NEWS
View file

@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
05 Oct 2014
10 June 2016
See the end of this file for copyrights and conditions.
@ -8,6 +8,54 @@ All changes mentioned here are more fully described in the GNU make
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
reporting bugs.
Version 4.2.1 (10 Jun 2016)
A complete list of bugs fixed in this version is available here:
h
ttp://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=107&set=custom
This release is a bug-fix release.
Version 4.2 (22 May 2016)
A complete list of bugs fixed in this version is available here:
http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=106&set=custom
* New variable: $(.SHELLSTATUS) is set to the exit status of the last != or
$(shell ...) function invoked in this instance of make. This will be "0" if
successful or not "0" if not successful. The variable value is unset if no
!= or $(shell ...) function has been invoked.
* The $(file ...) function can now read from a file with $(file <FILE).
The function is expanded to the contents of the file. The contents are
expanded verbatim except that the final newline, if any, is stripped.
* The makefile line numbers shown by GNU make now point directly to the
specific line in the recipe where the failure or warning occurred.
Sample changes suggested by Brian Vandenberg <phantall@gmail.com>
* The interface to GNU make's "jobserver" is stable as documented in the
manual, for tools which may want to access it.
WARNING: Backward-incompatibility! The internal-only command line option
--jobserver-fds has been renamed for publishing, to --jobserver-auth.
* The amount of parallelism can be determined by querying MAKEFLAGS, even when
the job server is enabled (previously MAKEFLAGS would always contain only
"-j", with no number, when job server was enabled).
* VMS-specific changes:
* Perl test harness now works.
* Full support for converting Unix exit status codes to VMS exit status
codes. BACKWARD INCOMPATIBILITY Notice: On a child failure the VMS exit
code is now the encoded Unix exit status that Make usually generates, not
the VMS exit status of the child.
Version 4.1 (05 Oct 2014)
@ -29,6 +77,33 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=105&set
make. Makefiles that rely on this syntax should be fixed.
See https://savannah.gnu.org/bugs/?33034
* VMS-specific changes:
* Support for library files added, including support for using the GNV ar
utility.
* Partial support for properly encoding Unix exit status codes into VMS exit
status codes.
WARNING: Backward-incompatibility! These are different exit status codes
than Make exited with in the past.
* Macros to hold the current make command are set up to translate the
argv[0] string to a VMS format path name and prefix it with "MCR " so that
the macro has a space in it.
WARNING: Backward-incompatibility! This may break complex makefiles that
do processing on those macros. This is unlikely because so much in that
area was not and is still not currently working on VMS, it is unlikely to
find such a complex makefile, so this is more likely to impact
construction of a future makefile.
* A command file is always used to run the commands for a recipe.
WARNING: Backward-incompatibility! Running the make self tests has
exposed that there are significant differences in behavior when running
with the command file mode. It is unknown if this will be noticed by most
existing VMS makefiles.
Version 4.0 (09 Oct 2013)
@ -237,6 +312,57 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=104&set
after the variable name, to allow for simple, conditional, or appending
multi-line variable assignment.
* VMS-specific changes:
* 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
adjusted to GMT based time, if the local VMS time was using a daylight
saving algorithm and if daylight saving was switched off.
* John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to
append output redirection in action lines.
* Rework of ctrl+c and ctrl+y handling.
* Fix a problem with cached strings, which showed on case-insensitive file
systems.
* Build fixes for const-ified code in VMS specific sources.
* 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 feature like ">>" to have DCL command or program
output redirected and appended to a file. GNU make for VMS already
implements the redirection of output. If such a redirection is detected,
an ">" on the action line, GNU make creates a DCL command procedure to
execute the action and to redirect its output. Based on that, now ">>"
is also recognized and a similar but different command procedure is
created to implement the append. The main idea here is to create a
temporary file which collects the output and which is appended to the
wanted output file. Then the temporary file is deleted. This is all done
in the command procedure to keep changes in make small and simple. This
obviously has some limitations but it seems good enough compared with
the current ">" implementation. (And in my opinion, redirection is not
really what GNU make has to do.) With this approach, it may happen that
the temporary file is not yet appended and is left in SYS$SCRATCH.
The temporary file names look like "CMDxxxxx.". Any time the created
command procedure can not complete, this 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 CMDxxxxx.COM.
* 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.
* Change in deleteing temporary command files. Temporary command files
are now deleted in the vms child termination handler. That deletes
them even if a Ctrl+C was pressed.
* 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 long, Ctrl+Y should be used instead.
Version 3.81 (01 Apr 2006)
@ -456,6 +582,42 @@ Version 3.80 (03 Oct 2002)
* Updated to autoconf 2.54 and automake 1.7. Users should not be impacted.
* VMS-specific changes:
* In default.c define variable ARCH as IA64 for VMS on Itanium systems.
* In makefile.vms avoid name collision for glob and globfree.
* This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
GNU Make 3.60 by Mike Moretti.
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
versions of DECC were used. VAXC was tried: it fails; but it doesn't
seem worth to get it working. There are still some PTRMISMATCH warnings
during the compile. Although perl is working on VMS the test scripts
don't work. The function $shell is still missing.
There is a known bug in some of the VMS CRTLs. It is in the shipped
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
shipped with newer VMS versions and all ECO kits after October 1999. It
only shows up during the daylight saving time period (DST): stat()
returns a modification time 1 hour ahead. This results in GNU make
warning messages. For a just created source you will see:
$ gmake x.exe
gmake.exe;1: *** Warning: File 'x.c' has modification time in the future
(940582863 > 940579269)
cc /obj=x.obj x.c
link x.obj /exe=x.exe
gmake.exe;1: *** Warning: Clock skew detected. Your build may be
incomplete.
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
@ -512,6 +674,56 @@ Version 3.79 (04 Apr 2000)
* Hartmut Becker provided many updates for the VMS port of GNU make.
See the README.VMS file for more details.
* VMS-specific changes:
* Fix a problem with automatically remaking makefiles. GNU make uses an
execve to restart itself after a successful remake of the makefile. On
UNIX systems execve replaces the running program with a new one and
resets all signal handling to the default. On VMS execve creates a child
process, signal and exit handlers of the parent are still active, and,
unfortunately, corrupt the exit code from the child. Fix in job.c:
ignore SIGCHLD.
* Added some switches to reflect latest features of DECC. Modifications in
makefile.vms.
* Set some definitions to reflect latest features of DECC. Modifications in
config.h-vms (which is copied to config.h).
* Added extern strcmpi declaration to avoid 'implicitly declared' messages.
Modification in make.h.
* Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
Compaq c/c++ compilers. Modifications in default.c.
* Usage of opendir() and friends, suppress file version. Modifications in
dir.c.
* Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
Modifications in job.c.
* Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
.SUFFIXES :
.SUFFIXES : .class .java
.java.class :
javac "$<
HelloWorld.class : HelloWorld.java
* A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled. The
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
Modifications in file.c and config.h-vms.
* Bootstrap make to start building make is still makefile.com, but make
needs to be re-made with a make to make a correct version: ignore all
possible warnings, delete all objects, rename make.exe to a different
name and run it.
* Made some minor modifications to the bootstrap build makefile.com.
Version 3.78 (22 Sep 1999)
@ -614,6 +826,45 @@ Version 3.77 (28 Jul 1998)
* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32),
and to the DOS port from Eli Zaretski (see README.DOS).
* VMS-specific changes:
* This is the VMS port of GNU Make.
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
This port was done by Klaus Kämpf <kkaempf@rmi.de>
* There is first-level support available from proGIS Software, Germany.
Visit their web-site at http://www.progis.de to get information
about other vms software and forthcoming updates to gnu make.
* /bin/sh style I/O redirection is supported. You can now write lines like
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
* Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override VMS symbols/logicals !
* Functions for file names are working now. See the GNU Make manual for
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
supported as arguments.
* The default rules are set up for GNU C. Building an executable from a
single source file is as easy as 'make file.exe'.
* The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
different VMS systems can now be written by checking $(ARCH) as in
ifeq ($(ARCH),ALPHA)
$(ECHO) "On the Alpha"
else
$(ECHO) "On the VAX"
endif
* Command lines of excessive length are correctly broken and written to a
batch file in sys$scratch for later execution. There's no limit to the
lengths of commands (and no need for .opt files :-) any more.
* Empty commands are handled correctly and don't end in a new DCL process.
Version 3.76.1 (19 Sep 1997)
@ -662,8 +913,54 @@ Version 3.76 (16 Sep 1997)
concerning this port to Eli Zaretskii <eliz@is.elta.co.il> or DJ
Delorie <dj@delorie.com>.
* John W. Eaton has updated the VMS port to support libraries and VPATH.
* VMS-specific changes:
* John W. Eaton has updated the VMS port to support libraries and VPATH.
* The cd command is supported if it's called as $(CD). This invokes
the 'builtin_cd' command which changes the directory.
Calling 'set def' doesn't do the trick, since a sub-shell is
spawned for this command, the directory is changed *in this sub-shell*
and the sub-shell ends.
* Libraries are not supported. They were in GNU Make 3.60 but somehow I
didn't care porting the code. If there is enough interest, I'll do it at
some later time.
* The variable $^ separates files with commas instead of spaces (It's the
natural thing to do for VMS).
* See defaults.c for VMS default suffixes and my definitions for default
rules and variables.
* The shell function is not implemented yet.
* Load average routines haven't been implemented for VMS yet.
* The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
* The default makefiles make looks for are: makefile.vms, gnumakefile,
makefile., and gnumakefile. .
* The stat() function and handling of time stamps in VMS is broken, so I
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
less than what vms provides. This might be a problem on the faster Alphas.
* You can use a : in a filename only if you precede it with a backslash ('\').
E.g.- hobbes\:[bogas.files]
* Make ignores success, informational, or warning errors (-S-, -I-, or -W-).
But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
* Remote stuff isn't implemented yet.
* Multiple line DCL commands, such as "if" statements, must be put inside
command files. You can run a command file by using \@.
Version 3.75 (27 Aug 1996)
* The directory messages printed by `-w' and implicitly in sub-makes,
@ -684,6 +981,14 @@ Version 3.75 (27 Aug 1996)
* Rob Tulloh of Tivoli Systems has contributed a port to Windows NT or 95.
See README.W32 for details, and direct all Windows-related questions to
<rob_tulloh@tivoli.com>.
* VMS-specific changes:
* Lots of default settings are adapted for VMS. See default.c.
* Long command lines are now converted to command files.
* Comma (',') as a separator is now allowed. See makefile.vms for an example.
Version 3.73 (05 Apr 1995)
@ -1219,7 +1524,7 @@ Version 3.05
(Changes from versions 1 through 3.05 were never recorded. Sorry.)
-------------------------------------------------------------------------------
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

2
README
View file

@ -162,7 +162,7 @@ at the right README!
-------------------------------------------------------------------------------
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

View file

@ -61,7 +61,7 @@ If you plan to use recursive makes, install make resident:
-------------------------------------------------------------------------------
Copyright (C) 1995-2014 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View file

@ -324,7 +324,7 @@ Bug reports:
-------------------------------------------------------------------------------
Copyright (C) 1996-2014 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

View file

@ -160,7 +160,7 @@ from the make source tree.
-------------------------------------------------------------------------------
Copyright (C) 2003-2014 Free Software Foundation, Inc.
Copyright (C) 2003-2016 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

View file

@ -1,284 +1,515 @@
This version of GNU make has been tested on
OpenVMS V8.3 (Alpha) and V8.4 (Integrity).
Overview: -*-text-mode-*-
---------
Build instructions
This version of GNU make has been tested on:
OpenVMS V8.3/V8.4 (Alpha) and V8.4 (Integrity) AND V7.3 (VAX)
This version of GNU Make is intended to be run from DCL to run
make scripts with a special syntax that is described below. It
likely will not be able to run unmodified Unix makefiles.
There is an older implementation of GNU Make that was ported to GNV.
Work is now in progress to merge that port to get a single version
of GNU Make available. When that merge is done, GNU Make will auto
detect that it is running under a Posix shell and then operate as close to
GNU Make on Unix as possible.
The descriptions below are for running GNU make from DCL or equivalent.
Recipe differences:
-------------------
GNU Make for OpenVMS can not currently run native Unix make files because of
differences in the implementation.
I am trying to document the current behavior in this section. This is based
on the information in the file NEWS. and running the test suite.
TODO: More tests are needed to validate and demonstrate the OpenVMS
expected behavior.
In some cases the older behavior of GNU Make when run from DCL is not
compatible with standard makefile behavior.
This behavior can be changed when running GNU Make from DCL by setting
either DCL symbols or logical names of the format GNV$. The settings
are enabled with a string starting with one of '1', 'T', or 'E' for "1",
"TRUE", or "ENABLE". They are disabled with a '0', 'F', or 'D' for "1",
"FALSE", or "DISABLE". If they are not explicitly set to one of these
values, then they will be set to their default values.
The value of the setting DECC$FILENAME_UNIX_REPORT or
DECC$FILENAME_UNIX_ONLY will now cause the $(dir x) function to return
'./' or '[]' as appropriate.
The name GNV$MAKE_OLD_VMS when enabled will cause GNU Make to behave as
much as the older method as can be done with out disabling VMS features.
When it is disabled GNU Make have the new behavior which more closely
matches Unix Make behavior.
The default is currently the old behavior when running GNU Make from DCL.
In the future this may change. When running make from GNV Bash the new
behavior is the default.
This is a global setting that sets the default behavior for several other
options that can be individually changed. Many of the individual settings
are to make it so that the self tests for GNU Make need less VMS specific
modifications.
The name GNV$MAKE_COMMA when enabled will cause GNU Make to expect a comma
for a path separator and use a comma for the separator for a list of files.
When disabled, it will cause GNU Make to use a colon for a path separator
and a space for the separator for a list of files. The default is to be
enabled if the GNU Make is set to the older behavior.
The name GNV$MAKE_SHELL_SIM when enabled will cause GNU Make to try to
simulate a Posix shell more closely. The following behaviors occur:
* Single quotes are converted to double quotes and any double
quotes inside of them are doubled. No environment variable expansion
is simulated.
* A exit command status will be converted to a Posix Exit
where 0 is success and non-zero is failure.
* The $ character will cause environment variable expansion.
* Environent variables can be set on the command line before a command.
VMS generally uses logical name search lists instead of path variables
where the resolution is handled by VMS independent of the program. Which
means that it is likely that nothing will notice if the default path
specifier is changed in the future.
Currently the built in VMS specific macros and recipes depend on the comma
being used as a file list separator.
TODO: Remove this dependency as other functions in GNU Make depend on a
space being used as a separator.
The format for recipes are a combination of Unix macros, a subset of
simulated UNIX commands, some shell emulation, and OpenVMS commands.
This makes the resulting makefiles unique to the OpenVMS port of GNU make.
If you are creating a OpenVMS specific makefile from scratch, you should also
look at MMK (Madgoat Make) available at https://github.com/endlesssoftware/mmk
MMK uses full OpenVMS syntax and a persistent subprocess is used for the
recipe lines, allowing multiple line rules.
The default makefile search order is "makefile.vms", "gnumakefile",
"makefile". TODO: See if that lookup is case sensitive.
When Make is invoked from DCL, it will create a foreign command
using the name of executable image, with any facility prefix removed,
for the duration of the make program, so it can be used internally
to recursively run make(). The macro MAKE_COMMAND will be set to
this foreign command.
When make is launched from an exec*() command from a C program,
the foreign command is not created. The macro MAKE_COMMAND will be
set to the actual command passed as argv[0] to the exec*() function.
If the DCL symbol or logical name GNV$MAKE_USE_MCR exists, then
the macro MAKE_COMMAND will be set to be an "MCR" command with the
absolute path used by DCL to launch make. The foreign command
will not be created.
The macro MAKE is set to be the same value as the macro MAKE_COMMAND
on all platforms.
Each recipe command is normally run as a separate spawned processes,
except for the cases documented below where a temporary DCL command
file may be used.
BUG: Testing has shown that the commands in the temporary command files
are not always created properly. This issue is still under investigation.
Any macros marked as exported are temporarily created as DCL symbols
for child images to use. DCL symbol substitution is not done with these
commands.
Untested: Symbol substitution.
When a temporary DCL command file is used, DCL symbol substitution
will work.
For VMS 7.3-1 and earlier, command lines are limited to 255 characters
or 1024 characters in a command file.
For VMS 7.3-2 and later, command lines are limited to 4059 characters
or 8192 characters in a command file.
VMS limits each token of a command line to 256 characters, and limits
a command line to 127 tokens.
Command lines above the limit length are written to a command file
in sys$scratch:.
In order to handle Unix style extensions to VMS DCL, GNU Make has
parsed the recipe commands and them modified them as needed. The
parser has been re-written to resolve numerous bugs in handling
valid VMS syntax and potential buffer overruns.
The new parser may need whitespace characters where DCL does not require
it, and also may require that quotes are matched were DCL forgives if
they are not. There is a small chance that existing VMS specific makefiles
will be affected.
The '<', '>' was previously implemented using command files. Now
GNU Make will check to see if the is already a VMS "PIPE" command and
if it is not, will convert the command to a VMS "PIPE" command.
The '>>' redirection has been implemented by using a temporary command file.
This will be described later.
The DCL symbol or logical name GNV$MAKE_USE_CMD_FILE when set to a
string starting with one of '1','T', or 'E' for "1", "TRUE", or "ENABLE",
then temporary DCL command files are always used for running commands.
Some recipe strings with embedded new lines will not be handled correctly
when a command file is used.
GNU Make generally does text comparisons for the targets and sources. The
make program itself can handle either Unix or OpenVMS format filenames, but
normally does not do any conversions from one format to another.
TODO: The OpenVMS format syntax handling is incomplete.
TODO: ODS-5 EFS support is missing.
BUG: The internal routines to convert filenames to and from OpenVMS format
do not work correctly.
Note: In the examples below, line continuations such as a backslash may have
been added to make the examples easier to read in this format.
BUG: That feature does not completely work at this time.
Since the OpenVMS utilities generally expect OpenVMS format paths, you will
usually have to use OpenVMS format paths for rules and targets.
BUG: Relative OpenVMS paths may not work in targets, especially combined
with vpaths. This is because GNU make will just concatenate the directories
as it does on Unix.
The variables $^ and $@ separate files with commas instead of spaces.
This is controlled by the name GNV$MAKE_COMMA as documented in the
previous section.
While this may seem the natural thing to do with OpenVMS, it actually
causes problems when trying to use other make functions that expect the
files to be separated by spaces. If you run into this, you need the
following workaround to convert the output.
TODO: Look at have the $^ and $@ use spaces like on Unix and have
and easy to use function to do the conversions and have the built
in OpenVMS specific recipes and macros use it.
Example:
comma := ,
empty :=
space := $(empty) $(empty)
foo: $(addsuffix .3,$(subs $(comma),$(space),$^)
Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override OpenVMS symbols/logicals.
OpenVMS logical and symbols names show up as "environment" using the
origin function. when the "-e" option is specified, the origion function
shows them as "environment override". On Posix the test scripts indicate
that they should show up just as "environment".
When GNU make reads in a symbol or logical name into the environment, it
converts any dollar signs found to double dollar signs for convenience in
using DCL symbols and logical names in recipes. When GNU make exports a
DCL symbol for a child process, if the first dollar sign found is followed
by second dollar sign, then all double dollar signs will be convirted to
single dollar signs.
The variable $(ARCH) is predefined as IA64, ALPHA or VAX respectively.
Makefiles for different OpenVMS systems can now be written by checking
$(ARCH). Since IA64 and ALPHA are similar, usually just a check for
VAX or not VAX is sufficient.
You may have to update makefiles that assume VAX if not ALPHA.
ifeq ($(ARCH),VAX)
$(ECHO) "On the VAX"
else
$(ECHO) "On the ALPHA or IA64"
endif
Empty commands are handled correctly and don't end in a new DCL process.
The exit command needs to have OpenVMS exit codes. To pass a Posix code
back to the make script, you need to encode it by multiplying it by 8
and then adding %x1035a002 for a failure code and %x1035a001 for a
success. Make will interpret any posix code other than 0 as a failure.
TODO: Add an option have simulate Posix exit commands in recipes.
Lexical functions can be used in pipes to simulate shell file test rules.
Example:
Posix:
b : c ; [ -f $@ ] || echo >> $@
OpenVMS:
b : c ; if f$$search("$@") then pipe open/append xx $@ ; write xx "" ; close xx
You can also use pipes and turning messages off to silently test for a
failure.
x = %x1035a00a
%.b : %.c
<tab>pipe set mess/nofac/noiden/nosev/notext ; type $^/output=$@ || exit $(x)
Runtime issues:
The OpenVMS C Runtime has a convention for encoding a Posix exit status into
to OpenVMS exit codes. These status codes will have the hex value of
0x35a000. OpenVMS exit code may also have a hex value of %x10000000 set on
them. This is a flag to tell DCL not to write out the exit code.
To convert an OpenVMS encoded Posix exit status code to the original code
You subtract %x35a000 and any flags from the OpenVMS code and divide it by 8.
WARNING: Backward-incompatibility!
The make program exit now returns the same encoded Posix exit code as on
Unix. Previous versions returned the OpenVMS exit status code if that is what
caused the recipe to fail.
TODO: Provide a way for scripts calling make to obtain that OpenVMS status
code.
Make internally has two error codes, MAKE_FAILURE and MAKE_TROUBLE. These
will have the error "-E-" severity set on exit.
MAKE_TROUBLE is returned only if the option "-q" or "--question" is used and
has a Posix value of 1 and an OpenVMS status of %x1035a00a.
MAKE_FAILURE has a Posix value of 2 and an OpenVMS status of %x1035a012.
Output from GNU make may have single quotes around some values where on
other platforms it does not. Also output that would be in double quotes
on some platforms may show up as single quotes on VMS.
There may be extra blank lines in the output on VMS.
https://savannah.gnu.org/bugs/?func=detailitem&item_id=41760
There may be a "Waiting for unfinished jobs..." show up in the output.
Error messages generated by Make or Unix utilities may slightly vary from
Posix platforms. Typically the case may be different.
When make deletes files, on posix platforms it writes out 'rm' and the list
of files. On VMS, only the files are writen out, one per line.
TODO: VMS
There may be extra leading white space or additional or missing whitespace
in the output of recipes.
GNU Make uses sys$scratch: for the tempfiles that it creates.
The OpenVMS CRTL library maps /tmp to sys$scratch if the TMP: logical name
does not exist. As the CRTL may use both sys$scratch: and /tmp internally,
if you define the TMP logical name to be different than SYS$SCRATCH:,
you may end up with only some temporary files in TMP: and some in SYS$SCRATCH:
The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
TODO: A better default may be desired.
If the device for a file in a recipe does not exist, on OpenVMS an error
message of "stat: <file>: no such device or address" will be output.
Make ignores success, informational, or warning errors (-S-, -I-, or
-W-). But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
Unix compatibilty features:
---------------------------
If the command 'echo' is seen, any single quotes on the line will be
converted to double quotes.
The variable $(CD) is implemented as a built in Change Directory
command. This invokes the 'builtin_cd' Executing a 'set default'
recipe doesn't do the trick, since it only affects the subprocess
spawned for that command.
The 'builtin_cd' is generally expected to be on its own line.
The 'builtin_cd' either from the expansion of $(CD) or directly
put in a recipe line will be executed before any other commands in
that recipe line. DCL parameter substitution will not work for the
'builtin_cd' command.
Putting a 'builtin_cd' in a pipeline or an IF-THEN line should not be
done because the 'builtin_cd' is always executed
and executed first. The directory change is persistent.
Unix shell style I/O redirection is supported. You can now write lines like:
"<tab>mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt"
Posix shells have ":" as a null command. These are now handled.
https://savannah.gnu.org/bugs/index.php?41761
A note on appending the redirected output. A simple mechanism is
implemented to make ">>" work in action lines. In OpenVMS there is no simple
feature like ">>" to have DCL command or program output redirected and
appended to a file. GNU make for OpenVMS implements the redirection
of ">>" by using a command procedure.
The current algorithm creates the output file if it does not exist and
then uses the DCL open/append to extend it. SYS$OUTPUT is then directed
to that file.
The implementation supports only one redirected append output to a file
and that redirection is done before any other commands in that line
are executed, so it redirects all output for that command.
The older implementation wrote the output to a temporary file in
in sys$scratch: and then attempted to append the file to the existing file.
The temporary file names looked like "CMDxxxxx.". Any time the created
command procedure can not complete, this happens. Pressing Ctrl+Y to
abort make is one case.
In case of Ctrl+Y the associated command procedure is left in SYS$SCRATCH:.
The command procedures will be named gnv$make_cmd*.com.
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.
Temporary command files are now deleted in the OpenVMS child termination
handler. That deletes them even if a Ctrl+C was pressed.
TODO: Does the previous section about >> leaving files still apply?
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
long, Ctrl+Y should be used instead.
Build Options:
Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
<TAB>.SUFFIXES :
<TAB>.SUFFIXES : .class .java
<TAB>.java.class :
<TAB><TAB>javac "$<"
<TAB>HelloWorld.class : HelloWorld.java
A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled.
TODO: This should be a run-time setting based on if the process
has been set to case sensitive.
Unimplemented functionality:
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 OpenVMS does not support running multiple commands simultaneously.
Self test failures and todos:
-----------------------------
The test harness can not handle testing some of the VMS specific modes
because of the features needed for to be set for the Perl to run.
Need to find a way to set the VMS features before running make as a
child.
GNU make was not currently translating the OpenVMS encoded POSIX values
returned to it back to the Posix values. I have temporarily modified the
Perl test script to compensate for it. This should be being handled
internally to Make.
TODO: Verify and update the Perl test script.
The features/parallelism test was failing. OpenVMS is executing the rules
in sequence not in parallel as this feature was not implemented.
GNU Make on VMS no longer claims it is implemented.
TODO: Implement it.
Symlink support is not present. Symlinks are supported by OpenVMS 8.3 and
later.
Error messages should be supressed with the "-" at the beginning of a line.
On openVMS they were showing up. TODO: Is this still an issue?
The internal vmsify and unixify OpenVMS to/from UNIX are not handling logical
names correctly.
Build instructions:
------------------
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.
Make a 1st version
$ @makefile.com ! ignore any compiler and/or linker warning
$ copy make.exe 1st-make.exe
Use the 1st version to generate a 2nd version
Use the 1st version to generate a 2nd version as a test.
$ mc sys$disk:[]1st-make clean ! ignore any file not found messages
$ mc sys$disk:[]1st-make
Verify your 2nd version
Verify your 2nd version by building Make again.
$ copy make.exe 2nd-make.exe
$ mc sys$disk:[]2nd-make clean
$ 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
---------------------------
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.
Running the tests:
------------------
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
Running the tests on OpenVMS requires the following software to be installed
as most of the tests are Unix oriented.
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
adjusted to GMT based time, if the local VMS time was using a daylight saving
algorithm and if daylight saving was switched off.
* Perl 5.18 or later.
https://sourceforge.net/projects/vmsperlkit/files/
* GNV 2.1.3 + Updates including a minimum of:
* Bash 4.3.30
* ld_tools 3.0.2
* coreutils 8.21
https://sourceforge.net/p/gnv/wiki/InstallingGNVPackages/
https://sourceforge.net/projects/gnv/files/
John Eisenbraun (at HP dot COM) supplied fixes and and an enhancement to append
output redirection in action lines.
As the test scripts need to create some foreign commands that persist
after the test is run, it is recommend that either you use a subprocess or
a dedicated login to run the tests.
Rework of ctrl+c and ctrl+y handling.
To get detailed information for running the tests:
Fix a problem with cached strings, which showed on case-insensitive file
systems.
$ set default [.tests]
$ @run_make_tests help
Build fixes for const-ified code in VMS specific sources.
Running the script with no parameters will run all the tests.
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
feature like ">>" to have DCL command or program output redirected and appended
to a file. GNU make for VMS already implements the redirection of output. If
such a redirection is detected, an ">" on the action line, GNU make creates a
DCL command procedure to execute the action and to redirect its output. Based
on that, now ">>" is also recognized and a similar but different command
procedure is created to implement the append. The main idea here is to create a
temporary file which collects the output and which is appended to the wanted
output file. Then the temporary file is deleted. This is all done in the
command procedure to keep changes in make small and simple. This obviously has
some limitations but it seems good enough compared with the current ">"
implementation. (And in my opinion, redirection is not really what GNU make has
to do.) With this approach, it may happen that the temporary file is not yet
appended and is left in SYS$SCRATCH. The temporary file names look like
"CMDxxxxx.". Any time the created command procedure can not complete, this
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
CMDxxxxx.COM.
After the the test script has been run once in a session, assuming
that you built make in sys$disk:[make], you can redefined the
"bin" logical name as follows:
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.
$ define bin sys$disk:[make],gnv$gnu:[bin]
Change in deleteing temporary command files. Temporary command files are now
deleted in the vms child termination handler. That deletes them even if
a Ctrl+C was pressed.
Then you can use Perl to run the scripts.
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
long, Ctrl+Y should be used instead.
Changes for GNU make 3.80
$ perl run_make_tests.pl
. In default.c define variable ARCH as IA64 for VMS on Itanium systems.
. In makefile.vms avoid name collision for glob and globfree.
This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
Acknowlegements:
----------------
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
GNU Make 3.60 by Mike Moretti.
See NEWS. for details of past changes.
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
versions of DECC were used. VAXC was tried: it fails; but it doesn't
seem worth to get it working. There are still some PTRMISMATCH warnings
during the compile. Although perl is working on VMS the test scripts
don't work. The function $shell is still missing.
These are the currently known contributers to this port.
There is a known bug in some of the VMS CRTLs. It is in the shipped
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
shipped with newer VMS versions and all ECO kits after October 1999. It
only shows up during the daylight saving time period (DST): stat()
returns a modification time 1 hour ahead. This results in GNU make
warning messages. For a just created source you will see:
$ gmake x.exe
gmake.exe;1: *** Warning: File 'x.c' has modification time in the future (940582863 > 940579269)
cc /obj=x.obj x.c
link x.obj /exe=x.exe
gmake.exe;1: *** Warning: Clock skew detected. Your build may be incomplete.
New in 3.78.1:
Fix a problem with automatically remaking makefiles. GNU make uses an
execve to restart itself after a successful remake of the makefile. On
UNIX systems execve replaces the running program with a new one and
resets all signal handling to the default. On VMS execve creates a child
process, signal and exit handlers of the parent are still active, and,
unfortunately, corrupt the exit code from the child. Fix in job.c:
ignore SIGCHLD.
Added some switches to reflect latest features of DECC. Modifications in
makefile.vms.
Set some definitions to reflect latest features of DECC. Modifications in
config.h-vms (which is copied to config.h).
Added extern strcmpi declaration to avoid 'implicitly declared' messages.
Modification in make.h.
Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
Compaq c/c++ compilers. Modifications in default.c.
Usage of opendir() and friends, suppress file version. Modifications in dir.c.
Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
Modifications in job.c.
Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
.SUFFIXES :
.SUFFIXES : .class .java
.java.class :
javac "$<
HelloWorld.class : HelloWorld.java
A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled. The
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
Modifications in file.c and config.h-vms.
Bootstrap make to start building make is still makefile.com, but make
needs to be re-made with a make to make a correct version: ignore all
possible warnings, delete all objects, rename make.exe to a different
name and run it.
Made some minor modifications to the bootstrap build makefile.com.
This is the VMS port of GNU Make.
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
This port was done by Klaus Kämpf <kkaempf@rmi.de>
There is first-level support available from proGIS Software, Germany.
Visit their web-site at http://www.progis.de to get information
about other vms software and forthcoming updates to gnu make.
New for 3.77:
/bin/sh style I/O redirection is supported. You can now write lines like
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override VMS symbols/logicals !
Functions for file names are working now. See the GNU Make manual for
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
supported as arguments.
The default rules are set up for GNU C. Building an executable from a
single source file is as easy as 'make file.exe'.
The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
different VMS systems can now be written by checking $(ARCH) as in
ifeq ($(ARCH),ALPHA)
$(ECHO) "On the Alpha"
else
$(ECHO) "On the VAX"
endif
Command lines of excessive length are correctly broken and written to a
batch file in sys$scratch for later execution. There's no limit to the
lengths of commands (and no need for .opt files :-) any more.
Empty commands are handled correctly and don't end in a new DCL process.
New for 3.76:
John W. Eaton has updated the VMS port to support libraries and VPATH.
To build Make, simply type @makefile. This should compile all the
necessary files and link Make. There is also a file called
makefile.vms. If you already have GNU Make built you can just use
Make with this makefile to rebuild.
Here are some notes about GNU Make for VMS:
The cd command is supported if it's called as $(CD). This invokes
the 'builtin_cd' command which changes the directory.
Calling 'set def' doesn't do the trick, since a sub-shell is
spawned for this command, the directory is changed *in this sub-shell*
and the sub-shell ends.
Libraries are not supported. They were in GNU Make 3.60 but somehow I
didn't care porting the code. If there is enough interest, I'll do it at
some later time.
The variable $^ separates files with commas instead of spaces (It's the
natural thing to do for VMS).
See defaults.c for VMS default suffixes and my definitions for default
rules and variables.
The shell function is not implemented yet.
Load average routines haven't been implemented for VMS yet.
The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
The default makefiles make looks for are: makefile.vms, gnumakefile,
makefile., and gnumakefile. .
The stat() function and handling of time stamps in VMS is broken, so I
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
less than what vms provides. This might be a problem on the faster Alphas.
You can use a : in a filename only if you precede it with a backslash ('\').
E.g.- hobbes\:[bogas.files]
Make ignores success, informational, or warning errors (-S-, -I-, or
-W-). But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
Remote stuff isn't implemented yet.
Multiple line DCL commands, such as "if" statements, must be put inside
command files. You can run a command file by using \@.
VMS changes made for 3.74.3
Lots of default settings are adapted for VMS. See default.c.
Long command lines are now converted to command files.
Comma (',') as a separator is now allowed. See makefile.vms for an example.
-------------------------------------------------------------------------------
Copyright (C) 1996-2014 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/>.
Hartmut Becker
John Malmberg
Michael Gehre
John Eisenbraun
Klaus Kaempf
Mike Moretti
John W. Eaton

View file

@ -1,11 +1,12 @@
This version of GNU make has been tested on
Microsoft Windows 2000/XP/2003/Vista/7/2008.
This version of GNU make has been tested on:
Microsoft Windows 2000/XP/2003/Vista/7/8/10
It has also been used on Windows 95/98/NT, and on OS/2.
It builds with the MinGW port of GCC (tested with GCC 3.4.2).
It builds with the MinGW port of GCC (tested with GCC 3.4.2, 4.8.1,
and 4.9.3).
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.
It also builds with MSVC 2.x, 4.x, 5.x, 6.x, 2003, and 14 (2015) as
well as with .NET 7.x and .NET 2003.
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
@ -13,32 +14,32 @@ itself, its dependency libraries and the pkg-config program. The
latter is used to figure out which compilation and link switches and
libraries need to be mentioned on the compiler command lines to
correctly link with Guile. A Windows port of pkg-config can be found
on the Windows download page of the GTK+ project:
on ezwinports site:
http://www.gtk.org/download/win32.php
http://sourceforge.net/projects/ezwinports/
The libraries on which Guile depends can vary depending on your
version and build of Guile. At the very least, the Boehm's GC library
will be needed, and typically also GNU MP, libffi, libunistring, and
libtool's libltdl. Whoever built the port of Guile you have should
also provide you with these dependencies or a URL where to download
them.
them. A precompiled 32-bit Windows build of Guile is available from
the ezwinports site mentioned above.
The Windows 32-bit port of GNU make is maintained jointly by various
people. It was originally made by Rob Tulloh.
The Windows port of GNU make is maintained jointly by various people.
It was originally made by Rob Tulloh.
It is currently maintained by Eli Zaretskii.
Do this first, regardless of the build method you choose:
---------------------------------------------------------
1. At the Windows command prompt run:
if not exist NMakefile copy NMakefile.template NMakefile
if not exist config.h copy config.h.W32 config.h
Then edit config.h to your liking (especially the few shell-related
1. Edit config.h.W32 to your liking (especially the few shell-related
defines near the end, or HAVE_CASE_INSENSITIVE_FS which corresponds
to './configure --enable-case-insensitive-file-system').
to './configure --enable-case-insensitive-file-system'). (We don't
recommend to define HAVE_CASE_INSENSITIVE_FS, but you may wish to
consider that if you have a lot of files whose names are in upper
case, while Makefile rules are written for lower-case versions.)
Using make_msvc_net2003.vcproj
@ -57,7 +58,9 @@ Building with (MinGW-)GCC using build_w32.bat
build_w32.bat gcc
This produces gnumake.exe in the current directory.
This produces gnumake.exe in the GccRel directory.
If you want a version of GNU make built with debugging enabled,
add the --debug option.
The batch file will probe for Guile installation, and will build
gnumake.exe with Guile if it finds it. If you have Guile
@ -77,7 +80,9 @@ Building with (MSVC++-)cl using build_w32.bat or NMakefile
build_w32.bat
(this produces WinDebug/gnumake.exe and WinRel/gnumake.exe)
This produces gnumake.exe in the WinRel directory.
If you want a version of GNU make built with debugging enabled,
add the --debug option.
... OR ...
@ -293,7 +298,7 @@ Bug reports:
is described in the GNU make manual and the base README.
-------------------------------------------------------------------------------
Copyright (C) 1996-2014 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

View file

@ -96,7 +96,7 @@ SunOS 4.1.x:
-------------------------------------------------------------------------------
Copyright (C) 1998-2014 Free Software Foundation, Inc.
Copyright (C) 1998-2016 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

View file

@ -3,7 +3,7 @@
# NOTE: If you have no 'make' program at all to process this makefile,
# run 'build.sh' instead.
#
# Copyright (C) 1995-2014 Free Software Foundation, Inc.
# Copyright (C) 1995-2016 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

View file

@ -1,7 +1,7 @@
dnl acinclude.m4 -- Extra macros needed for GNU make.
dnl
dnl Automake will incorporate this into its generated aclocal.m4.
dnl Copyright (C) 1998-2014 Free Software Foundation, Inc.
dnl Copyright (C) 1998-2016 Free Software Foundation, Inc.
dnl This file is part of GNU Make.
dnl
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
Copyright (C) 1995-2014 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View file

@ -1,5 +1,5 @@
/* Definitions for amiga specific things
Copyright (C) 1995-2014 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

10
ar.c
View file

@ -1,5 +1,5 @@
/* Interface to 'ar' archives for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 Free Software Foundation, Inc.
This file is part of GNU Make.
@ -73,7 +73,7 @@ static long int
ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, long int date,
int uid UNUSED, int gid UNUSED, int mode UNUSED,
int uid UNUSED, int gid UNUSED, unsigned int mode UNUSED,
const void *name)
{
return ar_name_equal (name, mem, truncated) ? date : 0;
@ -198,7 +198,7 @@ static long int
ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
long int hdrpos UNUSED, long int datapos UNUSED,
long int size UNUSED, long int date UNUSED, int uid UNUSED,
int gid UNUSED, int mode UNUSED, const void *arg)
int gid UNUSED, unsigned int mode UNUSED, const void *arg)
{
struct ar_glob_state *state = (struct ar_glob_state *)arg;
@ -224,7 +224,7 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
static int
glob_pattern_p (const char *pattern, int quote)
ar_glob_pattern_p (const char *pattern, int quote)
{
const char *p;
int opened = 0;
@ -267,7 +267,7 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size)
#ifdef VMS
char *vms_member_pattern;
#endif
if (! glob_pattern_p (member_pattern, 1))
if (! ar_glob_pattern_p (member_pattern, 1))
return 0;
/* Scan the archive for matches.

View file

@ -1,5 +1,5 @@
/* Library function for scanning an archive file.
Copyright (C) 1987-2014 Free Software Foundation, Inc.
Copyright (C) 1987-2016 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
@ -38,12 +38,18 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <ssdef.h>
#include <stsdef.h>
#include <rmsdef.h>
globalvalue unsigned int LBR$_HDRTRUNC;
#if __DECC
/* This symbol should be present in lbrdef.h. */
#ifndef LBR$_HDRTRUNC
#pragma extern_model save
#pragma extern_model globalvalue
extern unsigned int LBR$_HDRTRUNC;
#pragma extern_model restore
#endif
#include <unixlib.h>
#include <lbr$routines.h>
#endif
const char *
vmsify (const char *name, int type);
@ -414,7 +420,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef SARMAG
{
char buf[SARMAG];
register int nread = read (desc, buf, SARMAG);
int nread;
EINTRLOOP (nread, read (desc, buf, SARMAG));
if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
{
(void) close (desc);
@ -424,8 +431,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else
#ifdef AIAMAG
{
register int nread = read (desc, &fl_header, FL_HSZ);
int nread;
EINTRLOOP (nread, read (desc, &fl_header, FL_HSZ));
if (nread != FL_HSZ)
{
(void) close (desc);
@ -436,17 +443,20 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
re-read the header into the "big" structure. */
if (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
{
off_t o;
big_archive = 1;
/* seek back to beginning of archive */
if (lseek (desc, 0, 0) < 0)
EINTRLOOP (o, lseek (desc, 0, 0));
if (o < 0)
{
(void) close (desc);
return -2;
}
/* re-read the header into the "big" structure */
nread = read (desc, &fl_header_big, FL_HSZ_BIG);
EINTRLOOP (nread, read (desc, &fl_header_big, FL_HSZ_BIG));
if (nread != FL_HSZ_BIG)
{
(void) close (desc);
@ -469,7 +479,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#else
unsigned short int buf;
#endif
register int nread = read (desc, &buf, sizeof (buf));
int nread;
EINTRLOOP (nread, read (desc, &buf, sizeof (buf)));
if (nread != sizeof (buf) || buf != ARMAG)
{
(void) close (desc);
@ -536,10 +547,12 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
int long_name = 0;
#endif
long int eltsize;
int eltmode;
unsigned int eltmode;
long int fnval;
off_t o;
if (lseek (desc, member_offset, 0) < 0)
EINTRLOOP (o, lseek (desc, member_offset, 0));
if (o < 0)
{
(void) close (desc);
return -2;
@ -551,8 +564,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
#ifdef AIAMAGBIG
if (big_archive)
{
nread = read (desc, &member_header_big,
AR_MEMHDR_SZ(member_header_big) );
EINTRLOOP (nread, read (desc, &member_header_big,
AR_MEMHDR_SZ(member_header_big)));
if (nread != AR_MEMHDR_SZ(member_header_big))
{
@ -561,7 +574,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
}
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len);
EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len)
{
@ -583,8 +596,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
else
#endif
{
nread = read (desc, &member_header,
AR_MEMHDR_SZ(member_header) );
EINTRLOOP (nread, read (desc, &member_header,
AR_MEMHDR_SZ(member_header)));
if (nread != AR_MEMHDR_SZ(member_header))
{
@ -593,7 +606,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
}
sscanf (member_header.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len);
EINTRLOOP (nread, read (desc, name, name_len));
if (nread != name_len)
{
@ -621,7 +634,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
eltmode, arg);
#else /* Not AIAMAG. */
nread = read (desc, &member_header, AR_HDR_SIZE);
EINTRLOOP (nread, read (desc, &member_header, AR_HDR_SIZE));
if (nread == 0)
/* No data left means end of file; that is OK. */
break;
@ -690,7 +703,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
int namesize = atoi (name + 3);
name = alloca (namesize + 1);
nread = read (desc, name, namesize);
EINTRLOOP (nread, read (desc, name, namesize));
if (nread != namesize)
{
close (desc);
@ -761,7 +774,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
char *limit;
namemap = alloca (eltsize);
nread = read (desc, namemap, eltsize);
EINTRLOOP (nread, read (desc, namemap, eltsize));
if (nread != eltsize)
{
(void) close (desc);
@ -859,7 +872,7 @@ static long int
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
long int date UNUSED, int uid UNUSED, int gid UNUSED,
int mode UNUSED, const void *name)
unsigned int mode UNUSED, const void *name)
{
if (!ar_name_equal (name, mem, truncated))
return 0;
@ -879,7 +892,8 @@ ar_member_touch (const char *arname, const char *memname)
long int pos = ar_scan (arname, ar_member_pos, memname);
int fd;
struct ar_hdr ar_hdr;
int i;
off_t o;
int r;
unsigned int ui;
struct stat statbuf;
@ -888,28 +902,32 @@ ar_member_touch (const char *arname, const char *memname)
if (!pos)
return 1;
fd = open (arname, O_RDWR, 0666);
EINTRLOOP (fd, open (arname, O_RDWR, 0666));
if (fd < 0)
return -3;
/* Read in this member's header */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != read (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, read (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
/* Write back the header, thus touching the archive file. */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
/* The file's mtime is the time we we want. */
EINTRLOOP (i, fstat (fd, &statbuf));
if (i < 0)
EINTRLOOP (r, fstat (fd, &statbuf));
if (r < 0)
goto lose;
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
/* Advance member's time to that time */
for (ui = 0; ui < sizeof 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), "%lu", (long unsigned) statbuf.st_mtime);
#ifdef AIAMAG
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
#endif
@ -917,17 +935,19 @@ ar_member_touch (const char *arname, const char *memname)
ar_hdr.ar_date = statbuf.st_mtime;
#endif
/* Write back this member's header */
if (lseek (fd, pos, 0) < 0)
EINTRLOOP (o, lseek (fd, pos, 0));
if (o < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, &ar_hdr, AR_HDR_SIZE))
EINTRLOOP (r, write (fd, &ar_hdr, AR_HDR_SIZE));
if (r != AR_HDR_SIZE)
goto lose;
close (fd);
return 0;
lose:
i = errno;
r = errno;
close (fd);
errno = i;
errno = r;
return -3;
}
#endif
@ -937,7 +957,8 @@ ar_member_touch (const char *arname, const char *memname)
long int
describe_member (int desc, const char *name, int truncated,
long int hdrpos, long int datapos, long int size,
long int date, int uid, int gid, int mode, const void *arg)
long int date, int uid, int gid, unsigned int mode,
const void *arg)
{
extern char *ctime ();

View file

@ -2,7 +2,7 @@
# Shell script to build GNU Make in the absence of any 'make' program.
# @configure_input@
# Copyright (C) 1993-2014 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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

486
build_w32.bat Normal file → Executable file
View file

@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1996-2014 Free Software Foundation, Inc.
rem Copyright (C) 1996-2016 Free Software Foundation, Inc.
rem This file is part of GNU Make.
rem
rem GNU Make is free software; you can redistribute it and/or modify it under
@ -15,283 +15,217 @@ rem
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/>.
if "%1" == "-h" GoTo Usage
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
sed -f config.h.W32.sed config.h.W32.template > config.h.W32
echo static const char *const GUILE_module_defn = ^" \> gmk-default.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
call :Reset
if "%1" == "-h" goto Usage
if "%1" == "--help" goto Usage
set MAKE=gnumake
set GUILE=Y
set COMPILER=msvc
rem Guile configuration
set GUILECFLAGS=
set GUILELIBS=
set NOGUILE=
set OPT=-O2
set COMPILER=
set PKGMSC=
:ParseSW
if "%1" == "--debug" GoTo SetOpt
if "%1" == "--without-guile" GoTo NoGuile
if "%1" == "gcc" GoTo SetCC
if "%1" == "" GoTo ChkGuile
:SetOpt
set OPT=-O0
if "%1" == "--debug" goto SetDebug
if "%1" == "--without-guile" goto NoGuile
if "%1" == "gcc" goto SetCC
if "%1" == "" goto DoneSW
:SetDebug
set DEBUG=Y
shift
GoTo ParseSW
goto ParseSW
:NoGuile
set NOGUILE=Y
echo "Building without Guile"
set GUILE=N
echo Building without Guile
shift
GoTo ParseSW
goto ParseSW
:SetCC
set COMPILER=gcc
echo "Building with GCC"
echo Building with GCC
shift
GoTo ParseSW
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
pkg-config --help > guile.tmp 2> NUL
if ERRORLEVEL 1 GoTo NoPkgCfg
echo "Checking for Guile 2.0"
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
pkg-config --cflags --short-errors "guile-2.0" > guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
if not "%GUILECFLAGS%" == "" GoTo GuileDone
echo "Checking for Guile 1.8"
pkg-config --cflags --short-errors "guile-1.8" > guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < guile.tmp
if not "%GUILECFLAGS%" == "" GoTo GuileDone
echo "No Guile found, building without Guile"
GoTo GuileDone
:NoPkgCfg
echo "pkg-config not found, building without Guile"
:GuileDone
if not "%GUILECFLAGS%" == "" echo "Guile found, building with Guile"
if not "%GUILECFLAGS%" == "" set GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE
if "%COMPILER%" == "gcc" if "%OPT%" == "-O0" echo "Building without compiler optimizations"
cd w32\subproc
echo.
echo "Creating the subproc library"
%ComSpec% /c build.bat
cd ..\..
goto ParseSW
if exist link.dbg del link.dbg
if exist link.rel del link.rel
rem Build with Guile is supported only on NT and later versions
:DoneSW
echo.
echo "Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8"
if "%COMPILER%" == "gcc" GoTo GCCBuild
set make=gnumake
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8
if "%DEBUG%" == "Y" echo Building without compiler optimizations
if "%COMPILER%" == "gcc" goto GccBuild
set OUTDIR=.\WinRel
set "OPTS=/O2 /D NDEBUG"
set LINKOPTS=
if "%DEBUG%" == "Y" set OUTDIR=.\WinDebug
if "%DEBUG%" == "Y" set "OPTS=/Zi /Od /D _DEBUG"
if "%DEBUG%" == "Y" set LINKOPTS=/DEBUG
call :Build
goto Done
:GccBuild
set OUTDIR=.\GccRel
set OPTS=-O2
if "%DEBUG%" == "Y" set OPTS=-O0
if "%DEBUG%" == "Y" set OUTDIR=.\GccDebug
call :Build
goto Done
:Done
call :Reset
goto :EOF
:Build
:: Clean the directory if it exists
if exist %OUTDIR%\nul rmdir /S /Q %OUTDIR%
:: Recreate it
mkdir %OUTDIR%
mkdir %OUTDIR%\glob
mkdir %OUTDIR%\w32
mkdir %OUTDIR%\w32\compat
mkdir %OUTDIR%\w32\subproc
if "%GUILE%" == "Y" call :ChkGuile
echo.
echo Compiling %OUTDIR% version
if exist config.h.W32.template call :ConfigSCM
copy config.h.W32 %OUTDIR%\config.h
call :Compile ar
call :Compile arscan
call :Compile commands
call :Compile default
call :Compile dir
call :Compile expand
call :Compile file
call :Compile function
call :Compile getloadavg
call :Compile getopt
call :Compile getopt1
call :Compile glob\fnmatch
call :Compile glob\glob
call :Compile guile GUILE
call :Compile hash
call :Compile implicit
call :Compile job
call :Compile load
call :Compile loadapi
call :Compile main GUILE
call :Compile misc
call :Compile output
call :Compile read
call :Compile remake
call :Compile remote-stub
call :Compile rule
call :Compile signame
call :Compile strcache
call :Compile variable
call :Compile version
call :Compile vpath
call :Compile w32\compat\posixfcn
call :Compile w32\pathstuff
call :Compile w32\subproc\misc
call :Compile w32\subproc\sub_proc
call :Compile w32\subproc\w32err
call :Compile w32\w32os
if not "%COMPILER%" == "gcc" call :Compile w32\compat\dirent
call :Link
echo.
if not exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build FAILED!
if exist %OUTDIR%\%MAKE%.exe echo %OUTDIR% build succeeded.
goto :EOF
:Compile
set EXTRAS=
if "%2" == "GUILE" set "EXTRAS=%GUILECFLAGS%"
if "%COMPILER%" == "gcc" goto GccCompile
:: MSVC Compile
echo on
if not exist .\WinDebug\nul mkdir .\WinDebug
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /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 variable.c
echo WinDebug\variable.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 rule.c
echo WinDebug\rule.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 remote-stub.c
echo WinDebug\remote-stub.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 commands.c
echo WinDebug\commands.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 file.c
echo WinDebug\file.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 getloadavg.c
echo WinDebug\getloadavg.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 default.c
echo WinDebug\default.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 signame.c
echo WinDebug\signame.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 expand.c
echo WinDebug\expand.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 dir.c
echo WinDebug\dir.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS% /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 main.c
echo WinDebug\main.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 getopt1.c
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
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
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
echo WinDebug\version.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 getopt.c
echo WinDebug\getopt.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 arscan.c
echo WinDebug\arscan.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 hash.c
echo WinDebug\hash.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 strcache.c
echo WinDebug\strcache.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 remake.c
echo WinDebug\remake.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 misc.c
echo WinDebug\misc.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 ar.c
echo WinDebug\ar.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 function.c
echo WinDebug\function.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 vpath.c
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
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
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
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
echo WinDebug\fnmatch.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\pathstuff.c
echo WinDebug\pathstuff.obj >>link.dbg
cl.exe /nologo /MT /W4 /GX /Zi /YX /Od %GUILECFLAGS% /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 guile.c
echo WinDebug\guile.obj >>link.dbg
:LinkDbg
echo off
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/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
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 exist .\WinDebug/%make%.exe echo "WinDebug build succeeded!"
if not exist .\WinRel\nul mkdir .\WinRel
echo on
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 /D TIVOLI /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c variable.c
echo WinRel\variable.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 rule.c
echo WinRel\rule.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 remote-stub.c
echo WinRel\remote-stub.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 commands.c
echo WinRel\commands.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 file.c
echo WinRel\file.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 getloadavg.c
echo WinRel\getloadavg.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 default.c
echo WinRel\default.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 signame.c
echo WinRel\signame.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 expand.c
echo WinRel\expand.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 dir.c
echo WinRel\dir.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 %GUILECFLAGS% /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 main.c
echo WinRel\main.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 getopt1.c
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
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
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
echo WinRel\version.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 getopt.c
echo WinRel\getopt.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 arscan.c
echo WinRel\arscan.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 remake.c
echo WinRel\remake.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 hash.c
echo WinRel\hash.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 strcache.c
echo WinRel\strcache.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 misc.c
echo WinRel\misc.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 ar.c
echo WinRel\ar.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 function.c
echo WinRel\function.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 vpath.c
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
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
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
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
echo WinRel\fnmatch.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\pathstuff.c
echo WinRel\pathstuff.obj >>link.rel
cl.exe /nologo /MT /W4 /GX /YX /O2 %GUILECFLAGS% /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 guile.c
echo WinRel\guile.obj >>link.rel
:LinkRel
echo off
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/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
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 exist .\WinRel/%make%.exe echo "WinRel build succeeded!"
set make=
GoTo BuildEnd
:GCCBuild
echo on
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 %OPT% -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 remote-stub.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 %OPT% -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 getloadavg.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 %OPT% -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 expand.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 %OPT% -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 -c getopt1.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 %OPT% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c output.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 %OPT% -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 getopt.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 %OPT% -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 hash.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 %OPT% -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 ar.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 %OPT% -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 implicit.c
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 %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
gcc -mthreads -Wall -gdwarf-2 -g3 %OPT% %GUILECFLAGS% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H -c guile.c
:LinkGCC
cl.exe /nologo /MT /W4 /EHsc %OPTS% /I %OUTDIR% /I . /I glob /I w32/include /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR%OUTDIR% /Fp%OUTDIR%\%MAKE%.pch /Fo%OUTDIR%\%1.obj /Fd%OUTDIR%\%MAKE%.pdb %EXTRAS% /c %1.c
@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
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 guile.o 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
echo %OUTDIR%\%1.obj >>%OUTDIR%\link.sc
goto :EOF
:GccCompile
:: GCC Compile
echo on
gcc -mthreads -Wall -std=gnu99 -gdwarf-2 -g3 %OPTS% -I%OUTDIR% -I. -I./glob -I./w32/include -DWINDOWS32 -DHAVE_CONFIG_H %EXTRAS% -o %OUTDIR%\%1.o -c %1.c
@echo off
goto :EOF
:Link
echo Linking %OUTDIR%/%MAKE%.exe
if "%COMPILER%" == "gcc" goto GccLink
:: MSVC Link
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 >>%OUTDIR%\link.sc
echo on
link.exe /NOLOGO /SUBSYSTEM:console /PDB:%OUTDIR%\%MAKE%.pdb %LINKOPTS% /OUT:%OUTDIR%\%MAKE%.exe @%OUTDIR%\link.sc
@echo off
goto :EOF
:GccLink
:: GCC Link
echo on
gcc -mthreads -gdwarf-2 -g3 -o %OUTDIR%\%MAKE%.exe %OUTDIR%\variable.o %OUTDIR%\rule.o %OUTDIR%\remote-stub.o %OUTDIR%\commands.o %OUTDIR%\file.o %OUTDIR%\getloadavg.o %OUTDIR%\default.o %OUTDIR%\signame.o %OUTDIR%\expand.o %OUTDIR%\dir.o %OUTDIR%\main.o %OUTDIR%\getopt1.o %OUTDIR%\guile.o %OUTDIR%\job.o %OUTDIR%\output.o %OUTDIR%\read.o %OUTDIR%\version.o %OUTDIR%\getopt.o %OUTDIR%\arscan.o %OUTDIR%\remake.o %OUTDIR%\misc.o %OUTDIR%\hash.o %OUTDIR%\strcache.o %OUTDIR%\ar.o %OUTDIR%\function.o %OUTDIR%\vpath.o %OUTDIR%\implicit.o %OUTDIR%\loadapi.o %OUTDIR%\load.o %OUTDIR%\glob\glob.o %OUTDIR%\glob\fnmatch.o %OUTDIR%\w32\pathstuff.o %OUTDIR%\w32\compat\posixfcn.o %OUTDIR%\w32\w32os.o %OUTDIR%\w32\subproc\misc.o %OUTDIR%\w32\subproc\sub_proc.o %OUTDIR%\w32\subproc\w32err.o %GUILELIBS% -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -Wl,--out-implib=%OUTDIR%\libgnumake-1.dll.a
@echo off
goto :EOF
:ConfigSCM
echo Generating config from SCM templates
sed -n "s/^AC_INIT(\[GNU make\],\[\([^]]\+\)\].*/s,%%VERSION%%,\1,g/p" configure.ac > %OUTDIR%\config.h.W32.sed
echo s,%%PACKAGE%%,make,g >> %OUTDIR%\config.h.W32.sed
sed -f %OUTDIR%\config.h.W32.sed config.h.W32.template > config.h.W32
echo static const char *const GUILE_module_defn = ^" \> gmk-default.h
sed -e "s/;.*//" -e "/^[ \t]*$/d" -e "s/\"/\\\\\"/g" -e "s/$/ \\\/" gmk-default.scm >> gmk-default.h
echo ^";>> gmk-default.h
goto :EOF
:ChkGuile
if not "%OS%" == "Windows_NT" goto NoGuile
pkg-config --help > %OUTDIR%\guile.tmp 2> NUL
if ERRORLEVEL 1 goto NoPkgCfg
echo Checking for Guile 2.0
if not "%COMPILER%" == "gcc" set PKGMSC=--msvc-syntax
pkg-config --cflags --short-errors "guile-2.0" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-2.0" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
if not "%GUILECFLAGS%" == "" goto GuileDone
echo Checking for Guile 1.8
pkg-config --cflags --short-errors "guile-1.8" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILECFLAGS= < %OUTDIR%\guile.tmp
pkg-config --libs --static --short-errors %PKGMSC% "guile-1.8" > %OUTDIR%\guile.tmp
if not ERRORLEVEL 1 set /P GUILELIBS= < %OUTDIR%\guile.tmp
if not "%GUILECFLAGS%" == "" goto GuileDone
echo No Guile found, building without Guile
goto GuileDone
:NoPkgCfg
echo pkg-config not found, building without Guile
:GuileDone
if "%GUILECFLAGS%" == "" goto :EOF
echo Guile found, building with Guile
set "GUILECFLAGS=%GUILECFLAGS% -DHAVE_GUILE"
goto :EOF
:Usage
echo Usage: %0 [options] [gcc]
echo Options:
@ -299,12 +233,18 @@ 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
@echo off
set GUILELIBS=
set GUILECFLAGS=
set PKGMSC=
set OPT=
goto :EOF
:Reset
set COMPILER=
set DEBUG=
set GUILE=
set GUILECFLAGS=
set GUILELIBS=
set LINKOPTS=
set MAKE=
set NOGUILE=
echo on
set OPTS=
set OUTDIR=
set PKGMSC=
goto :EOF

View file

@ -1,5 +1,5 @@
/* Command processing for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -26,13 +26,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#endif
#if VMS
# define FILE_LIST_SEPARATOR ','
# define FILE_LIST_SEPARATOR (vms_comma_separator ? ',' : ' ')
#else
# define FILE_LIST_SEPARATOR ' '
#endif
int remote_kill (int id, int sig);
#ifndef HAVE_UNISTD_H
int getpid ();
#endif
@ -411,10 +409,10 @@ chop_commands (struct commands *cmds)
for (idx = 0; idx < nlines; ++idx)
{
int flags = 0;
unsigned char flags = 0;
const char *p = lines[idx];
while (isblank (*p) || *p == '-' || *p == '@' || *p == '+')
while (ISBLANK (*p) || *p == '-' || *p == '@' || *p == '+')
switch (*(p++))
{
case '+':
@ -451,7 +449,7 @@ execute_file_commands (struct file *file)
the commands are nothing but whitespace. */
for (p = file->cmds->commands; *p != '\0'; ++p)
if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
if (!ISSPACE (*p) && *p != '-' && *p != '@' && *p != '+')
break;
if (*p == '\0')
{

View file

@ -1,5 +1,5 @@
/* Definition of data structures describing shell commands for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -19,10 +19,10 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
struct commands
{
gmk_floc fileinfo; /* Where commands were defined. */
floc fileinfo; /* Where commands were defined. */
char *commands; /* Commands text. */
char **command_lines; /* Commands chopped up into lines. */
char *lines_flags; /* One set of flag bits for each line. */
unsigned char *lines_flags; /* One set of flag bits for each line. */
unsigned short ncommand_lines;/* Number of command lines. */
char recipe_prefix; /* Recipe prefix for this command set. */
unsigned int any_recurse:1; /* Nonzero if any 'lines_flags' elt has */
@ -34,6 +34,7 @@ struct commands
#define COMMANDS_SILENT 2 /* Silent: @. */
#define COMMANDS_NOERROR 4 /* No errors: -. */
RETSIGTYPE fatal_error_signal (int sig);
void execute_file_commands (struct file *file);
void print_commands (const struct commands *cmds);
void delete_child_targets (struct child *child);

View file

@ -1,5 +1,5 @@
/* config.h -- hand-massaged for Amiga -*-C-*-
Copyright (C) 1995-2014 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View file

@ -1,6 +1,6 @@
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> -*-C-*-
Copyright (C) 1996-2014 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

View file

@ -1,6 +1,6 @@
/* config.h.W32 -- hand-massaged config.h file for Windows builds -*-C-*-
Copyright (C) 1996-2014 Free Software Foundation, Inc.
Copyright (C) 1996-2016 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

49
config/ChangeLog.1 Normal file
View file

@ -0,0 +1,49 @@
2012-01-15 Paul Smith <psmith@gnu.org>
* dospaths.m4: Use AC_LANG_PROGRAM to encapsulate the test code.
Fixes Savannah bug #35256. Patch from Sebastian Pipping.
2006-03-09 Paul Smith <psmith@gnu.org>
* dospaths.m4: Add MSYS to the list of targets allowing DOS-style
pathnames. Reported by David Ergo <david.ergo@alterface.com>.
2005-07-01 Paul D. Smith <psmith@gnu.org>
* Makefile.am (EXTRA_DIST): Added more M4 files to EXTRA_DIST, so
users can re-run aclocal.
2003-04-30 Paul D. Smith <psmith@gnu.org>
* dospaths.m4: New macro to test for DOS-style pathnames, based on
coreutils 5.0 "dos.m4" by Jim Meyering.
2002-04-21 gettextize <bug-gnu-gettext@gnu.org>
* codeset.m4: New file, from gettext-0.11.1.
* gettext.m4: New file, from gettext-0.11.1.
* glibc21.m4: New file, from gettext-0.11.1.
* iconv.m4: New file, from gettext-0.11.1.
* isc-posix.m4: New file, from gettext-0.11.1.
* lcmessage.m4: New file, from gettext-0.11.1.
* lib-ld.m4: New file, from gettext-0.11.1.
* lib-link.m4: New file, from gettext-0.11.1.
* lib-prefix.m4: New file, from gettext-0.11.1.
* progtest.m4: New file, from gettext-0.11.1.
* Makefile.am: New file.
Copyright (C) 2002-2016 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/>.

View file

@ -1,5 +1,5 @@
# -*-Makefile-*-, or close enough
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# Copyright (C) 2002-2016 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

View file

@ -1,7 +1,7 @@
# 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.
#
# Copyright (C) 1993-2014 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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

View file

@ -1,6 +1,6 @@
/* configh.dos -- hand-massaged config.h file for MS-DOS builds -*-C-*-
Copyright (C) 1994-2014 Free Software Foundation, Inc.
Copyright (C) 1994-2016 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

View file

@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
#
# Copyright (C) 1993-2014 Free Software Foundation, Inc.
# Copyright (C) 1993-2016 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
@ -16,9 +16,9 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
AC_INIT([GNU make],[4.1],[bug-make@gnu.org])
AC_INIT([GNU make],[4.2.1],[bug-make@gnu.org])
AC_PREREQ([2.62])
AC_PREREQ([2.69])
# Autoconf setup
AC_CONFIG_AUX_DIR([config])
@ -29,7 +29,7 @@ AC_CONFIG_HEADERS([config.h])
# We have to enable "foreign" because ChangeLog is auto-generated
# We cannot enable -Werror because gettext 0.18.1 has invalid content
# When we update gettext to 0.18.3 or better we can add it again.
AM_INIT_AUTOMAKE([1.11.1 silent-rules foreign -Wall])
AM_INIT_AUTOMAKE([1.15 foreign -Werror -Wall])
# Checks for programs.
AC_USE_SYSTEM_EXTENSIONS
@ -51,7 +51,7 @@ AC_ISC_POSIX
AC_MINIX
# Enable gettext, in "external" mode.
AM_GNU_GETTEXT_VERSION([0.18.1])
AM_GNU_GETTEXT_VERSION([0.19.4])
AM_GNU_GETTEXT([external])
# This test must come as early as possible after the compiler configuration
@ -68,22 +68,18 @@ AC_HEADER_DIRENT
AC_HEADER_STAT
AC_HEADER_TIME
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 \
sys/select.h])
AM_PROG_CC_C_O
AC_C_CONST
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_PID_T
# Find some definition for uintmax_t
AC_CHECK_TYPE([uintmax_t],[],
[ uintmax_t="unsigned long"
AC_CHECK_TYPE([unsigned long long],[uintmax_t="unsigned long long"])
AC_DEFINE_UNQUOTED([uintmax_t], [$uintmax_t],
[Define uintmax_t if not defined in <stdint.h> or <inttypes.h>.])
])
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINTMAX_T
# Find out whether our struct stat returns nanosecond resolution timestamps.
@ -140,7 +136,7 @@ AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
dup dup2 getcwd realpath sigsetmask sigaction \
getgroups seteuid setegid setlinebuf setreuid setregid \
getrlimit setrlimit setvbuf pipe strerror strsignal \
lstat readlink atexit isatty ttyname])
lstat readlink atexit isatty ttyname pselect])
# We need to check declarations, not just existence, because on Tru64 this
# function is not declared without special flags, which themselves cause
@ -148,6 +144,8 @@ AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
AC_CHECK_DECLS([bsd_signal], [], [], [[#define _GNU_SOURCE 1
#include <signal.h>]])
AC_FUNC_FORK
AC_FUNC_SETVBUF_REVERSED
# Rumor has it that strcasecmp lives in -lresolv on some odd systems.

View file

@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1994-2014 Free Software Foundation, Inc.
rem Copyright (C) 1994-2016 Free Software Foundation, Inc.
rem This file is part of GNU Make.
rem
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.
Copyright (C) 1999-2014 Free Software Foundation, Inc.
Copyright (C) 1999-2016 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

View file

@ -1,5 +1,5 @@
/* Data base of default implicit rules for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -131,10 +131,47 @@ static struct pspec default_terminal_rules[] =
static const char *default_suffix_rules[] =
{
#ifdef VMS
".o",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".obj",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".s",
"$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".S",
"$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".c",
"$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".cc",
"$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".C",
"$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".cpp",
"$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".f",
"$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".m",
"$(LINK.m) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".p",
"$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".F",
"$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".r",
"$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".mod",
"$(COMPILE.mod) -o $@ -e $@ $^",
".def.sym",
"$(COMPILE.def) -o $@ $<",
".sh",
"copy $< >$@",
".obj.exe",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".mar.exe",
"$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".s.o",
"$(COMPILE.s) -o $@ $<",
".s.exe",
"$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".c.exe",
@ -205,6 +242,27 @@ static const char *default_suffix_rules[] =
".tex.dvi",
"$(TEX) $<",
".cpp.o",
"$(COMPILE.cpp) $(OUTPUT_OPTION) $<",
".f.o",
"$(COMPILE.f) $(OUTPUT_OPTION) $<",
".m.o",
"$(COMPILE.m) $(OUTPUT_OPTION) $<",
".p.o",
"$(COMPILE.p) $(OUTPUT_OPTION) $<",
".r.o",
"$(COMPILE.r) $(OUTPUT_OPTION) $<",
".mod.o",
"$(COMPILE.mod) -o $@ $<",
".c.ln",
"$(LINT.c) -C$* $<",
".y.ln",
"$(YACC.y) $< \n rename y_tab.c $@",
".l.ln",
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
#else /* ! VMS */
".o",
@ -413,19 +471,44 @@ static const char *default_variables[] =
"LDLIBS", "",
#endif
"LINK.o", "$(LD) $(LDFLAGS)",
"LINK.obj", "$(LD) $(LDFLAGS)",
#ifndef GCC_IS_NATIVE
"CXXLINK.obj", "$(CXXLD) $(LDFLAGS)",
"COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
#endif
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.C", "$(COMPILE.cc)",
"COMPILE.cpp", "$(COMPILE.cc)",
"LINK.C", "$(LINK.cc)",
"LINK.cpp", "$(LINK.cc)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS)",
"YACC.m", "$(YACC) $(YFLAGS)",
"LEX.m", "$(LEX) $(LFLAGS) -t",
"COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)",
"COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c",
"LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c",
"LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)",
"COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)",
"COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.mar", "$(MACRO) $(MACROFLAGS)",
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
"COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
"PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
"PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"MV", "rename/new_version",
@ -519,10 +602,21 @@ static const char *default_variables[] =
"COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
#ifndef HAVE_CASE_INSENSITIVE_FS
/* On case-insensitive filesystems, treat *.C files as *.c files,
to avoid erroneously compiling C sources as C++, which will
probably fail. */
"COMPILE.C", "$(COMPILE.cc)",
#else
"COMPILE.C", "$(COMPILE.c)",
#endif
"COMPILE.cpp", "$(COMPILE.cc)",
"LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
#ifndef HAVE_CASE_INSENSITIVE_FS
"LINK.C", "$(LINK.cc)",
#else
"LINK.C", "$(LINK.c)",
#endif
"LINK.cpp", "$(LINK.cc)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS) -t",

99
dep.h
View file

@ -1,5 +1,5 @@
/* Definitions of dependency data structures for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -14,9 +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
this program. If not, see <http://www.gnu.org/licenses/>. */
/* Structure used in chains of names, for parsing and globbing. */
#define NAMESEQ(_t) \
_t *next; \
const char *name
struct nameseq
{
NAMESEQ (struct nameseq);
};
/* Flag bits for the second argument to 'read_makefile'.
These flags are saved in the 'changed' field of each
'struct dep' in the chain returned by 'read_all_makefiles'. */
These flags are saved in the 'flags' field of each
'struct goaldep' in the chain returned by 'read_all_makefiles'. */
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
@ -25,34 +37,37 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define RM_NOFLAG 0
/* Structure representing one dependency of a file.
Each struct file's 'deps' points to a chain of these,
chained through the 'next'. 'stem' is the stem for this
dep line of static pattern rule or NULL.
Each struct file's 'deps' points to a chain of these, through 'next'.
'stem' is the stem for this dep line of static pattern rule or NULL. */
Note that the first two words of this match a struct nameseq. */
#define DEP(_t) \
NAMESEQ (_t); \
struct file *file; \
const char *stem; \
unsigned short flags : 8; \
unsigned short changed : 1; \
unsigned short ignore_mtime : 1; \
unsigned short staticpattern : 1; \
unsigned short need_2nd_expansion : 1
struct dep
{
struct dep *next;
const char *name;
const char *stem;
struct file *file;
unsigned int changed : 8;
unsigned int ignore_mtime : 1;
unsigned int staticpattern : 1;
unsigned int need_2nd_expansion : 1;
unsigned int dontcare : 1;
DEP (struct dep);
};
/* Structure representing one goal.
The goals to be built constitute a chain of these, chained through 'next'.
'stem' is not used, but it's simpler to include and ignore it. */
/* Structure used in chains of names, for parsing and globbing. */
struct nameseq
struct goaldep
{
struct nameseq *next;
const char *name;
DEP (struct goaldep);
unsigned short error;
floc floc;
};
/* Options for parsing lists of filenames. */
#define PARSEFS_NONE 0x0000
#define PARSEFS_NOSTRIP 0x0001
#define PARSEFS_NOAR 0x0002
@ -78,15 +93,39 @@ char *tilde_expand (const char *name);
struct nameseq *ar_glob (const char *arname, const char *member_pattern, unsigned int size);
#endif
#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
#define dep_name(d) ((d)->name ? (d)->name : (d)->file->name)
#define alloc_dep() (xcalloc (sizeof (struct dep)))
#define free_ns(_n) free (_n)
#define free_dep(_d) free_ns (_d)
#define alloc_seq_elt(_t) xcalloc (sizeof (_t))
void free_ns_chain (struct nameseq *n);
#if defined(MAKE_MAINTAINER_MODE) && defined(__GNUC__)
/* Use inline to get real type-checking. */
#define SI static inline
SI struct nameseq *alloc_ns() { return alloc_seq_elt (struct nameseq); }
SI struct dep *alloc_dep() { return alloc_seq_elt (struct dep); }
SI struct goaldep *alloc_goaldep() { return alloc_seq_elt (struct goaldep); }
SI void free_ns(struct nameseq *n) { free (n); }
SI void free_dep(struct dep *d) { free_ns ((struct nameseq *)d); }
SI void free_goaldep(struct goaldep *g) { free_dep ((struct dep *)g); }
SI void free_dep_chain(struct dep *d) { free_ns_chain((struct nameseq *)d); }
SI void free_goal_chain(struct goaldep *g) { free_dep_chain((struct dep *)g); }
#else
# define alloc_ns() alloc_seq_elt (struct nameseq)
# define alloc_dep() alloc_seq_elt (struct dep)
# define alloc_goaldep() alloc_seq_elt (struct goaldep)
# define free_ns(_n) free (_n)
# define free_dep(_d) free_ns (_d)
# define free_goaldep(_g) free_dep (_g)
# define free_dep_chain(_d) free_ns_chain ((struct nameseq *)(_d))
# define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g))
#endif
struct dep *copy_dep_chain (const struct dep *d);
void free_dep_chain (struct dep *d);
void free_ns_chain (struct nameseq *n);
struct dep *read_all_makefiles (const char **makefiles);
void eval_buffer (char *buffer, const gmk_floc *floc);
enum update_status update_goal_chain (struct dep *goals);
struct goaldep *read_all_makefiles (const char **makefiles);
void eval_buffer (char *buffer, const floc *floc);
enum update_status update_goal_chain (struct goaldep *goals);

227
dir.c
View file

@ -1,5 +1,5 @@
/* Directory hashing for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -142,6 +142,32 @@ downcase (const char *filename)
#ifdef VMS
static char *
downcase_inplace(char *filename)
{
char *name;
name = filename;
while (*name != '\0')
{
*name = tolower ((unsigned char)*name);
++name;
}
return filename;
}
#ifndef _USE_STD_STAT
/* VMS 8.2 fixed the VMS stat output to have unique st_dev and st_ino
when _USE_STD_STAT is used on the compile line.
Prior to _USE_STD_STAT support, the st_dev is a pointer to thread
static memory containing the device of the last filename looked up.
Todo: find out if the ino_t still needs to be faked on a directory.
*/
/* Define this if the older VMS_INO_T is needed */
#define VMS_INO_T 1
static int
vms_hash (const char *name)
{
@ -200,6 +226,10 @@ vmsstat_dir (const char *name, struct stat *st)
return 0;
}
# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
#endif /* _USE_STD_STAT */
#endif /* VMS */
/* Hash table of directories. */
@ -218,14 +248,14 @@ struct directory_contents
* qualified name of the directory. Beware though, this is also
* unreliable. I'm open to suggestion on a better way to emulate inode. */
char *path_key;
int ctime;
int mtime; /* controls check for stale directory cache */
int fs_flags; /* FS_FAT, FS_NTFS, ... */
time_t ctime;
time_t mtime; /* controls check for stale directory cache */
int fs_flags; /* FS_FAT, FS_NTFS, ... */
# define FS_FAT 0x1
# define FS_NTFS 0x2
# define FS_UNKNOWN 0x4
#else
# ifdef VMS
# ifdef VMS_INO_T
ino_t ino[3];
# else
ino_t ino;
@ -246,7 +276,7 @@ directory_contents_hash_1 (const void *key_0)
ISTRING_HASH_1 (key->path_key, hash);
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
#else
# ifdef VMS
# ifdef VMS_INO_T
hash = (((unsigned int) key->dev << 4)
^ ((unsigned int) key->ino[0]
+ (unsigned int) key->ino[1]
@ -269,7 +299,7 @@ directory_contents_hash_2 (const void *key_0)
ISTRING_HASH_2 (key->path_key, hash);
hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
#else
# ifdef VMS
# ifdef VMS_INO_T
hash = (((unsigned int) key->dev << 4)
^ ~((unsigned int) key->ino[0]
+ (unsigned int) key->ino[1]
@ -308,7 +338,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
if (result)
return result;
#else
# ifdef VMS
# ifdef VMS_INO_T
result = MAKECMP(x->ino[0], y->ino[0]);
if (result)
return result;
@ -375,7 +405,7 @@ static unsigned int open_directories = 0;
struct dirfile
{
const char *name; /* Name of the file. */
short length;
size_t length;
short impossible; /* This file is impossible. */
};
@ -419,13 +449,6 @@ find_directory (const char *name)
struct directory **dir_slot;
struct directory dir_key;
#ifdef VMS
if ((*name == '.') && (*(name+1) == 0))
name = "[]";
else
name = vmsify (name,1);
#endif
dir_key.name = name;
dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
dir = *dir_slot;
@ -439,7 +462,12 @@ find_directory (const char *name)
dir = xmalloc (sizeof (struct directory));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
dir->name = strcache_add_len (downcase (name), p - name);
/* Todo: Why is this only needed on VMS? */
{
char *lname = downcase_inplace (xstrdup (name));
dir->name = strcache_add_len (lname, p - name);
free (lname);
}
#else
dir->name = strcache_add_len (name, p - name);
#endif
@ -447,9 +475,7 @@ find_directory (const char *name)
/* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */
#ifdef VMS
r = vmsstat_dir (name, &st);
#elif defined(WINDOWS32)
#if defined(WINDOWS32)
{
char tem[MAXPATHLEN], *tstart, *tend;
@ -492,7 +518,7 @@ find_directory (const char *name)
dc_key.path_key = w32_path = w32ify (name, 1);
dc_key.ctime = st.st_ctime;
#else
# ifdef VMS
# ifdef VMS_INO_T
dc_key.ino[0] = st.st_ino[0];
dc_key.ino[1] = st.st_ino[1];
dc_key.ino[2] = st.st_ino[2];
@ -537,7 +563,7 @@ find_directory (const char *name)
else
dc->fs_flags = FS_UNKNOWN;
#else
# ifdef VMS
# ifdef VMS_INO_T
dc->ino[0] = st.st_ino[0];
dc->ino[1] = st.st_ino[1];
dc->ino[2] = st.st_ino[2];
@ -602,11 +628,6 @@ dir_contents_file_exists_p (struct directory_contents *dir,
if (filename != 0)
_fnlwr (filename); /* lower case for FAT drives */
#endif
#ifdef VMS
filename = vmsify (filename,0);
#endif
if (filename != 0)
{
struct dirfile dirfile_key;
@ -679,7 +700,9 @@ dir_contents_file_exists_p (struct directory_contents *dir,
}
#if defined(VMS) && defined(HAVE_DIRENT_H)
/* In VMS we get file versions too, which have to be stripped off */
/* In VMS we get file versions too, which have to be stripped off.
Some versions of VMS return versions on Unix files even when
the feature option to strip them is set. */
{
char *p = strrchr (d->d_name, ';');
if (p)
@ -703,7 +726,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
{
df = xmalloc (sizeof (struct dirfile));
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
df->name = strcache_add_len (downcase (d->d_name), len);
/* TODO: Why is this only needed on VMS? */
df->name = strcache_add_len (downcase_inplace (d->d_name), len);
#else
df->name = strcache_add_len (d->d_name, len);
#endif
@ -734,6 +758,15 @@ dir_contents_file_exists_p (struct directory_contents *dir,
int
dir_file_exists_p (const char *dirname, const char *filename)
{
#ifdef VMS
if ((filename != NULL) && (dirname != NULL))
{
int want_vmsify;
want_vmsify = (strpbrk (dirname, ":<[") != NULL);
if (want_vmsify)
filename = vmsify (filename, 0);
}
#endif
return dir_contents_file_exists_p (find_directory (dirname)->contents,
filename);
}
@ -752,14 +785,24 @@ file_exists_p (const char *name)
return ar_member_date (name) != (time_t) -1;
#endif
#ifdef VMS
dirend = strrchr (name, ']');
if (dirend == 0)
dirend = strrchr (name, ':');
if (dirend == 0)
return dir_file_exists_p ("[]", name);
#else /* !VMS */
dirend = strrchr (name, '/');
#ifdef VMS
if (dirend == 0)
{
dirend = strrchr (name, ']');
dirend == NULL ? dirend : dirend++;
}
if (dirend == 0)
{
dirend = strrchr (name, '>');
dirend == NULL ? dirend : dirend++;
}
if (dirend == 0)
{
dirend = strrchr (name, ':');
dirend == NULL ? dirend : dirend++;
}
#endif /* VMS */
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
@ -774,10 +817,9 @@ file_exists_p (const char *name)
if (dirend == 0)
#ifndef _AMIGA
return dir_file_exists_p (".", name);
#else /* !VMS && !AMIGA */
#else /* !AMIGA */
return dir_file_exists_p ("", name);
#endif /* AMIGA */
#endif /* VMS */
slash = dirend;
if (dirend == name)
@ -796,7 +838,13 @@ file_exists_p (const char *name)
p[dirend - name] = '\0';
dirname = p;
}
return dir_file_exists_p (dirname, slash + 1);
#ifdef VMS
if (*slash == '/')
slash++;
#else
slash++;
#endif
return dir_file_exists_p (dirname, slash);
}
/* Mark FILENAME as 'impossible' for 'file_impossible_p'.
@ -811,16 +859,25 @@ file_impossible (const char *filename)
struct directory *dir;
struct dirfile *new;
#ifdef VMS
dirend = strrchr (p, ']');
if (dirend == 0)
dirend = strrchr (p, ':');
dirend++;
if (dirend == (char *)1)
dir = find_directory ("[]");
#else
dirend = strrchr (p, '/');
# ifdef HAVE_DOS_PATHS
#ifdef VMS
if (dirend == NULL)
{
dirend = strrchr (p, ']');
dirend == NULL ? dirend : dirend++;
}
if (dirend == NULL)
{
dirend = strrchr (p, '>');
dirend == NULL ? dirend : dirend++;
}
if (dirend == NULL)
{
dirend = strrchr (p, ':');
dirend == NULL ? dirend : dirend++;
}
#endif
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
const char *bslash = strrchr (p, '\\');
@ -830,14 +887,13 @@ file_impossible (const char *filename)
if (!dirend && p[0] && p[1] == ':')
dirend = p + 1;
}
# endif /* HAVE_DOS_PATHS */
#endif /* HAVE_DOS_PATHS */
if (dirend == 0)
# ifdef _AMIGA
#ifdef _AMIGA
dir = find_directory ("");
# else /* !VMS && !AMIGA */
#else /* !AMIGA */
dir = find_directory (".");
# endif /* AMIGA */
#endif /* VMS */
#endif /* AMIGA */
else
{
const char *dirname;
@ -859,7 +915,14 @@ file_impossible (const char *filename)
dirname = cp;
}
dir = find_directory (dirname);
#ifdef VMS
if (*slash == '/')
filename = p = slash + 1;
else
filename = p = slash;
#else
filename = p = slash + 1;
#endif
}
if (dir->contents == 0)
@ -878,6 +941,7 @@ file_impossible (const char *filename)
new = xmalloc (sizeof (struct dirfile));
new->length = strlen (filename);
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
/* todo: Why is this only needed on VMS? */
new->name = strcache_add_len (downcase (filename), new->length);
#else
new->name = strcache_add_len (filename, new->length);
@ -895,13 +959,22 @@ file_impossible_p (const char *filename)
struct directory_contents *dir;
struct dirfile *dirfile;
struct dirfile dirfile_key;
#ifdef VMS
dirend = strrchr (filename, ']');
if (dirend == 0)
dir = find_directory ("[]")->contents;
#else
int want_vmsify = 0;
#endif
dirend = strrchr (filename, '/');
#ifdef VMS
if (dirend == NULL)
{
want_vmsify = (strpbrk (filename, "]>:^") != NULL);
dirend = strrchr (filename, ']');
}
if (dirend == NULL && want_vmsify)
dirend = strrchr (filename, '>');
if (dirend == NULL && want_vmsify)
dirend = strrchr (filename, ':');
#endif
#ifdef HAVE_DOS_PATHS
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
@ -916,10 +989,9 @@ file_impossible_p (const char *filename)
if (dirend == 0)
#ifdef _AMIGA
dir = find_directory ("")->contents;
#else /* !VMS && !AMIGA */
#else /* !AMIGA */
dir = find_directory (".")->contents;
#endif /* AMIGA */
#endif /* VMS */
else
{
const char *dirname;
@ -941,7 +1013,14 @@ file_impossible_p (const char *filename)
dirname = cp;
}
dir = find_directory (dirname)->contents;
#ifdef VMS
if (*slash == '/')
filename = slash + 1;
else
filename = slash;
#else
filename = slash + 1;
#endif
}
if (dir == 0 || dir->dirfiles.ht_vec == 0)
@ -955,7 +1034,8 @@ file_impossible_p (const char *filename)
filename = downcase (filename);
#endif
#ifdef VMS
filename = vmsify (filename, 1);
if (want_vmsify)
filename = vmsify (filename, 1);
#endif
dirfile_key.name = filename;
@ -1002,10 +1082,11 @@ print_dir_data_base (void)
else if (dir->contents->dirfiles.ht_vec == 0)
{
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
dir->name, dir->contents->path_key,dir->contents->mtime);
printf (_("# %s (key %s, mtime %I64u): could not be opened.\n"),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS
#ifdef VMS_INO_T
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
@ -1038,10 +1119,11 @@ print_dir_data_base (void)
}
}
#ifdef WINDOWS32
printf (_("# %s (key %s, mtime %d): "),
dir->name, dir->contents->path_key, dir->contents->mtime);
printf (_("# %s (key %s, mtime %I64u): "),
dir->name, dir->contents->path_key,
(unsigned long long)dir->contents->mtime);
#else /* WINDOWS32 */
#ifdef VMS
#ifdef VMS_INO_T
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
dir->name, dir->contents->dev,
dir->contents->ino[0], dir->contents->ino[1],
@ -1087,8 +1169,6 @@ print_dir_data_base (void)
/* Hooks for globbing. */
#include <glob.h>
/* Structure describing state of iterating through a directory hash table. */
struct dirstream
@ -1179,9 +1259,16 @@ read_dirstream (__ptr_t stream)
* On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
* regular file; fix that here.
*/
#if !defined(stat) && !defined(WINDOWS32)
#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
# ifndef VMS
# ifndef HAVE_SYS_STAT_H
int stat (const char *path, struct stat *sbuf);
# endif
# else
/* We are done with the fake stat. Go back to the real stat */
# ifdef stat
# undef stat
# endif
# endif
# define local_stat stat
#else

View file

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

View file

@ -1,5 +1,5 @@
/* Variable expansion functions for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -26,7 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Initially, any errors reported when expanding strings will be reported
against the file where the error appears. */
const gmk_floc **expanding_var = &reading_file;
const floc **expanding_var = &reading_file;
/* The next two describe the variable output buffer.
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)
{
char *value;
const gmk_floc *this_var;
const gmk_floc **saved_varp;
const floc *this_var;
const floc **saved_varp;
struct variable_set_list *save = 0;
int set_reading = 0;
@ -235,8 +235,10 @@ variable_expand_string (char *line, const char *string, long length)
switch (*p)
{
case '$':
/* $$ seen means output one $ to the variable output buffer. */
o = variable_buffer_output (o, p, 1);
case '\0':
/* $$ or $ at the end of the string means output one $ to the
variable output buffer. */
o = variable_buffer_output (o, p1, 1);
break;
case '(':
@ -381,11 +383,8 @@ variable_expand_string (char *line, const char *string, long length)
}
break;
case '\0':
break;
default:
if (isblank ((unsigned char)p[-1]))
if (ISSPACE (p[-1]))
break;
/* A $ followed by a random char is a variable reference:
@ -459,7 +458,7 @@ variable_expand_for_file (const char *line, struct file *file)
{
char *result;
struct variable_set_list *savev;
const gmk_floc *savef;
const floc *savef;
if (file == 0)
return variable_expand (line);

31
file.c
View file

@ -1,5 +1,5 @@
/* Target file management for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -57,9 +57,6 @@ file_hash_cmp (const void *x, const void *y)
((struct file const *) y)->hname);
}
#ifndef FILE_BUCKETS
#define FILE_BUCKETS 1007
#endif
static struct hash_table files;
/* Whether or not .SECONDARY with no prerequisites was given. */
@ -75,8 +72,11 @@ lookup_file (const char *name)
{
struct file *f;
struct file file_key;
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
#ifdef VMS
int want_vmsify;
#ifndef WANT_CASE_SENSITIVE_TARGETS
char *lname;
#endif
#endif
assert (*name != '\0');
@ -85,6 +85,7 @@ lookup_file (const char *name)
for names read from makefiles. It is here for names passed
on the command line. */
#ifdef VMS
want_vmsify = (strpbrk (name, "]>:^") != NULL);
# ifndef WANT_CASE_SENSITIVE_TARGETS
if (*name != '.')
{
@ -100,6 +101,8 @@ lookup_file (const char *name)
while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
name += 2;
while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
name += 2;
#endif
while (name[0] == '.'
#ifdef HAVE_DOS_PATHS
@ -120,15 +123,19 @@ lookup_file (const char *name)
}
if (*name == '\0')
/* It was all slashes after a dot. */
#if defined(VMS)
name = "[]";
#elif defined(_AMIGA)
name = "";
{
/* It was all slashes after a dot. */
#if defined(_AMIGA)
name = "";
#else
name = "./";
name = "./";
#endif
#if defined(VMS)
/* TODO - This section is probably not needed. */
if (want_vmsify)
name = "[]";
#endif
}
file_key.hname = name;
f = hash_find_item (&files, &file_key);
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)

View file

@ -1,5 +1,5 @@
/* Definition of target file data structures for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -58,6 +58,8 @@ struct file
FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
has been performed. */
unsigned int considered; /* equal to 'considered' if file has been
considered on current scan of goal chain */
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
enum update_status /* Status of the last attempt to update. */
{
@ -96,14 +98,12 @@ struct file
unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */
unsigned int pat_searched:1;/* Nonzero if we already searched for
pattern-specific variables. */
unsigned int considered:1; /* equal to 'considered' if file has been
considered on current scan of goal chain */
unsigned int no_diag:1; /* True if the file failed to update and no
diagnostics has been issued (dontcare). */
};
extern struct file *suffix_file, *default_file;
extern struct file *default_file;
struct file *lookup_file (const char *name);
@ -117,9 +117,12 @@ void rehash_file (struct file *file, const char *name);
void set_command_state (struct file *file, enum cmd_state state);
void notice_finished_file (struct file *file);
void init_hash_files (void);
void verify_file_data_base (void);
char *build_target_list (char *old_list);
void print_prereqs (const struct dep *deps);
void print_file_data_base (void);
int try_implicit_rule (struct file *file, unsigned int depth);
int stemlen_compare (const void *v1, const void *v2);
#if FILE_TIMESTAMP_HI_RES
# define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \

View file

@ -1,5 +1,5 @@
/* Builtin function expansion for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -115,8 +115,8 @@ subst_expand (char *o, const char *text, const char *subst, const char *replace,
/* If we're substituting only by fully matched words,
or only at the ends of words, check that this case qualifies. */
if (by_word
&& ((p > text && !isblank ((unsigned char)p[-1]))
|| ! STOP_SET (p[slen], MAP_BLANK|MAP_NUL)))
&& ((p > text && !ISSPACE (p[-1]))
|| ! STOP_SET (p[slen], MAP_SPACE|MAP_NUL)))
/* Struck out. Output the rest of the string that is
no longer to be replaced. */
o = variable_buffer_output (o, subst, slen);
@ -566,10 +566,12 @@ func_notdir_suffix (char *o, char **argv, const char *funcname)
if (is_notdir || p >= p2)
{
#ifdef VMS
o = variable_buffer_output (o, ",", 1);
#else
o = variable_buffer_output (o, " ", 1);
if (vms_comma_separator)
o = variable_buffer_output (o, ",", 1);
else
#endif
o = variable_buffer_output (o, " ", 1);
doneany = 1;
}
}
@ -596,7 +598,7 @@ func_basename_dir (char *o, char **argv, const char *funcname)
int stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
#ifdef VMS
/* As in func_notdir_suffix ... */
char *vms_p3 = alloca(strlen(p3) + 1);
char *vms_p3 = alloca (strlen(p3) + 1);
int i;
for (i = 0; p3[i]; i++)
if (p3[i] == ',')
@ -624,7 +626,13 @@ func_basename_dir (char *o, char **argv, const char *funcname)
#endif
else if (is_dir)
#ifdef VMS
o = variable_buffer_output (o, "[]", 2);
{
extern int vms_report_unix_paths;
if (vms_report_unix_paths)
o = variable_buffer_output (o, "./", 2);
else
o = variable_buffer_output (o, "[]", 2);
}
#else
#ifndef _AMIGA
o = variable_buffer_output (o, "./", 2);
@ -637,10 +645,12 @@ func_basename_dir (char *o, char **argv, const char *funcname)
o = variable_buffer_output (o, p2, len);
#ifdef VMS
o = variable_buffer_output (o, ",", 1);
#else
o = variable_buffer_output (o, " ", 1);
if (vms_comma_separator)
o = variable_buffer_output (o, ",", 1);
else
#endif
o = variable_buffer_output (o, " ", 1);
doneany = 1;
}
@ -745,9 +755,9 @@ func_words (char *o, char **argv, const char *funcname UNUSED)
char *
strip_whitespace (const char **begpp, const char **endpp)
{
while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
while (*begpp <= *endpp && ISSPACE (**begpp))
(*begpp) ++;
while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
while (*endpp >= *begpp && ISSPACE (**endpp))
(*endpp) --;
return (char *)*begpp;
}
@ -860,8 +870,12 @@ func_foreach (char *o, char **argv, const char *funcname UNUSED)
unsigned int len;
struct variable *var;
/* Clean up the variable name by removing whitespace. */
char *vp = next_token (varname);
end_of_token (vp)[0] = '\0';
push_new_variable_scope ();
var = define_variable (varname, strlen (varname), "", o_automatic, 0);
var = define_variable (vp, strlen (vp), "", o_automatic, 0);
/* loop through LIST, put the value in VAR and expand BODY */
while ((p = find_next_token (&list_iterator, &len)) != 0)
@ -1071,10 +1085,9 @@ func_strip (char *o, char **argv, const char *funcname UNUSED)
int i=0;
const char *word_start;
while (isspace ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
word_start = p;
for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
for (i=0; *p != '\0' && !ISSPACE (*p); ++p, ++i)
{}
if (!i)
break;
@ -1440,10 +1453,23 @@ fold_newlines (char *buffer, unsigned int *length, int trim_newlines)
*length = last_nonnl - buffer;
}
pid_t shell_function_pid = 0;
static int shell_function_completed;
void
shell_completed (int exit_code, int exit_sig)
{
char buf[256];
int shell_function_pid = 0, shell_function_completed;
shell_function_pid = 0;
if (exit_sig == 0 && exit_code == 127)
shell_function_completed = -1;
else
shell_function_completed = 1;
sprintf (buf, "%d", exit_code);
define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
}
#ifdef WINDOWS32
/*untested*/
@ -1592,8 +1618,7 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
extern int dos_command_running, dos_status;
/* Make sure not to bother processing an empty line. */
while (isblank ((unsigned char)*text))
++text;
NEXT_TOKEN (text);
if (*text == '\0')
return 0;
@ -1623,14 +1648,15 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
errno = EINTR;
else if (errno == 0)
errno = ENOMEM;
shell_function_completed = -1;
if (fpipe)
pclose (fpipe);
shell_completed (127, 0);
}
else
{
pipedes[0] = fileno (fpipe);
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
errno = e;
shell_function_completed = 1;
}
return fpipe;
}
@ -1689,7 +1715,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
#endif
return o;
}
#endif
#endif /* !__MSDOS__ */
/* Using a target environment for 'shell' loses in cases like:
export var = $(shell echo foobie)
@ -1709,7 +1735,8 @@ func_shell_base (char *o, char **argv, int trim_newlines)
if (reading_file && reading_file->filenm)
{
char *p = alloca (strlen (reading_file->filenm)+11+4);
sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
sprintf (p, "%s:%lu: ", reading_file->filenm,
reading_file->lineno + reading_file->offset);
error_prefix = p;
}
else
@ -1728,6 +1755,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
perror_with_name (error_prefix, "pipe");
return o;
}
#elif defined(WINDOWS32)
windows32_openpipe (pipedes, errfd, &pid, command_argv, envp);
/* Restore the value of just_print_flag. */
@ -1736,11 +1764,11 @@ func_shell_base (char *o, char **argv, int trim_newlines)
if (pipedes[0] < 0)
{
/* Open of the pipe failed, mark as failed execution. */
shell_function_completed = -1;
shell_completed (127, 0);
perror_with_name (error_prefix, "pipe");
return o;
}
else
#else
if (pipe (pipedes) < 0)
{
@ -1748,115 +1776,113 @@ func_shell_base (char *o, char **argv, int trim_newlines)
return o;
}
# ifdef __EMX__
/* close some handles that are unnecessary for the child process */
/* Close handles that are unnecessary for the child process. */
CLOSE_ON_EXEC(pipedes[1]);
CLOSE_ON_EXEC(pipedes[0]);
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
pid = child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
if (pid < 0)
perror_with_name (error_prefix, "spawn");
# else /* ! __EMX__ */
pid = fork ();
if (pid < 0)
perror_with_name (error_prefix, "fork");
else if (pid == 0)
{
# 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
# endif
#endif
{
/* We are the parent. */
char *buffer;
unsigned int maxlen, i;
int cc;
/* Record the PID for reap_children. */
shell_function_pid = pid;
{
struct output out;
out.syncout = 1;
out.out = pipedes[1];
out.err = errfd;
pid = child_execute_job (&out, 1, command_argv, envp);
}
if (pid < 0)
{
perror_with_name (error_prefix, "fork");
return o;
}
#endif
{
char *buffer;
unsigned int maxlen, i;
int cc;
/* Record the PID for reap_children. */
shell_function_pid = pid;
#ifndef __MSDOS__
shell_function_completed = 0;
shell_function_completed = 0;
/* Free the storage only the child needed. */
free (command_argv[0]);
free (command_argv);
/* Free the storage only the child needed. */
free (command_argv[0]);
free (command_argv);
/* Close the write side of the pipe. We test for -1, since
pipedes[1] is -1 on MS-Windows, and some versions of MS
libraries barf when 'close' is called with -1. */
if (pipedes[1] >= 0)
close (pipedes[1]);
/* Close the write side of the pipe. We test for -1, since
pipedes[1] is -1 on MS-Windows, and some versions of MS
libraries barf when 'close' is called with -1. */
if (pipedes[1] >= 0)
close (pipedes[1]);
#endif
/* Set up and read from the pipe. */
/* Set up and read from the pipe. */
maxlen = 200;
buffer = xmalloc (maxlen + 1);
maxlen = 200;
buffer = xmalloc (maxlen + 1);
/* Read from the pipe until it gets EOF. */
for (i = 0; ; i += cc)
{
if (i == maxlen)
{
maxlen += 512;
buffer = xrealloc (buffer, maxlen + 1);
}
/* Read from the pipe until it gets EOF. */
for (i = 0; ; i += cc)
{
if (i == maxlen)
{
maxlen += 512;
buffer = xrealloc (buffer, maxlen + 1);
}
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
if (cc <= 0)
break;
}
buffer[i] = '\0';
EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
if (cc <= 0)
break;
}
buffer[i] = '\0';
/* Close the read side of the pipe. */
/* Close the read side of the pipe. */
#ifdef __MSDOS__
if (fpipe)
(void) pclose (fpipe);
if (fpipe)
{
int st = pclose (fpipe);
shell_completed (st, 0);
}
#else
(void) close (pipedes[0]);
(void) close (pipedes[0]);
#endif
/* Loop until child_handler or reap_children() sets
shell_function_completed to the status of our child shell. */
while (shell_function_completed == 0)
reap_children (1, 0);
/* Loop until child_handler or reap_children() sets
shell_function_completed to the status of our child shell. */
while (shell_function_completed == 0)
reap_children (1, 0);
if (batch_filename)
{
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename));
remove (batch_filename);
free (batch_filename);
}
shell_function_pid = 0;
if (batch_filename)
{
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename));
remove (batch_filename);
free (batch_filename);
}
shell_function_pid = 0;
/* The child_handler function will set shell_function_completed
to 1 when the child dies normally, or to -1 if it
dies with status 127, which is most likely an exec fail. */
/* shell_completed() will set shell_function_completed to 1 when the
child dies normally, or to -1 if it dies with status 127, which is
most likely an exec fail. */
if (shell_function_completed == -1)
{
/* This likely means that the execvp failed, so we should just
write the error message in the pipe from the child. */
fputs (buffer, stderr);
fflush (stderr);
}
else
{
/* The child finished normally. Replace all newlines in its output
with spaces, and put that in the variable output buffer. */
fold_newlines (buffer, &i, trim_newlines);
o = variable_buffer_output (o, buffer, i);
}
if (shell_function_completed == -1)
{
/* This likely means that the execvp failed, so we should just
write the error message in the pipe from the child. */
fputs (buffer, stderr);
fflush (stderr);
}
else
{
/* The child finished normally. Replace all newlines in its output
with spaces, and put that in the variable output buffer. */
fold_newlines (buffer, &i, trim_newlines);
o = variable_buffer_output (o, buffer, i);
}
free (buffer);
}
free (buffer);
}
return o;
}
@ -1950,7 +1976,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
}
#endif /* _AMIGA */
char *
static char *
func_shell (char *o, char **argv, const char *funcname UNUSED)
{
return func_shell_base (o, argv, 1);
@ -1979,8 +2005,7 @@ func_not (char *o, char **argv, char *funcname UNUSED)
{
const char *s = argv[0];
int result = 0;
while (isspace ((unsigned char)*s))
s++;
NEXT_TOKEN (s);
result = ! (*s);
o = variable_buffer_output (o, result ? "1" : "", result);
return o;
@ -2184,29 +2209,70 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
mode = "a";
++fn;
}
fn = next_token (fn);
NEXT_TOKEN (fn);
fp = fopen (fn, mode);
if (fn[0] == '\0')
O (fatal, *expanding_var, _("file: missing filename"));
ENULLLOOP (fp, fopen (fn, mode));
if (fp == NULL)
{
const char *err = strerror (errno);
OSS (fatal, reading_file, _("open: %s: %s"), fn, err);
}
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
if (argv[1])
{
int l = strlen (argv[1]);
int nl = l == 0 || argv[1][l-1] != '\n';
if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
{
const char *err = strerror (errno);
OSS (fatal, reading_file, _("write: %s: %s"), fn, err);
}
OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
}
fclose (fp);
if (fclose (fp))
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
}
else if (fn[0] == '<')
{
char *preo = o;
FILE *fp;
++fn;
NEXT_TOKEN (fn);
if (fn[0] == '\0')
O (fatal, *expanding_var, _("file: missing filename"));
if (argv[1])
O (fatal, *expanding_var, _("file: too many arguments"));
ENULLLOOP (fp, fopen (fn, "r"));
if (fp == NULL)
{
if (errno == ENOENT)
return o;
OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
}
while (1)
{
char buf[1024];
size_t l = fread (buf, 1, sizeof (buf), fp);
if (l > 0)
o = variable_buffer_output (o, buf, l);
if (ferror (fp))
if (errno != EINTR)
OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
if (feof (fp))
break;
}
if (fclose (fp))
OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
/* Remove trailing newline. */
if (o > preo && o[-1] == '\n')
if (--o > preo && o[-1] == '\r')
--o;
}
else
OS (fatal, reading_file, _("Invalid file operation: %s"), fn);
OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
return o;
}
@ -2379,7 +2445,8 @@ handle_function (char **op, const char **stringp)
/* We found a builtin function. Find the beginning of its arguments (skip
whitespace after the name). */
beg = next_token (beg + entry_p->len);
beg += entry_p->len;
NEXT_TOKEN (beg);
/* Find the end of the function invocation, counting nested use of
whichever kind of parens we use. Since we're looking, count commas
@ -2479,7 +2546,6 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
{
static int max_args = 0;
char *fname;
char *cp;
char *body;
int flen;
int i;
@ -2487,16 +2553,9 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
const struct function_table_entry *entry_p;
struct variable *v;
/* 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. */
fname = argv[0];
while (isspace ((unsigned char)*fname))
++fname;
cp = fname + strlen (fname) - 1;
while (cp > fname && isspace ((unsigned char)*cp))
--cp;
cp[1] = '\0';
/* Clean up the name of the variable to be invoked. */
fname = next_token (argv[0]);
end_of_token (fname)[0] = '\0';
/* Calling nothing is a no-op */
if (*fname == '\0')
@ -2575,7 +2634,7 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
}
void
define_new_function (const gmk_floc *flocp, const char *name,
define_new_function (const floc *flocp, const char *name,
unsigned int min, unsigned int max, unsigned int flags,
gmk_func_ptr func)
{
@ -2595,10 +2654,10 @@ define_new_function (const gmk_floc *flocp, const char *name,
OS (fatal, flocp, _("Function name too long: %s"), name);
if (min > 255)
ONS (fatal, flocp,
_("Invalid minimum argument count (%d) for function %s"), min, name);
_("Invalid minimum argument count (%u) for function %s"), min, name);
if (max > 255 || (max && max < min))
ONS (fatal, flocp,
_("Invalid maximum argument count (%d) for function %s"), max, name);
_("Invalid maximum argument count (%u) for function %s"), max, name);
ent = xmalloc (sizeof (struct function_table_entry));
ent->name = name;

View file

@ -1,5 +1,5 @@
/* Get the system load averages.
Copyright (C) 1985-2014 Free Software Foundation, Inc.
Copyright (C) 1985-2016 Free Software Foundation, Inc.
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

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
before changing it!
Copyright (C) 1987-2014 Free Software Foundation, Inc.
Copyright (C) 1987-2016 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.

View file

@ -1,5 +1,5 @@
/* Declarations for getopt.
Copyright (C) 1989-2014 Free Software Foundation, Inc.
Copyright (C) 1989-2016 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
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.
Copyright (C) 1987-1994, 1996-2014 Free Software Foundation, Inc.
Copyright (C) 1987-1994, 1996-2016 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.

View file

@ -1,5 +1,5 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-2014 Free Software Foundation, Inc.
Copyright (C) 1995-2016 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

View file

@ -1,5 +1,5 @@
;; Contents of the (gnu make) Guile module
;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Copyright (C) 2011-2016 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

View file

@ -1,7 +1,7 @@
/* 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-2014 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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

View file

@ -1,5 +1,5 @@
/* GNU Guile interface for GNU Make.
Copyright (C) 2011-2014 Free Software Foundation, Inc.
Copyright (C) 2011-2016 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
@ -140,7 +140,7 @@ func_guile (const char *funcname UNUSED, unsigned int argc UNUSED, char **argv)
/* We could send the flocp to define_new_function(), but since guile is
"kind of" built-in, that didn't seem so useful. */
int
guile_gmake_setup (const gmk_floc *flocp UNUSED)
guile_gmake_setup (const floc *flocp UNUSED)
{
/* Create a make function "guile". */
gmk_add_function ("guile", func_guile, 0, 1, GMK_FUNC_DEFAULT);
@ -151,7 +151,7 @@ guile_gmake_setup (const gmk_floc *flocp UNUSED)
#else
int
guile_gmake_setup (const gmk_floc *flocp UNUSED)
guile_gmake_setup (const floc *flocp UNUSED)
{
return 1;
}

View file

@ -1,5 +1,5 @@
/* Implicit rule searching for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -72,8 +72,7 @@ get_next_word (const char *buffer, unsigned int *length)
char c;
/* Skip any leading whitespace. */
while (isblank ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
beg = p;
c = *(p++);
@ -266,12 +265,15 @@ pattern_search (struct file *file, int archive,
/* Set LASTSLASH to point at the last slash in FILENAME
but not counting any slash at the end. (foo/bar/ counts as
bar/ in directory foo/, not empty in directory foo/bar/.) */
#ifdef VMS
lastslash = strrchr (filename, ']');
if (lastslash == 0)
lastslash = strrchr (filename, ':');
#else
lastslash = strrchr (filename, '/');
#ifdef VMS
if (lastslash == NULL)
lastslash = strrchr (filename, ']');
if (lastslash == NULL)
lastslash = strrchr (filename, '>');
if (lastslash == NULL)
lastslash = strrchr (filename, ':');
#endif
#ifdef HAVE_DOS_PATHS
/* Handle backslashes (possibly mixed with forward slashes)
and the case of "d:file". */
@ -282,7 +284,6 @@ pattern_search (struct file *file, int archive,
if (lastslash == 0 && filename[0] && filename[1] == ':')
lastslash = filename + 1;
}
#endif
#endif
if (lastslash != 0 && lastslash[1] == '\0')
lastslash = 0;
@ -315,7 +316,7 @@ pattern_search (struct file *file, int archive,
{
const char *target = rule->targets[ti];
const char *suffix = rule->suffixes[ti];
int check_lastslash;
char check_lastslash;
/* Rules that can match any filename and are not terminal
are ignored if we're recursing, so that they cannot be
@ -339,10 +340,10 @@ pattern_search (struct file *file, int archive,
if (lastslash)
{
#ifdef VMS
check_lastslash = (strchr (target, ']') == 0
&& strchr (target, ':') == 0);
check_lastslash = strpbrk (target, "/]>:") == NULL;
#else
check_lastslash = strchr (target, '/') == 0;
#endif
#ifdef HAVE_DOS_PATHS
/* Didn't find it yet: check for DOS-type directories. */
if (check_lastslash)
@ -350,7 +351,6 @@ pattern_search (struct file *file, int archive,
char *b = strchr (target, '\\');
check_lastslash = !(b || (target[0] && target[1] == ':'));
}
#endif
#endif
}
if (check_lastslash)
@ -437,7 +437,7 @@ pattern_search (struct file *file, int archive,
for (ri = 0; ri < nrules; ri++)
{
struct dep *dep;
int check_lastslash;
char check_lastslash;
unsigned int failed = 0;
int file_variables_set = 0;
unsigned int deps_found = 0;
@ -863,9 +863,10 @@ pattern_search (struct file *file, int archive,
/* We don't want to delete an intermediate file that happened
to be a prerequisite of some (other) target. Mark it as
precious. */
secondary. We don't want it to be precious as that disables
DELETE_ON_ERROR etc. */
if (f != 0)
f->precious = 1;
f->secondary = 1;
else
f = enter_file (imf->name);

634
job.c

File diff suppressed because it is too large Load diff

20
job.h
View file

@ -1,5 +1,5 @@
/* Definitions for managing subprocesses in GNU Make.
Copyright (C) 1992-2014 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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
@ -24,7 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* How to set close-on-exec for a file descriptor. */
#if !defined F_SETFD
#if !defined(F_SETFD) || !defined(F_GETFD)
# ifdef WINDOWS32
# define CLOSE_ON_EXEC(_d) process_noinherit(_d)
# else
@ -99,6 +99,7 @@ struct child
char *comname; /* Temporary command file name */
int efn; /* Completion event flag number */
int cstatus; /* Completion status */
int vms_launch_status; /* non-zero if lib$spawn, etc failed */
#endif
unsigned int command_line; /* Index into command_lines. */
@ -108,11 +109,14 @@ struct child
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
unsigned int recursive:1; /* Nonzero for recursive command ('+' etc.) */
unsigned int dontcare:1; /* Saved dontcare flag. */
};
extern struct child *children;
/* A signal handler for SIGCHLD, if needed. */
RETSIGTYPE child_handler (int sig);
int is_bourne_compatible_shell(const char *path);
void new_job (struct file *file);
void reap_children (int block, int err);
@ -120,20 +124,16 @@ void start_waiting_jobs (void);
char **construct_command_argv (char *line, char **restp, struct file *file,
int cmd_flags, char** batch_file);
#ifdef VMS
int child_execute_job (char *argv, struct child *child);
int child_execute_job (struct child *child, char *argv);
#else
# 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
int child_execute_job (struct output *out, int good_stdin, char **argv, char **envp);
#endif
#ifdef _AMIGA
void exec_command (char **argv) __attribute__ ((noreturn));
#elif defined(__EMX__)

30
load.c
View file

@ -1,5 +1,5 @@
/* Loading dynamic objects for GNU Make.
Copyright (C) 2012-2014 Free Software Foundation, Inc.
Copyright (C) 2012-2016 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
@ -45,8 +45,8 @@ struct load_list
static struct load_list *loaded_syms = NULL;
static load_func_t
load_object (const gmk_floc *flocp, int noerror,
const char *ldname, const char *symname)
load_object (const floc *flocp, int noerror, const char *ldname,
const char *symname)
{
static void *global_dl = NULL;
load_func_t symp;
@ -119,7 +119,7 @@ load_object (const gmk_floc *flocp, int noerror,
}
int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
load_file (const floc *flocp, const char **ldname, int noerror)
{
int nmlen = strlen (*ldname);
char *new = alloca (nmlen + CSTRLEN (SYMBOL_EXTENSION) + 1);
@ -168,9 +168,8 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
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;
goto exit;
/* If we didn't find a symbol name yet, construct it from the ldname. */
if (! symname)
@ -214,8 +213,21 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
/* 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);
{
size_t loadlen = strlen (loaded);
char *newval = alloca (loadlen + strlen (*ldname) + 2);
/* Don't add a space if it's empty. */
if (loadlen)
{
memcpy (newval, loaded, loadlen);
newval[loadlen++] = ' ';
}
strcpy (&newval[loadlen], *ldname);
do_variable_definition (flocp, ".LOADED", newval, o_default, f_simple, 0);
}
exit:
free (loaded);
return r;
}
@ -237,7 +249,7 @@ unload_file (const char *name)
#else
int
load_file (const gmk_floc *flocp, const char **ldname, int noerror)
load_file (const floc *flocp, const char **ldname UNUSED, int noerror)
{
if (! noerror)
O (fatal, flocp,
@ -247,7 +259,7 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
}
void
unload_file (const char *name)
unload_file (const char *name UNUSED)
{
O (fatal, NILF, "INTERNAL: Cannot unload when load is not supported!");
}

View file

@ -1,5 +1,5 @@
/* API for GNU Make dynamic objects.
Copyright (C) 2013-2014 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@ -37,17 +37,29 @@ gmk_free (char *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)
gmk_eval (const char *buffer, const gmk_floc *gfloc)
{
/* Preserve existing variable buffer context. */
char *pbuf;
unsigned int plen;
char *s;
floc fl;
floc *flp;
if (gfloc)
{
fl.filenm = gfloc->filenm;
fl.lineno = gfloc->lineno;
fl.offset = 0;
flp = &fl;
}
else
flp = NULL;
install_variable_buffer (&pbuf, &plen);
s = xstrdup (buffer);
eval_buffer (s, floc);
eval_buffer (s, flp);
free (s);
restore_variable_buffer (pbuf, plen);

600
main.c

File diff suppressed because it is too large Load diff

4
make.1
View file

@ -1,4 +1,4 @@
.TH MAKE 1 "03 March 2012" "GNU" "User Commands"
.TH MAKE 1 "28 February 2016" "GNU" "User Commands"
.SH NAME
make \- GNU make utility to maintain groups of programs
.SH SYNOPSIS
@ -363,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
McGrath. Maintained by Paul Smith.
.SH "COPYRIGHT"
Copyright \(co 1992-1993, 1996-2014 Free Software Foundation, Inc.
Copyright \(co 1992-1993, 1996-2016 Free Software Foundation, Inc.
This file is part of
.IR "GNU make" .
.LP

View file

@ -234,6 +234,9 @@
<File
RelativePath=".\w32\pathstuff.c">
</File>
<File
RelativePath=".\w32\w32os.c">
</File>
<File
RelativePath=".\w32\subproc\sub_proc.c">
</File>

View file

@ -74,8 +74,9 @@ $ endif
$ filelist = "alloca ar arscan commands default dir expand file function " + -
"guile hash implicit job load main misc read remake " + -
"remote-stub rule output signame variable version " + -
"vmsfunctions vmsify vpath " + -
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
"vmsfunctions vmsify vpath vms_progname vms_exit " + -
"vms_export_symbol [.glob]glob [.glob]fnmatch getopt1 " + -
"getopt strcache"
$!
$ copy config.h-vms config.h
$ n=0
@ -131,6 +132,7 @@ $!-----------------------------------------------------------------------------
$!
$ compileit : subroutine
$ ploc = f$locate("]",p1)
$! filnam = p1
$ if ploc .lt. f$length(p1)
$ then
$ objdir = f$extract(0, ploc+1, p1)
@ -139,14 +141,15 @@ $ else
$ objdir := []
$ write optf objdir+p1
$ endif
$ cc'ccopt'/include=([],[.glob])/obj='objdir' -
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS") -
$ cc'ccopt'/nested=none/include=([],[.glob])/obj='objdir' -
/define=("allocated_variable_expand_for_file=alloc_var_expand_for_file",-
"unlink=remove","HAVE_CONFIG_H","VMS") -
'p1'
$ exit
$ endsubroutine : compileit
$!
$!-----------------------------------------------------------------------------
$!Copyright (C) 1996-2014 Free Software Foundation, Inc.
$!Copyright (C) 1996-2016 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

View file

@ -1,6 +1,6 @@
# -*-Makefile-*- to build GNU make on VMS
#
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Copyright (C) 1996-2016 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
@ -32,9 +32,12 @@ CP = copy
#
ifeq ($(CC),cc)
CFLAGS = $(defines) /include=([],[.glob])/prefix=(all,except=(glob,globfree))/standard=relaxed/warn=(disable=questcompare)
cinclude = /nested=none/include=([],[.glob])
cprefix = /prefix=(all,except=(glob,globfree))
cwarn = /standard=relaxed/warn=(disable=questcompare)
CFLAGS = $(defines) $(cinclude)$(cprefix)$(cwarn)
else
CFLAGS = $(defines) /include=([],[.glob])
CFLAGS = $(defines) $(cinclude)
endif
#LDFLAGS = /deb
LDFLAGS =
@ -93,13 +96,14 @@ guile = ,guile.obj
objs = commands.obj,job.obj,output.obj,dir.obj,file.obj,misc.obj,hash.obj,\
load.obj,main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\
default.obj,variable.obj,expand.obj,function.obj,strcache.obj,\
vpath.obj,version.obj$(guile)\
$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob)
vpath.obj,version.obj,vms_progname.obj,vms_exit.obj,\
vms_export_symbol.obj$(guile)$(ARCHIVES)$(extras)$(getopt)$(glob)
srcs = commands.c job.c output.c dir.c file.c misc.c guile.c hash.c \
load.c main.c read.c remake.c rule.c implicit.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 vms_progname.c vms_exit.c \
vms_export_symbol.c $(ARCHIVES_SRC) $(ALLOCASRC) \
commands.h dep.h filedef.h job.h output.h makeint.h rule.h variable.h
@ -168,6 +172,9 @@ vmsfunctions.obj: vmsfunctions.c makeint.h config.h gnumake.h gettext.h \
vmsify.obj: vmsify.c
vpath.obj: vpath.c makeint.h config.h gnumake.h gettext.h filedef.h hash.h \
variable.h
vms_progname.obj: vms_progname.c
vms_exit.obj: vms_exit.c
vms_export_symbol.obj: vms_export_symbol.c
config.h: config.h-vms
$(CP) $< $@

194
makeint.h
View file

@ -1,5 +1,5 @@
/* Miscellaneous global declarations and portability cruft for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -95,8 +95,13 @@ char *alloca ();
extern int errno;
#endif
#ifndef isblank
# define isblank(c) ((c) == ' ' || (c) == '\t')
#ifdef __VMS
/* In strict ANSI mode, VMS compilers should not be defining the
VMS macro. Define it here instead of a bulk edit for the correct code.
*/
# ifndef VMS
# define VMS
# endif
#endif
#ifdef HAVE_UNISTD_H
@ -129,6 +134,10 @@ extern int errno;
# define SA_RESTART 0
#endif
#ifdef HAVE_VFORK_H
# include <vfork.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
@ -201,6 +210,13 @@ unsigned int get_path_max (void);
# include <perror.h>
/* Needed to use alloca on VMS. */
# include <builtins.h>
extern int vms_use_mcr_command;
extern int vms_always_use_cmd_file;
extern int vms_gnv_shell;
extern int vms_comma_separator;
extern int vms_legacy_behavior;
extern int vms_unix_simulation;
#endif
#ifndef __attribute__
@ -325,21 +341,6 @@ char *strsignal (int signum);
#define N_(msgid) gettext_noop (msgid)
#define S_(msg1,msg2,num) ngettext (msg1,msg2,num)
/* Handle other OSs.
To overcome an issue parsing paths in a DOS/Windows environment when
built in a unix based environment, override the PATH_SEPARATOR_CHAR
definition unless being built for Cygwin. */
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
# undef PATH_SEPARATOR_CHAR
# define PATH_SEPARATOR_CHAR ';'
#elif !defined(PATH_SEPARATOR_CHAR)
# if defined (VMS)
# define PATH_SEPARATOR_CHAR ','
# else
# define PATH_SEPARATOR_CHAR ':'
# endif
#endif
/* This is needed for getcwd() and chdir(), on some W32 systems. */
#if defined(HAVE_DIRECT_H)
# include <direct.h>
@ -375,7 +376,7 @@ extern int unixy_shell;
# endif
/* Include only the minimal stuff from windows.h. */
#define WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif /* WINDOWS32 */
#define ANY_SET(_v,_m) (((_v)&(_m)) != 0)
@ -383,7 +384,7 @@ extern int unixy_shell;
#define MAP_NUL 0x0001
#define MAP_BLANK 0x0002
#define MAP_SPACE 0x0004
#define MAP_NEWLINE 0x0004
#define MAP_COMMENT 0x0008
#define MAP_SEMI 0x0010
#define MAP_EQUALS 0x0020
@ -406,7 +407,40 @@ extern int unixy_shell;
# define MAP_VMSCOMMA 0x0000
#endif
#define STOP_SET(_v,_m) ANY_SET (stopchar_map[(unsigned char)(_v)],(_m))
#define MAP_SPACE (MAP_BLANK|MAP_NEWLINE)
/* Handle other OSs.
To overcome an issue parsing paths in a DOS/Windows environment when
built in a unix based environment, override the PATH_SEPARATOR_CHAR
definition unless being built for Cygwin. */
#if defined(HAVE_DOS_PATHS) && !defined(__CYGWIN__)
# undef PATH_SEPARATOR_CHAR
# define PATH_SEPARATOR_CHAR ';'
# define MAP_PATHSEP MAP_SEMI
#elif !defined(PATH_SEPARATOR_CHAR)
# if defined (VMS)
# define PATH_SEPARATOR_CHAR (vms_comma_separator ? ',' : ':')
# define MAP_PATHSEP (vms_comma_separator ? MAP_COMMA : MAP_SEMI)
# else
# define PATH_SEPARATOR_CHAR ':'
# define MAP_PATHSEP MAP_COLON
# endif
#elif PATH_SEPARATOR_CHAR == ':'
# define MAP_PATHSEP MAP_COLON
#elif PATH_SEPARATOR_CHAR == ';'
# define MAP_PATHSEP MAP_SEMI
#elif PATH_SEPARATOR_CHAR == ','
# define MAP_PATHSEP MAP_COMMA
#else
# error "Unknown PATH_SEPARATOR_CHAR"
#endif
#define STOP_SET(_v,_m) ANY_SET(stopchar_map[(unsigned char)(_v)],(_m))
#define ISBLANK(c) STOP_SET((c),MAP_BLANK)
#define ISSPACE(c) STOP_SET((c),MAP_SPACE)
#define NEXT_TOKEN(s) while (ISSPACE (*(s))) ++(s)
#define END_OF_TOKEN(s) while (! STOP_SET (*(s), MAP_SPACE|MAP_NUL)) ++(s)
#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT)
# define SET_STACK_SIZE
@ -416,7 +450,9 @@ extern int unixy_shell;
extern struct rlimit stack_limit;
#endif
#define NILF ((gmk_floc *)0)
#include <glob.h>
#define NILF ((floc *)0)
#define CSTRLEN(_s) (sizeof (_s)-1)
#define STRING_SIZE_TUPLE(_s) (_s), CSTRLEN(_s)
@ -424,20 +460,30 @@ extern struct rlimit stack_limit;
/* The number of bytes needed to represent the largest integer as a string. */
#define INTSTR_LENGTH CSTRLEN ("18446744073709551616")
#define DEFAULT_TTYNAME "true"
#ifdef HAVE_TTYNAME
# define TTYNAME(_f) ttyname (_f)
#else
# define TTYNAME(_f) "true"
# define TTYNAME(_f) DEFAULT_TTYNAME
#endif
/* Specify the location of elements read from makefiles. */
typedef struct
{
const char *filenm;
unsigned long lineno;
unsigned long offset;
} floc;
const char *concat (unsigned int, ...);
void message (int prefix, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void error (const gmk_floc *flocp, size_t length, const char *fmt, ...)
void error (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
void fatal (const gmk_floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
void fatal (const floc *flocp, size_t length, const char *fmt, ...)
__attribute__ ((noreturn, __format__ (__printf__, 3, 4)));
#define O(_t,_a,_f) _t((_a), 0, (_f))
#define OS(_t,_a,_f,_s) _t((_a), strlen (_s), (_f), (_s))
@ -483,7 +529,8 @@ time_t ar_member_date (const char *);
typedef long int (*ar_member_func_t) (int desc, const char *mem, int truncated,
long int hdrpos, long int datapos,
long int size, long int date, int uid,
int gid, int mode, const void *arg);
int gid, unsigned int mode,
const void *arg);
long int ar_scan (const char *archive, ar_member_func_t function, const void *arg);
int ar_name_equal (const char *name, const char *mem, int truncated);
@ -497,6 +544,8 @@ int file_exists_p (const char *);
int file_impossible_p (const char *);
void file_impossible (const char *);
const char *dir_name (const char *);
void print_dir_data_base (void);
void dir_setup_glob (glob_t *);
void hash_init_directories (void);
void define_default_variables (void);
@ -519,20 +568,21 @@ void child_access (void);
char *strip_whitespace (const char **begpp, const char **endpp);
void show_goal_error (void);
/* String caching */
void strcache_init (void);
void strcache_print_stats (const char *prefix);
int strcache_iscached (const char *str);
const char *strcache_add (const char *str);
const char *strcache_add_len (const char *str, unsigned int len);
int strcache_setbufsize (unsigned int size);
/* Guile support */
int guile_gmake_setup (const gmk_floc *flocp);
int guile_gmake_setup (const floc *flocp);
/* Loadable object support. Sets to the strcached name of the loaded file. */
typedef int (*load_func_t)(const gmk_floc *flocp);
int load_file (const gmk_floc *flocp, const char **filename, int noerror);
typedef int (*load_func_t)(const floc *flocp);
int load_file (const floc *flocp, const char **filename, int noerror);
void unload_file (const char *name);
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
@ -545,16 +595,16 @@ long int atol ();
long int lseek ();
# endif
#endif /* Not GNU C library or POSIX. */
#ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
# ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
char *getcwd ();
# endif
#else
# endif
# else
char *getwd ();
# define getcwd(buf, len) getwd (buf)
#endif
# define getcwd(buf, len) getwd (buf)
# endif
#endif /* Not GNU C library or POSIX. */
#if !HAVE_STRCASECMP
# if HAVE_STRICMP
@ -583,11 +633,12 @@ int strncasecmp (const char *s1, const char *s2, int n);
#define OUTPUT_SYNC_TARGET 2
#define OUTPUT_SYNC_RECURSE 3
extern const gmk_floc *reading_file;
extern const gmk_floc **expanding_var;
/* Non-GNU systems may not declare this in unistd.h. */
extern char **environ;
extern const floc *reading_file;
extern const floc **expanding_var;
extern unsigned short stopchar_map[];
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
@ -598,6 +649,8 @@ extern int warn_undefined_variables_flag, trace_flag, posix_pedantic;
extern int not_parallel, second_expansion, clock_skew_detected;
extern int rebuilding_makefiles, one_shell, output_sync, verify_flag;
extern const char *default_shell;
/* can we run commands via 'sh -c xxx' or must we use batch files? */
extern int batch_mode_shell;
@ -607,8 +660,6 @@ extern int batch_mode_shell;
extern char cmd_prefix;
extern unsigned int job_slots;
extern int job_fds[2];
extern int job_rfd;
#ifndef NO_FLOAT
extern double max_load_average;
#else
@ -622,10 +673,46 @@ extern const char *program;
#endif
#ifdef VMS
const char *vms_command(const char *argv0);
const char *vms_progname(const char *argv0);
const char *vms_command (const char *argv0);
const char *vms_progname (const char *argv0);
void vms_exit (int);
# define _exit(foo) vms_exit(foo)
# define exit(foo) vms_exit(foo)
extern char *program_name;
void
set_program_name (const char *arv0);
int
need_vms_symbol (void);
int
create_foreign_command (const char *command, const char *image);
int
vms_export_dcl_symbol (const char *name, const char *value);
int
vms_putenv_symbol (const char *string);
void
vms_restore_symbol (const char *string);
#endif
void remote_setup (void);
void remote_cleanup (void);
int start_remote_job_p (int);
int start_remote_job (char **, char **, int, int *, int *, int *);
int remote_status (int *, int *, int *, int);
void block_remote_children (void);
void unblock_remote_children (void);
int remote_kill (int id, int sig);
void print_variable_data_base (void);
void print_vpath_data_base (void);
extern char *starting_directory;
extern unsigned int makelevel;
extern char *version_string, *remote_description, *make_host;
@ -643,18 +730,9 @@ extern int handling_fatal_signal;
#endif
#ifdef VMS
/* These are the VMS __posix_exit compliant exit codes, constructed out of
STS$M_INHIB_MSG, C facility code, a POSIX condition code mask, MAKE_NNN<<3 and
the coresponding VMS severity, here STS$K_SUCCESS and STS$K_ERROR. */
# define MAKE_SUCCESS 0x1035a001
# define MAKE_TROUBLE 0x1035a00a
# define MAKE_FAILURE 0x1035a012
#else
# define MAKE_SUCCESS 0
# define MAKE_TROUBLE 1
# define MAKE_FAILURE 2
#endif
#define MAKE_SUCCESS 0
#define MAKE_TROUBLE 1
#define MAKE_FAILURE 2
/* Set up heap debugging library dmalloc. */

32
misc.c
View file

@ -1,5 +1,5 @@
/* Miscellaneous generic support functions for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -91,12 +91,13 @@ collapse_continuations (char *line)
{
/* Backslash/newline handling:
In traditional GNU make all trailing whitespace, consecutive
backslash/newlines, and any leading whitespace on the next line
is reduced to a single space.
backslash/newlines, and any leading non-newline whitespace on the
next line is reduced to a single space.
In POSIX, each backslash/newline and is replaced by a space. */
in = next_token (in);
while (ISBLANK (*in))
++in;
if (! posix_pedantic)
while (out > line && isblank ((unsigned char)out[-1]))
while (out > line && ISBLANK (out[-1]))
--out;
*out++ = ' ';
}
@ -314,8 +315,7 @@ lindex (const char *s, const char *limit, int c)
char *
end_of_token (const char *s)
{
while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
++s;
END_OF_TOKEN (s);
return (char *)s;
}
@ -324,8 +324,7 @@ end_of_token (const char *s)
char *
next_token (const char *s)
{
while (isblank ((unsigned char)*s))
++s;
NEXT_TOKEN (s);
return (char *)s;
}
@ -377,19 +376,6 @@ copy_dep_chain (const struct dep *d)
return firstnew;
}
/* Free a chain of 'struct dep'. */
void
free_dep_chain (struct dep *d)
{
while (d != 0)
{
struct dep *df = d;
d = d->next;
free_dep (df);
}
}
/* Free a chain of struct nameseq.
For struct dep chains use free_dep_chain. */
@ -400,7 +386,7 @@ free_ns_chain (struct nameseq *ns)
{
struct nameseq *t = ns;
ns = ns->next;
free (t);
free_ns (t);
}
}

84
os.h Normal file
View file

@ -0,0 +1,84 @@
/* Declarations for operating system interfaces for GNU Make.
Copyright (C) 2016 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/>. */
/* This section provides OS-specific functions to support the jobserver. */
#ifdef MAKE_JOBSERVER
/* Returns 1 if the jobserver is enabled, else 0. */
unsigned int jobserver_enabled (void);
/* Called in the master instance to set up the jobserver initially. */
unsigned int jobserver_setup (int job_slots);
/* Called in a child instance to connect to the jobserver. */
unsigned int jobserver_parse_auth (const char* auth);
/* Returns an allocated buffer used to pass to child instances. */
char *jobserver_get_auth (void);
/* Clear this instance's jobserver configuration. */
void jobserver_clear (void);
/* Recover all the jobserver tokens and return the number we got. */
unsigned int jobserver_acquire_all (void);
/* Release a jobserver token. If it fails and is_fatal is 1, fatal. */
void jobserver_release (int is_fatal);
/* Notify the jobserver that a child exited. */
void jobserver_signal (void);
/* Get ready to start a non-recursive child. */
void jobserver_pre_child (int);
/* Complete starting a non-recursive child. */
void jobserver_post_child (int);
/* Set up to acquire a new token. */
void jobserver_pre_acquire (void);
/* Wait until we can acquire a jobserver token.
TIMEOUT is 1 if we have other jobs waiting for the load to go down;
in this case we won't wait forever, so we can check the load.
Returns 1 if we got a token, or 0 if we stopped waiting due to a child
exiting or a timeout. */
unsigned int jobserver_acquire (int timeout);
#else
#define jobserver_enabled() (0)
#define jobserver_setup(_slots) (0)
#define jobserver_parse_auth(_auth) (0)
#define jobserver_get_auth() (NULL)
#define jobserver_clear() (void)(0)
#define jobserver_release(_fatal) (void)(0)
#define jobserver_acquire_all() (0)
#define jobserver_signal() (void)(0)
#define jobserver_pre_child(_r) (void)(0)
#define jobserver_post_child(_r) (void)(0)
#define jobserver_pre_acquire() (void)(0)
#define jobserver_acquire(_tmout) (0)
#endif
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
#if !defined(VMD) && !defined(WINDOWS32) && !defined(_AMIGA) && !defined(__MSDOS__)
int get_bad_stdin (void);
#else
# define get_bad_stdin() (-1)
#endif

View file

@ -1,5 +1,5 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013-2014 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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
@ -46,7 +46,7 @@ unsigned int stdio_traced = 0;
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
#ifdef HAVE_FCNTL
#ifdef HAVE_FCNTL_H
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#else
# define STREAM_OK(_s) 1
@ -174,7 +174,7 @@ static sync_handle_t sync_handle = -1;
/* Set up the sync handle. Disables output_sync on error. */
static int
sync_init ()
sync_init (void)
{
int combined_output = 0;
@ -283,7 +283,7 @@ release_semaphore (void *sem)
/* 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 ()
output_tmpfd (void)
{
int fd = -1;
FILE *tfile = tmpfile ();
@ -344,7 +344,7 @@ setup_tmpfile (struct output *out)
/* If we failed to create a temp file, disable output sync going forward. */
error:
output_close (out);
output_sync = 0;
output_sync = OUTPUT_SYNC_NONE;
}
/* Synchronize the output of jobs in -j mode to keep the results of
@ -441,7 +441,7 @@ output_tmpfile (char **name, const char *template)
# ifdef HAVE_FDOPEN
/* Can't use mkstemp(), but guard against a race condition. */
fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
if (fd == -1)
return 0;
return fdopen (fd, "w");
@ -558,7 +558,7 @@ output_close (struct output *out)
/* We're about to generate output: be sure it's set up. */
void
output_start ()
output_start (void)
{
#ifndef NO_OUTPUT_SYNC
/* If we're syncing output make sure the temporary file is set up. */
@ -640,7 +640,7 @@ message (int prefix, size_t len, const char *fmt, ...)
/* Print an error message. */
void
error (const gmk_floc *flocp, size_t len, const char *fmt, ...)
error (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
char *p;
@ -651,7 +651,7 @@ error (const gmk_floc *flocp, size_t len, const char *fmt, ...)
p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
else if (makelevel == 0)
sprintf (p, "%s: ", program);
else
@ -671,7 +671,7 @@ error (const gmk_floc *flocp, size_t len, const char *fmt, ...)
/* Print an error message and exit. */
void
fatal (const gmk_floc *flocp, size_t len, const char *fmt, ...)
fatal (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
const char *stop = _(". Stop.\n");
@ -683,7 +683,7 @@ fatal (const gmk_floc *flocp, size_t len, const char *fmt, ...)
p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
else if (makelevel == 0)
sprintf (p, "%s: *** ", program);
else

View file

@ -1,5 +1,5 @@
/* Output to stdout / stderr for GNU make
Copyright (C) 2013-2014 Free Software Foundation, Inc.
Copyright (C) 2013-2016 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

View file

@ -1,5 +1,5 @@
# This is a -*-Makefile-*-
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# Copyright (C) 2002-2016 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

View file

@ -1,5 +1,5 @@
# List of source files containing translatable strings.
# Copyright (C) 2000-2014 Free Software Foundation, Inc.
# Copyright (C) 2000-2016 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
@ -32,6 +32,7 @@ load.c
main.c
misc.c
output.c
posixos.c
read.c
remake.c
remote-cstms.c
@ -43,3 +44,4 @@ variable.h
vmsfunctions.c
vmsjobs.c
vpath.c
w32/w32os.c

431
posixos.c Normal file
View file

@ -0,0 +1,431 @@
/* POSIX-based operating system interface for GNU Make.
Copyright (C) 2016 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 <stdio.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#if defined(HAVE_PSELECT) && defined(HAVE_SYS_SELECT_H)
# include <sys/select.h>
#endif
#include "debug.h"
#include "job.h"
#include "os.h"
#ifdef MAKE_JOBSERVER
/* This section provides OS-specific functions to support the jobserver. */
/* These track the state of the jobserver pipe. Passed to child instances. */
static int job_fds[2] = { -1, -1 };
/* Used to signal read() that a SIGCHLD happened. Always CLOEXEC.
If we use pselect() this will never be created and always -1.
*/
static int job_rfd = -1;
/* Token written to the pipe (could be any character...) */
static char token = '+';
static int
make_job_rfd (void)
{
#ifdef HAVE_PSELECT
/* Pretend we succeeded. */
return 0;
#else
EINTRLOOP (job_rfd, dup (job_fds[0]));
if (job_rfd >= 0)
CLOSE_ON_EXEC (job_rfd);
return job_rfd;
#endif
}
unsigned int
jobserver_setup (int slots)
{
int r;
EINTRLOOP (r, pipe (job_fds));
if (r < 0)
pfatal_with_name (_("creating jobs pipe"));
if (make_job_rfd () < 0)
pfatal_with_name (_("duping jobs pipe"));
while (slots--)
{
EINTRLOOP (r, write (job_fds[1], &token, 1));
if (r != 1)
pfatal_with_name (_("init jobserver pipe"));
}
return 1;
}
unsigned int
jobserver_parse_auth (const char *auth)
{
/* Given the command-line parameter, parse it. */
if (sscanf (auth, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
OS (fatal, NILF,
_("internal error: invalid --jobserver-auth string '%s'"), auth);
DB (DB_JOBS,
(_("Jobserver client (fds %d,%d)\n"), job_fds[0], job_fds[1]));
#ifdef HAVE_FCNTL_H
# define FD_OK(_f) (fcntl ((_f), F_GETFD) != -1)
#else
# define FD_OK(_f) 1
#endif
/* Make sure our pipeline is valid, and (possibly) create a duplicate pipe,
that will be closed in the SIGCHLD handler. If this fails with EBADF,
the parent has closed the pipe on us because it didn't think we were a
submake. If so, warn and default to -j1. */
if (!FD_OK (job_fds[0]) || !FD_OK (job_fds[1]) || make_job_rfd () < 0)
{
if (errno != EBADF)
pfatal_with_name (_("jobserver pipeline"));
job_fds[0] = job_fds[1] = -1;
return 0;
}
return 1;
}
char *
jobserver_get_auth (void)
{
char *auth = xmalloc ((INTSTR_LENGTH * 2) + 2);
sprintf (auth, "%d,%d", job_fds[0], job_fds[1]);
return auth;
}
unsigned int
jobserver_enabled (void)
{
return job_fds[0] >= 0;
}
void
jobserver_clear (void)
{
if (job_fds[0] >= 0)
close (job_fds[0]);
if (job_fds[1] >= 0)
close (job_fds[1]);
if (job_rfd >= 0)
close (job_rfd);
job_fds[0] = job_fds[1] = job_rfd = -1;
}
void
jobserver_release (int is_fatal)
{
int r;
EINTRLOOP (r, write (job_fds[1], &token, 1));
if (r != 1)
{
if (is_fatal)
pfatal_with_name (_("write jobserver"));
perror_with_name ("write", "");
}
}
unsigned int
jobserver_acquire_all (void)
{
unsigned int tokens = 0;
/* Close the write side, so the read() won't hang. */
close (job_fds[1]);
job_fds[1] = -1;
while (1)
{
char intake;
int r;
EINTRLOOP (r, read (job_fds[0], &intake, 1));
if (r != 1)
return tokens;
++tokens;
}
}
/* Prepare the jobserver to start a child process. */
void
jobserver_pre_child (int recursive)
{
/* If it's not a recursive make, avoid polutting the jobserver pipes. */
if (!recursive && job_fds[0] >= 0)
{
CLOSE_ON_EXEC (job_fds[0]);
CLOSE_ON_EXEC (job_fds[1]);
}
}
void
jobserver_post_child (int recursive)
{
#if defined(F_GETFD) && defined(F_SETFD)
if (!recursive && job_fds[0] >= 0)
{
unsigned int i;
for (i = 0; i < 2; ++i)
{
int flags;
EINTRLOOP (flags, fcntl (job_fds[i], F_GETFD));
if (flags >= 0)
{
int r;
EINTRLOOP (r, fcntl (job_fds[i], F_SETFD, flags & ~FD_CLOEXEC));
}
}
}
#endif
}
void
jobserver_signal (void)
{
if (job_rfd >= 0)
{
close (job_rfd);
job_rfd = -1;
}
}
void
jobserver_pre_acquire (void)
{
/* Make sure we have a dup'd FD. */
if (job_rfd < 0 && job_fds[0] >= 0 && make_job_rfd () < 0)
pfatal_with_name (_("duping jobs pipe"));
}
#ifdef HAVE_PSELECT
/* Use pselect() to atomically wait for both a signal and a file descriptor.
It also provides a timeout facility so we don't need to use SIGALRM.
This method relies on the fact that SIGCHLD will be blocked everywhere,
and only unblocked (atomically) within the pselect() call, so we can
never miss a SIGCHLD.
*/
unsigned int
jobserver_acquire (int timeout)
{
sigset_t empty;
fd_set readfds;
struct timespec spec;
struct timespec *specp = NULL;
int r;
char intake;
sigemptyset (&empty);
FD_ZERO (&readfds);
FD_SET (job_fds[0], &readfds);
if (timeout)
{
/* Alarm after one second (is this too granular?) */
spec.tv_sec = 1;
spec.tv_nsec = 0;
specp = &spec;
}
r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty);
if (r == -1)
{
/* Better be SIGCHLD. */
if (errno != EINTR)
pfatal_with_name (_("pselect jobs pipe"));
return 0;
}
if (r == 0)
/* Timeout. */
return 0;
/* The read FD is ready: read it! */
EINTRLOOP (r, read (job_fds[0], &intake, 1));
if (r < 0)
pfatal_with_name (_("read jobs pipe"));
/* What does it mean if read() returns 0? It shouldn't happen because only
the master make can reap all the tokens and close the write side...?? */
return r > 0;
}
#else
/* This method uses a "traditional" UNIX model for waiting on both a signal
and a file descriptor. However, it's complex and since we have a SIGCHLD
handler installed we need to check ALL system calls for EINTR: painful!
Read a token. As long as there's no token available we'll block. We
enable interruptible system calls before the read(2) so that if we get a
SIGCHLD while we're waiting, we'll return with EINTR and we can process the
death(s) and return tokens to the free pool.
Once we return from the read, we immediately reinstate restartable system
calls. This allows us to not worry about checking for EINTR on all the
other system calls in the program.
There is one other twist: there is a span between the time reap_children()
does its last check for dead children and the time the read(2) call is
entered, below, where if a child dies we won't notice. This is extremely
serious as it could cause us to deadlock, given the right set of events.
To avoid this, we do the following: before we reap_children(), we dup(2)
the read FD on the jobserver pipe. The read(2) call below uses that new
FD. In the signal handler, we close that FD. That way, if a child dies
during the section mentioned above, the read(2) will be invoked with an
invalid FD and will return immediately with EBADF. */
static RETSIGTYPE
job_noop (int sig UNUSED)
{
}
/* Set the child handler action flags to FLAGS. */
static void
set_child_handler_action_flags (int set_handler, int set_alarm)
{
struct sigaction sa;
#ifdef __EMX__
/* The child handler must be turned off here. */
signal (SIGCHLD, SIG_DFL);
#endif
memset (&sa, '\0', sizeof sa);
sa.sa_handler = child_handler;
sa.sa_flags = set_handler ? 0 : SA_RESTART;
#if defined SIGCHLD
if (sigaction (SIGCHLD, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGCHLD");
#endif
#if defined SIGCLD && SIGCLD != SIGCHLD
if (sigaction (SIGCLD, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGCLD");
#endif
#if defined SIGALRM
if (set_alarm)
{
/* If we're about to enter the read(), set an alarm to wake up in a
second so we can check if the load has dropped and we can start more
work. On the way out, turn off the alarm and set SIG_DFL. */
if (set_handler)
{
sa.sa_handler = job_noop;
sa.sa_flags = 0;
if (sigaction (SIGALRM, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGALRM");
alarm (1);
}
else
{
alarm (0);
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
if (sigaction (SIGALRM, &sa, NULL) < 0)
pfatal_with_name ("sigaction: SIGALRM");
}
}
#endif
}
unsigned int
jobserver_acquire (int timeout)
{
char intake;
int got_token;
int saved_errno;
/* Set interruptible system calls, and read() for a job token. */
set_child_handler_action_flags (1, timeout);
EINTRLOOP (got_token, read (job_rfd, &intake, 1));
saved_errno = errno;
set_child_handler_action_flags (0, timeout);
if (got_token == 1)
return 1;
/* If the error _wasn't_ expected (EINTR or EBADF), fatal. Otherwise,
go back and reap_children(), and try again. */
errno = saved_errno;
if (errno != EINTR && errno != EBADF)
pfatal_with_name (_("read jobs pipe"));
if (errno == EBADF)
DB (DB_JOBS, ("Read returned EBADF.\n"));
return 0;
}
#endif
#endif /* MAKE_JOBSERVER */
/* Create a "bad" file descriptor for stdin when parallel jobs are run. */
int
get_bad_stdin (void)
{
static int bad_stdin = -1;
/* Set up a bad standard input that reads from a broken pipe. */
if (bad_stdin == -1)
{
/* Make a file descriptor that is the read end of a broken pipe.
This will be used for some children's standard inputs. */
int pd[2];
if (pipe (pd) == 0)
{
/* Close the write side. */
(void) close (pd[1]);
/* Save the read side. */
bad_stdin = pd[0];
/* Set the descriptor to close on exec, so it does not litter any
child's descriptor table. When it is dup2'd onto descriptor 0,
that descriptor will not close on exec. */
CLOSE_ON_EXEC (bad_stdin);
}
}
return bad_stdin;
}

193
read.c
View file

@ -1,5 +1,5 @@
/* Reading and parsing of makefiles for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -18,8 +18,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <glob.h>
#include "filedef.h"
#include "dep.h"
#include "job.h"
@ -54,7 +52,7 @@ struct ebuffer
char *bufstart; /* Start of the entire buffer. */
unsigned int size; /* Malloc'd size of buffer. */
FILE *fp; /* File, or NULL if this is an internal buffer. */
gmk_floc floc; /* Info on the file in fp (if any). */
floc floc; /* Info on the file in fp (if any). */
};
/* Track the modifiers we can have on variable assignments */
@ -128,13 +126,13 @@ static unsigned int max_incl_len;
/* The filename and pointer to line number of the
makefile currently being read in. */
const gmk_floc *reading_file = 0;
const floc *reading_file = 0;
/* The chain of files read by read_all_makefiles. */
static struct dep *read_files = 0;
static struct goaldep *read_files = 0;
static int eval_makefile (const char *filename, int flags);
static struct goaldep *eval_makefile (const char *filename, int flags);
static void eval (struct ebuffer *buffer, int flags);
static long readline (struct ebuffer *ebuf);
@ -142,16 +140,16 @@ static void do_undefine (char *name, enum variable_origin origin,
struct ebuffer *ebuf);
static struct variable *do_define (char *name, enum variable_origin origin,
struct ebuffer *ebuf);
static int conditional_line (char *line, int len, const gmk_floc *flocp);
static int conditional_line (char *line, int len, const floc *flocp);
static void record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
char prefix, const gmk_floc *flocp);
char prefix, const floc *flocp);
static void record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin,
struct vmodifiers *vmod,
const gmk_floc *flocp);
const floc *flocp);
static enum make_word_type get_next_mword (char *buffer, char *delim,
char **startp, unsigned int *length);
static void remove_comments (char *line);
@ -167,7 +165,7 @@ static char *unescape_char (char *string, int c);
/* Read in all the makefiles and return a chain of targets to rebuild. */
struct dep *
struct goaldep *
read_all_makefiles (const char **makefiles)
{
unsigned int num_makefiles = 0;
@ -217,17 +215,11 @@ read_all_makefiles (const char **makefiles)
if (makefiles != 0)
while (*makefiles != 0)
{
struct dep *tail = read_files;
struct dep *d;
struct goaldep *d = eval_makefile (*makefiles, 0);
if (! eval_makefile (*makefiles, 0))
if (errno)
perror_with_name ("", *makefiles);
/* Find the first element eval_makefile() added to read_files. */
d = read_files;
while (d->next != tail)
d = d->next;
/* Reuse the storage allocated for the read_file. */
*makefiles = dep_name (d);
++num_makefiles;
@ -241,7 +233,8 @@ read_all_makefiles (const char **makefiles)
static const char *default_makefiles[] =
#ifdef VMS
/* all lower case since readdir() (the vms version) 'lowercasifies' */
{ "makefile.vms", "gnumakefile.", "makefile.", 0 };
/* TODO: Above is not always true, this needs more work */
{ "makefile.vms", "gnumakefile", "makefile", 0 };
#else
#ifdef _AMIGA
{ "GNUmakefile", "Makefile", "SMakefile", 0 };
@ -259,25 +252,25 @@ read_all_makefiles (const char **makefiles)
if (*p != 0)
{
if (! eval_makefile (*p, 0))
eval_makefile (*p, 0);
if (errno)
perror_with_name ("", *p);
}
else
{
/* No default makefile was found. Add the default makefiles to the
'read_files' chain so they will be updated if possible. */
struct dep *tail = read_files;
struct goaldep *tail = read_files;
/* Add them to the tail, after any MAKEFILES variable makefiles. */
while (tail != 0 && tail->next != 0)
tail = tail->next;
for (p = default_makefiles; *p != 0; ++p)
{
struct dep *d = alloc_dep ();
struct goaldep *d = alloc_goaldep ();
d->file = enter_file (strcache_add (*p));
d->dontcare = 1;
/* Tell update_goal_chain to bail out as soon as this file is
made, and main not to die if we can't make this file. */
d->changed = RM_DONTCARE;
d->flags = RM_DONTCARE;
if (tail == 0)
read_files = d;
else
@ -318,17 +311,18 @@ restore_conditionals (struct conditionals *saved)
conditionals = saved;
}
static int
static struct goaldep *
eval_makefile (const char *filename, int flags)
{
struct dep *deps;
struct goaldep *deps;
struct ebuffer ebuf;
const gmk_floc *curfile;
const floc *curfile;
char *expanded = 0;
int makefile_errno;
ebuf.floc.filenm = filename; /* Use the original file name. */
ebuf.floc.lineno = 1;
ebuf.floc.offset = 0;
if (ISDB (DB_VERBOSE))
{
@ -400,16 +394,14 @@ eval_makefile (const char *filename, int flags)
filename = strcache_add (filename);
/* Add FILENAME to the chain of read makefiles. */
deps = alloc_dep ();
deps = alloc_goaldep ();
deps->next = read_files;
read_files = deps;
deps->file = lookup_file (filename);
if (deps->file == 0)
deps->file = enter_file (filename);
filename = deps->file->name;
deps->changed = flags;
if (flags & RM_DONTCARE)
deps->dontcare = 1;
deps->flags = flags;
free (expanded);
@ -418,10 +410,10 @@ eval_makefile (const char *filename, int flags)
if (ebuf.fp == 0)
{
/* If we did some searching, errno has the error from the last
attempt, rather from FILENAME itself. Restore it in case the
attempt, rather from FILENAME itself. Store it in case the
caller wants to use it in a message. */
errno = makefile_errno;
return 0;
return deps;
}
/* Set close-on-exec to avoid leaking the makefile to children, such as
@ -451,16 +443,17 @@ eval_makefile (const char *filename, int flags)
free (ebuf.bufstart);
alloca (0);
return 1;
errno = 0;
return deps;
}
void
eval_buffer (char *buffer, const gmk_floc *floc)
eval_buffer (char *buffer, const floc *flocp)
{
struct ebuffer ebuf;
struct conditionals *saved;
struct conditionals new;
const gmk_floc *curfile;
const floc *curfile;
/* Evaluate the buffer */
@ -468,14 +461,15 @@ eval_buffer (char *buffer, const gmk_floc *floc)
ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer;
ebuf.fp = NULL;
if (floc)
ebuf.floc = *floc;
if (flocp)
ebuf.floc = *flocp;
else if (reading_file)
ebuf.floc = *reading_file;
else
{
ebuf.floc.filenm = NULL;
ebuf.floc.lineno = 1;
ebuf.floc.offset = 0;
}
curfile = reading_file;
@ -510,7 +504,7 @@ parse_var_assignment (const char *line, struct vmodifiers *vmod)
memset (vmod, '\0', sizeof (*vmod));
/* Find the start of the next token. If there isn't one we're done. */
line = next_token (line);
NEXT_TOKEN (line);
if (*line == '\0')
return (char *)line;
@ -589,8 +583,8 @@ eval (struct ebuffer *ebuf, int set_default)
char prefix = cmd_prefix;
const char *pattern = 0;
const char *pattern_percent;
gmk_floc *fstart;
gmk_floc fi;
floc *fstart;
floc fi;
#define record_waiting_files() \
do \
@ -598,6 +592,7 @@ eval (struct ebuffer *ebuf, int set_default)
if (filenames != 0) \
{ \
fi.lineno = tgts_started; \
fi.offset = 0; \
record_files (filenames, pattern, pattern_percent, depstr, \
cmds_started, commands, commands_idx, two_colon, \
prefix, &fi); \
@ -719,8 +714,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* Get rid if starting space (including formfeed, vtab, etc.) */
p = collapsed;
while (isspace ((unsigned char)*p))
++p;
NEXT_TOKEN (p);
/* See if this is a variable assignment. We need to do this early, to
allow variables with names like 'ifdef', 'export', 'private', etc. */
@ -730,9 +724,6 @@ eval (struct ebuffer *ebuf, int set_default)
struct variable *v;
enum variable_origin origin = vmod.override_v ? o_override : o_file;
/* Variable assignment ends the previous rule. */
record_waiting_files ();
/* If we're ignoring then we're done now. */
if (ignoring)
{
@ -741,6 +732,9 @@ eval (struct ebuffer *ebuf, int set_default)
continue;
}
/* Variable assignment ends the previous rule. */
record_waiting_files ();
if (vmod.undefine_v)
{
do_undefine (p, origin, ebuf);
@ -768,7 +762,7 @@ eval (struct ebuffer *ebuf, int set_default)
p2 = end_of_token (p);
wlen = p2 - p;
p2 = next_token (p2);
NEXT_TOKEN (p2);
/* If we're in an ignored define, skip this line (but maybe get out). */
if (in_ignored_define)
@ -903,21 +897,20 @@ eval (struct ebuffer *ebuf, int set_default)
while (files != 0)
{
struct nameseq *next = files->next;
const char *name = files->name;
int r;
int flags = (RM_INCLUDED | RM_NO_TILDE
| (noerror ? RM_DONTCARE : 0)
| (set_default ? 0 : RM_NO_DEFAULT_GOAL));
struct goaldep *d = eval_makefile (files->name, flags);
if (errno)
{
d->error = (unsigned short)errno;
d->floc = *fstart;
}
free_ns (files);
files = next;
r = eval_makefile (name,
(RM_INCLUDED | RM_NO_TILDE
| (noerror ? RM_DONTCARE : 0)
| (set_default ? 0 : RM_NO_DEFAULT_GOAL)));
if (!r && !noerror)
{
const char *err = strerror (errno);
OSS (error, fstart, "%s: %s", name, err);
}
}
/* Restore conditional state. */
@ -957,7 +950,7 @@ eval (struct ebuffer *ebuf, int set_default)
{
struct nameseq *next = files->next;
const char *name = files->name;
struct dep *deps;
struct goaldep *deps;
int r;
/* Load the file. 0 means failure. */
@ -973,7 +966,7 @@ eval (struct ebuffer *ebuf, int set_default)
continue;
/* It succeeded, so add it to the list "to be rebuilt". */
deps = alloc_dep ();
deps = alloc_goaldep ();
deps->next = read_files;
read_files = deps;
deps->file = lookup_file (name);
@ -1241,8 +1234,7 @@ eval (struct ebuffer *ebuf, int set_default)
The rule is that it's only a target, if there are TWO :'s
OR a space around the :.
*/
if (p && !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
if (p && !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
p = 0;
#endif
#ifdef HAVE_DOS_PATHS
@ -1435,7 +1427,7 @@ do_undefine (char *name, enum variable_origin origin, struct ebuffer *ebuf)
if (*name == '\0')
O (fatal, &ebuf->floc, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
while (p > name && ISBLANK (*p))
--p;
p[1] = '\0';
@ -1452,7 +1444,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
{
struct variable *v;
struct variable var;
gmk_floc defstart;
floc defstart;
int nlevels = 1;
unsigned int length = 100;
char *definition = xmalloc (length);
@ -1480,7 +1472,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
if (name[0] == '\0')
O (fatal, &defstart, _("empty variable name"));
p = name + strlen (name) - 1;
while (p > name && isblank ((unsigned char)*p))
while (p > name && ISBLANK (*p))
--p;
p[1] = '\0';
@ -1508,13 +1500,13 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
len = strlen (p);
/* If this is another 'define', increment the level count. */
if ((len == 6 || (len > 6 && isblank ((unsigned char)p[6])))
if ((len == 6 || (len > 6 && ISBLANK (p[6])))
&& strneq (p, "define", 6))
++nlevels;
/* If this is an 'endef', decrement the count. If it's now 0,
we've found the last one. */
else if ((len == 5 || (len > 5 && isblank ((unsigned char)p[5])))
else if ((len == 5 || (len > 5 && ISBLANK (p[5])))
&& strneq (p, "endef", 5))
{
p += 5;
@ -1568,7 +1560,7 @@ do_define (char *name, enum variable_origin origin, struct ebuffer *ebuf)
1 if following text should be ignored. */
static int
conditional_line (char *line, int len, const gmk_floc *flocp)
conditional_line (char *line, int len, const floc *flocp)
{
const char *cmdname;
enum { c_ifdef, c_ifndef, c_ifeq, c_ifneq, c_else, c_endif } cmdtype;
@ -1590,7 +1582,8 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
return -2;
/* Found one: skip past it and any whitespace after it. */
line = next_token (line + len);
line += len;
NEXT_TOKEN (line);
#define EXTRATEXT() OS (error, flocp, _("extraneous text after '%s' directive"), cmdname)
#define EXTRACMD() OS (fatal, flocp, _("extraneous '%s'"), cmdname)
@ -1711,7 +1704,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
/* Make sure there's only one variable name to test. */
p = end_of_token (var);
i = p - var;
p = next_token (p);
NEXT_TOKEN (p);
if (*p != '\0')
return -1;
@ -1757,7 +1750,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
{
/* Strip blanks after the first string. */
char *p = line++;
while (isblank ((unsigned char)p[-1]))
while (ISBLANK (p[-1]))
--p;
*p = '\0';
}
@ -1773,7 +1766,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
if (termin != ',')
/* Find the start of the second string. */
line = next_token (line);
NEXT_TOKEN (line);
termin = termin == ',' ? ')' : *line;
if (termin != ')' && termin != '"' && termin != '\'')
@ -1808,8 +1801,8 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
if (*line == '\0')
return -1;
*line = '\0';
line = next_token (++line);
*(line++) = '\0';
NEXT_TOKEN (line);
if (*line != '\0')
EXTRATEXT ();
@ -1838,7 +1831,7 @@ conditional_line (char *line, int len, const gmk_floc *flocp)
static void
record_target_var (struct nameseq *filenames, char *defn,
enum variable_origin origin, struct vmodifiers *vmod,
const gmk_floc *flocp)
const floc *flocp)
{
struct nameseq *nextf;
struct variable_set_list *global;
@ -1942,7 +1935,7 @@ record_files (struct nameseq *filenames, const char *pattern,
const char *pattern_percent, char *depstr,
unsigned int cmds_started, char *commands,
unsigned int commands_idx, int two_colon,
char prefix, const gmk_floc *flocp)
char prefix, const floc *flocp)
{
struct commands *cmds;
struct dep *deps;
@ -1966,6 +1959,7 @@ record_files (struct nameseq *filenames, const char *pattern,
cmds = xmalloc (sizeof (struct commands));
cmds->fileinfo.filenm = flocp->filenm;
cmds->fileinfo.lineno = cmds_started;
cmds->fileinfo.offset = 0;
cmds->commands = xstrndup (commands, commands_idx);
cmds->command_lines = 0;
cmds->recipe_prefix = prefix;
@ -2261,6 +2255,10 @@ find_char_unquote (char *string, int map)
{
char openparen = p[1];
/* Check if '$' is the last character in the string. */
if (openparen == '\0')
break;
p += 2;
/* Skip the contents of a non-quoted, multi-char variable ref. */
@ -2342,6 +2340,10 @@ unescape_char (char *string, int c)
/* It's not; just take it all without unescaping. */
memmove (p, s, l);
p += l;
// If we hit the end of the string, we're done
if (*e == '\0')
break;
}
else if (l > 1)
{
@ -2350,6 +2352,7 @@ unescape_char (char *string, int c)
memmove (p, s, l);
p += l;
}
s = e;
}
@ -2457,7 +2460,7 @@ find_percent_cached (const char **string)
Since we aren't really reading from a file, don't bother with linenumbers.
*/
static unsigned long
static long
readstring (struct ebuffer *ebuf)
{
char *eol;
@ -2631,7 +2634,7 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
char c;
/* Skip any leading whitespace. */
while (isblank ((unsigned char)*p))
while (ISBLANK (*p))
++p;
beg = p;
@ -2729,6 +2732,8 @@ get_next_mword (char *buffer, char *delim, char **startp, unsigned int *length)
c = *(p++);
if (c == '$')
break;
if (c == '\0')
goto done_word;
/* This is a variable reference, so note that it's expandable.
Then read it to the matching close paren. */
@ -2913,7 +2918,6 @@ tilde_expand (const char *name)
#ifndef VMS
if (name[1] == '/' || name[1] == '\0')
{
extern char *getenv ();
char *home_dir;
int is_variable;
@ -2936,7 +2940,6 @@ tilde_expand (const char *name)
# if !defined(_AMIGA) && !defined(WINDOWS32)
if (home_dir == 0 || home_dir[0] == '\0')
{
extern char *getlogin ();
char *logname = getlogin ();
home_dir = 0;
if (logname != 0)
@ -3005,8 +3008,6 @@ void *
parse_file_seq (char **stringp, unsigned int size, int stopmap,
const char *prefix, int flags)
{
extern void dir_setup_glob (glob_t *glob);
/* tmp points to tmpbuf after the prefix, if any.
tp is the end of the buffer. */
static char *tmpbuf = NULL;
@ -3064,7 +3065,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
int i;
/* Skip whitespace; at the end of the string or STOPCHAR we're done. */
p = next_token (p);
NEXT_TOKEN (p);
if (STOP_SET (*p, stopmap))
break;
@ -3079,8 +3080,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
#endif
#ifdef _AMIGA
if (p && STOP_SET (*p, stopmap & MAP_COLON)
&& !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
&& !(ISSPACE (p[1]) || !p[1] || ISSPACE (p[-1])))
p = find_char_unquote (p+1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
#ifdef HAVE_DOS_PATHS
@ -3089,7 +3089,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
Note that tokens separated by spaces should be treated as separate
tokens since make doesn't allow path names with spaces */
if (stopmap | MAP_COLON)
while (p != 0 && !isspace ((unsigned char)*p) &&
while (p != 0 && !ISSPACE (*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
p = find_char_unquote (p + 1, stopmap|MAP_VMSCOMMA|MAP_BLANK);
#endif
@ -3099,12 +3099,15 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
/* Strip leading "this directory" references. */
if (NONE_SET (flags, PARSEFS_NOSTRIP))
#ifdef VMS
/* Skip leading '[]'s. */
while (p - s > 2 && s[0] == '[' && s[1] == ']')
#else
/* Skip leading '[]'s. should only be one set or bug somwhere else */
if (p - s > 2 && s[0] == '[' && s[1] == ']')
s += 2;
/* Skip leading '<>'s. should only be one set or bug somwhere else */
if (p - s > 2 && s[0] == '<' && s[1] == '>')
s += 2;
#endif
/* Skip leading './'s. */
while (p - s > 2 && s[0] == '.' && s[1] == '/')
#endif
{
/* Skip "./" and all following slashes. */
s += 2;
@ -3118,9 +3121,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
if (s == p)
{
/* The name was stripped to empty ("./"). */
#if defined(VMS)
continue;
#elif defined(_AMIGA)
#if defined(_AMIGA)
/* PDS-- This cannot be right!! */
tp[0] = '\0';
nlen = 0;
@ -3183,7 +3184,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
do
{
const char *o = e;
e = next_token (e);
NEXT_TOKEN (e);
/* 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
last char in the word. */

155
remake.c
View file

@ -1,5 +1,5 @@
/* Basic dependency engine for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -37,8 +37,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <io.h>
#endif
extern int try_implicit_rule (struct file *file, unsigned int depth);
/* The test for circular dependencies is based on the 'updating' bit in
'struct file'. However, double colon targets have separate 'struct
@ -55,8 +53,13 @@ extern int try_implicit_rule (struct file *file, unsigned int depth);
/* Incremented when a command is started (under -n, when one would be). */
unsigned int commands_started = 0;
/* Current value for pruning the scan of the goal chain (toggle 0/1). */
static unsigned int considered;
/* Set to the goal dependency. Mostly needed for remaking makefiles. */
static struct goaldep *goal_list;
static struct dep *goal_dep;
/* Current value for pruning the scan of the goal chain.
All files start with considered == 0. */
static unsigned int considered = 0;
static enum update_status update_file (struct file *file, unsigned int depth);
static enum update_status update_file_1 (struct file *file, unsigned int depth);
@ -77,31 +80,22 @@ static const char *library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr);
one goal whose 'changed' member is nonzero is successfully made. */
enum update_status
update_goal_chain (struct dep *goals)
update_goal_chain (struct goaldep *goaldeps)
{
int t = touch_flag, q = question_flag, n = just_print_flag;
enum update_status status = us_none;
/* Duplicate the chain so we can remove things from it. */
struct dep *goals = copy_dep_chain ((struct dep *)goaldeps);
goal_list = rebuilding_makefiles ? goaldeps : NULL;
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
: file_mtime (file))
/* Duplicate the chain so we can remove things from it. */
goals = copy_dep_chain (goals);
{
/* Clear the 'changed' flag of each goal in the chain.
We will use the flag below to notice when any commands
have actually been run for a target. When no commands
have been run, we give an "up to date" diagnostic. */
struct dep *g;
for (g = goals; g != 0; g = g->next)
g->changed = 0;
}
/* All files start with the considered bit 0, so the global value is 1. */
considered = 1;
/* Start a fresh batch of consideration. */
++considered;
/* Update all the goals until they are all finished. */
@ -125,6 +119,8 @@ update_goal_chain (struct dep *goals)
struct file *file;
int stop = 0, any_not_updated = 0;
goal_dep = g;
for (file = g->file->double_colon ? g->file->double_colon : g->file;
file != NULL;
file = file->prev)
@ -132,7 +128,7 @@ update_goal_chain (struct dep *goals)
unsigned int ocommands_started;
enum update_status fail;
file->dontcare = g->dontcare;
file->dontcare = ANY_SET (g->flags, RM_DONTCARE);
check_renamed (file);
if (rebuilding_makefiles)
@ -252,10 +248,10 @@ update_goal_chain (struct dep *goals)
}
}
/* If we reached the end of the dependency graph toggle the considered
flag for the next pass. */
/* If we reached the end of the dependency graph update CONSIDERED
for the next pass. */
if (g == 0)
considered = !considered;
++considered;
}
if (rebuilding_makefiles)
@ -268,6 +264,30 @@ update_goal_chain (struct dep *goals)
return status;
}
/* If we're rebuilding an included makefile that failed, and we care
about errors, show an error message the first time. */
void
show_goal_error (void)
{
struct goaldep *goal;
if ((goal_dep->flags & (RM_INCLUDED|RM_DONTCARE)) != RM_INCLUDED)
return;
for (goal = goal_list; goal; goal = goal->next)
if (goal_dep->file == goal->file)
{
if (goal->error)
{
OSS (error, &goal->floc, "%s: %s",
goal->file->name, strerror ((int)goal->error));
goal->error = 0;
}
return;
}
}
/* If FILE is not up to date, execute the commands for it.
Return 0 if successful, non-0 if unsuccessful;
but with some flag settings, just call 'exit' if unsuccessful.
@ -301,7 +321,7 @@ update_file (struct file *file, unsigned int depth)
&& !f->dontcare && f->no_diag))
{
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 : us_success;
}
}
@ -325,12 +345,9 @@ update_file (struct file *file, unsigned int depth)
if (f->command_state == cs_running
|| f->command_state == cs_deps_running)
{
/* Don't run the other :: rules for this
file until this rule is finished. */
status = us_success;
break;
}
/* Don't run other :: rules for this target until
this rule is finished. */
return us_success;
if (new > status)
status = new;
@ -349,7 +366,7 @@ update_file (struct file *file, unsigned int depth)
{
enum update_status new = update_file (d->file, depth + 1);
if (new > status)
new = status;
status = new;
}
}
@ -380,29 +397,28 @@ complain (struct file *file)
if (d == 0)
{
show_goal_error ();
/* Didn't find any dependencies to complain about. */
if (file->parent)
{
size_t l = strlen (file->name) + strlen (file->parent->name) + 4;
const char *m = _("%sNo rule to make target '%s', needed by '%s'%s");
if (!keep_going_flag)
fatal (NILF, l,
_("%sNo rule to make target '%s', needed by '%s'%s"),
"", file->name, file->parent->name, "");
fatal (NILF, l, m, "", file->name, file->parent->name, "");
error (NILF, l, _("%sNo rule to make target '%s', needed by '%s'%s"),
"*** ", file->name, file->parent->name, ".");
error (NILF, l, m, "*** ", file->name, file->parent->name, ".");
}
else
{
size_t l = strlen (file->name) + 4;
const char *m = _("%sNo rule to make target '%s'%s");
if (!keep_going_flag)
fatal (NILF, l,
_("%sNo rule to make target '%s'%s"), "", file->name, "");
fatal (NILF, l, m, "", file->name, "");
error (NILF, l,
_("%sNo rule to make target '%s'%s"), "*** ", file->name, ".");
error (NILF, l, m, "*** ", file->name, ".");
}
file->no_diag = 0;
@ -600,8 +616,8 @@ update_file_1 (struct file *file, unsigned int depth)
break;
if (!running)
/* The prereq is considered changed if the timestamp has changed while
it was built, OR it doesn't exist. */
/* The prereq is considered changed if the timestamp has changed
while it was built, OR it doesn't exist. */
d->changed = ((file_mtime (d->file) != mtime)
|| (mtime == NONEXISTENT_MTIME));
@ -635,7 +651,7 @@ update_file_1 (struct file *file, unsigned int depth)
/* We may have already considered this file, when we didn't know
we'd need to update it. Force update_file() to consider it and
not prune it. */
d->file->considered = !considered;
d->file->considered = 0;
new = update_file (d->file, depth);
if (new > dep_status)
@ -1072,7 +1088,7 @@ check_dep (struct file *file, unsigned int depth,
/* 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;
file->considered = 0;
set_command_state (file, cs_not_started);
}
@ -1158,8 +1174,9 @@ touch_file (struct file *file)
else
#endif
{
int fd = open (file->name, O_RDWR | O_CREAT, 0666);
int fd;
EINTRLOOP (fd, open (file->name, O_RDWR | O_CREAT, 0666));
if (fd < 0)
TOUCH_ERROR ("touch: open: ");
else
@ -1172,18 +1189,24 @@ touch_file (struct file *file)
if (e < 0)
TOUCH_ERROR ("touch: fstat: ");
/* Rewrite character 0 same as it already is. */
if (read (fd, &buf, 1) < 0)
EINTRLOOP (e, read (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: read: ");
if (lseek (fd, 0L, 0) < 0L)
TOUCH_ERROR ("touch: lseek: ");
if (write (fd, &buf, 1) < 0)
{
off_t o;
EINTRLOOP (o, lseek (fd, 0L, 0));
if (o < 0L)
TOUCH_ERROR ("touch: lseek: ");
}
EINTRLOOP (e, write (fd, &buf, 1));
if (e < 0)
TOUCH_ERROR ("touch: write: ");
/* If file length was 0, we just
changed it, so change it back. */
/* If file length was 0, we just changed it, so change it back. */
if (statbuf.st_size == 0)
{
(void) close (fd);
fd = open (file->name, O_RDWR | O_TRUNC, 0666);
EINTRLOOP (fd, open (file->name, O_RDWR | O_TRUNC, 0666));
if (fd < 0)
TOUCH_ERROR ("touch: open: ");
}
@ -1249,6 +1272,7 @@ FILE_TIMESTAMP
f_mtime (struct file *file, int search)
{
FILE_TIMESTAMP mtime;
int propagate_timestamp;
/* File's mtime is not known; must get it from the system. */
@ -1325,6 +1349,8 @@ f_mtime (struct file *file, int search)
|| (file->name[0] == '-' && file->name[1] == 'l'
&& (name = library_search (file->name, &mtime)) != 0))
{
int name_len;
if (mtime != UNKNOWN_MTIME)
/* vpath_search and library_search store UNKNOWN_MTIME
if they didn't need to do a stat call for their work. */
@ -1333,7 +1359,14 @@ f_mtime (struct file *file, int search)
/* 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
dependencies are updated. */
if (gpath_search (name, strlen (name) - strlen (file->name) - 1))
#ifndef VMS
name_len = strlen (name) - strlen (file->name) - 1;
#else
name_len = strlen (name) - strlen (file->name);
if (name[name_len - 1] == '/')
name_len--;
#endif
if (gpath_search (name, name_len))
{
rename_file (file, name);
check_renamed (file);
@ -1416,10 +1449,13 @@ f_mtime (struct file *file, int search)
}
}
/* Store the mtime into all the entries for this file. */
/* Store the mtime into all the entries for this file for which it is safe
to do so: avoid propagating timestamps to double-colon rules that haven't
been examined so they're run or not based on the pre-update timestamp. */
if (file->double_colon)
file = file->double_colon;
propagate_timestamp = file->updated;
do
{
/* If this file is not implicit but it is intermediate then it was
@ -1431,7 +1467,8 @@ f_mtime (struct file *file, int search)
&& !file->tried_implicit && file->intermediate)
file->intermediate = 0;
file->last_mtime = mtime;
if (file->updated == propagate_timestamp)
file->last_mtime = mtime;
file = file->prev;
}
while (file != 0);

View file

@ -3,7 +3,7 @@
Please do not send bug reports or questions about it to
the Make maintainers.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -222,7 +222,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
fflush (stderr);
}
pid = fork ();
pid = vfork ();
if (pid < 0)
{
/* The fork failed! */

View file

@ -1,5 +1,5 @@
/* Template for the remote job exportation interface to GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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

3
rule.c
View file

@ -1,5 +1,5 @@
/* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -380,6 +380,7 @@ install_pattern_rule (struct pspec *p, int terminal)
r->cmds = xmalloc (sizeof (struct commands));
r->cmds->fileinfo.filenm = 0;
r->cmds->fileinfo.lineno = 0;
r->cmds->fileinfo.offset = 0;
/* These will all be string literals, but we malloc space for them
anyway because somebody might want to free them later. */
r->cmds->commands = xstrdup (p->commands);

3
rule.h
View file

@ -1,5 +1,5 @@
/* Definitions for using pattern rules in GNU Make.
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Copyright (C) 1988-2016 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
@ -55,3 +55,4 @@ void install_pattern_rule (struct pspec *p, int terminal);
void create_pattern_rule (const char **targets, const char **target_percents,
unsigned int num, int terminal, struct dep *deps,
struct commands *commands, int override);
void print_rule_data_base (void);

View file

@ -1,5 +1,5 @@
/* Convert between signal names and numbers.
Copyright (C) 1990-2014 Free Software Foundation, Inc.
Copyright (C) 1990-2016 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

View file

@ -1,5 +1,5 @@
/* Constant string caching for GNU Make.
Copyright (C) 2006-2014 Free Software Foundation, Inc.
Copyright (C) 2006-2016 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
@ -42,8 +42,8 @@ struct strcache {
#define CACHE_BUFFER_ALLOC(_s) ((_s) - (2 * sizeof (size_t)))
#define CACHE_BUFFER_OFFSET (offsetof (struct strcache, buffer))
#define CACHE_BUFFER_SIZE(_s) (CACHE_BUFFER_ALLOC(_s) - CACHE_BUFFER_OFFSET)
#define BUFSIZE CACHE_BUFFER_SIZE (CACHE_BUFFER_BASE)
static sc_buflen_t bufsize = CACHE_BUFFER_SIZE (CACHE_BUFFER_BASE);
static struct strcache *strcache = NULL;
static struct strcache *fullcache = NULL;
@ -57,65 +57,76 @@ static unsigned long total_size = 0;
that this doesn't seem to be much of an issue in practice.
*/
static struct strcache *
new_cache ()
new_cache (struct strcache **head, sc_buflen_t buflen)
{
struct strcache *new;
new = xmalloc (bufsize + CACHE_BUFFER_OFFSET);
struct strcache *new = xmalloc (buflen + CACHE_BUFFER_OFFSET);
new->end = 0;
new->count = 0;
new->bytesfree = bufsize;
new->bytesfree = buflen;
new->next = strcache;
strcache = new;
new->next = *head;
*head = new;
++total_buffers;
return new;
}
static const char *
copy_string (struct strcache *sp, const char *str, unsigned int len)
{
/* Add the string to this cache. */
char *res = &sp->buffer[sp->end];
memmove (res, str, len);
res[len++] = '\0';
sp->end += len;
sp->bytesfree -= len;
++sp->count;
return res;
}
static const char *
add_string (const char *str, unsigned int len)
{
char *res;
const char *res;
struct strcache *sp;
struct strcache **spp = &strcache;
/* We need space for the nul char. */
unsigned int sz = len + 1;
/* If the string we want is too large to fit into a single buffer, then
no existing cache is large enough. Change the maximum size. */
if (sz > bufsize)
bufsize = CACHE_BUFFER_SIZE ((((sz + 1) / CACHE_BUFFER_BASE) + 1)
* CACHE_BUFFER_BASE);
else
/* Find the first cache with enough free space. */
for (; *spp != NULL; spp = &(*spp)->next)
if ((*spp)->bytesfree > sz)
break;
/* If nothing is big enough, make a new cache. */
sp = *spp;
if (sp == NULL)
{
sp = new_cache ();
spp = &sp;
}
/* Add the string to this cache. */
res = &sp->buffer[sp->end];
memmove (res, str, len);
res[len] = '\0';
sp->end += sz;
sp->bytesfree -= sz;
++sp->count;
/* If the amount free in this cache is less than the average string size,
consider it full and move it to the full list. */
++total_strings;
total_size += sz;
if (sp->bytesfree < (total_size / total_strings) + 1)
/* If the string we want is too large to fit into a single buffer, then
no existing cache is large enough. Add it directly to the fullcache. */
if (sz > BUFSIZE)
{
*spp = (*spp)->next;
sp = new_cache (&fullcache, sz);
return copy_string (sp, str, len);
}
/* Find the first cache with enough free space. */
for (; *spp != NULL; spp = &(*spp)->next)
if ((*spp)->bytesfree > sz)
break;
sp = *spp;
/* If nothing is big enough, make a new cache at the front. */
if (sp == NULL)
{
sp = new_cache (&strcache, BUFSIZE);
spp = &strcache;
}
/* Add the string to this cache. */
res = copy_string (sp, str, len);
/* If the amount free in this cache is less than the average string size,
consider it full and move it to the full list. */
if (total_strings > 20 && sp->bytesfree < (total_size / total_strings) + 1)
{
*spp = sp->next;
sp->next = fullcache;
fullcache = sp;
}
@ -123,6 +134,26 @@ add_string (const char *str, unsigned int len)
return res;
}
/* For strings too large for the strcache, we just save them in a list. */
struct hugestring {
struct hugestring *next; /* The next string. */
char buffer[1]; /* The string. */
};
static struct hugestring *hugestrings = NULL;
static const char *
add_hugestring (const char *str, unsigned int len)
{
struct hugestring *new = xmalloc (sizeof (struct hugestring) + len);
memcpy (new->buffer, str, len);
new->buffer[len] = '\0';
new->next = hugestrings;
hugestrings = new;
return new->buffer;
}
/* Hash table of strings in the cache. */
@ -148,11 +179,19 @@ static struct hash_table strings;
static unsigned long total_adds = 0;
static const char *
add_hash (const char *str, int len)
add_hash (const char *str, unsigned int len)
{
char *const *slot;
const char *key;
/* If it's too large for the string cache, just copy it.
We don't bother trying to match these. */
if (len > USHRT_MAX - 1)
return add_hugestring (str, len);
/* Look up the string in the hash. If it's there, return it. */
char *const *slot = (char *const *) hash_find_slot (&strings, str);
const char *key = *slot;
slot = (char *const *) hash_find_slot (&strings, str);
key = *slot;
/* Count the total number of add operations we performed. */
++total_adds;
@ -179,6 +218,13 @@ strcache_iscached (const char *str)
if (str >= sp->buffer && str < sp->buffer + sp->end)
return 1;
{
struct hugestring *hp;
for (hp = hugestrings; hp != 0; hp = hp->next)
if (str == hp->buffer)
return 1;
}
return 0;
}
@ -207,14 +253,6 @@ strcache_add_len (const char *str, unsigned int len)
return add_hash (str, len);
}
int
strcache_setbufsize (unsigned int size)
{
if (size > bufsize)
bufsize = size;
return bufsize;
}
void
strcache_init (void)
{
@ -229,7 +267,7 @@ strcache_print_stats (const char *prefix)
{
const struct strcache *sp;
unsigned long numbuffs = 0, fullbuffs = 0;
unsigned long totfree = 0, maxfree = 0, minfree = bufsize;
unsigned long totfree = 0, maxfree = 0, minfree = BUFSIZE;
if (! strcache)
{
@ -268,12 +306,13 @@ strcache_print_stats (const char *prefix)
(total_size / total_strings));
printf (_("%s current buf: size = %hu B / used = %hu B / count = %hu / avg = %hu B\n"),
prefix, bufsize, strcache->end, strcache->count,
prefix, (sc_buflen_t)BUFSIZE, strcache->end, strcache->count,
(strcache->end / strcache->count));
if (numbuffs)
{
unsigned long sz = total_size - bufsize;
/* Show information about non-current buffers. */
unsigned long sz = total_size - strcache->end;
unsigned long cnt = total_strings - strcache->count;
sc_buflen_t avgfree = totfree / numbuffs;

View file

@ -1,5 +1,5 @@
@echo off
rem Copyright (C) 1996-2014 Free Software Foundation, Inc.
rem Copyright (C) 1996-2016 Free Software Foundation, Inc.
rem This file is part of GNU Make.
rem
rem GNU Make is free software; you can redistribute it and/or modify it under
@ -20,4 +20,5 @@ set MAKE=%2
set MAKEFILE=%1
if x%2 == x set MAKE=nmake
%MAKE% /f %MAKEFILE%
if ERRORLEVEL 1 exit /B
cd ..\..

View file

@ -1413,7 +1413,7 @@
ChangeLog file for the test suite created.
Copyright (C) 1992-2014 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

View file

@ -162,7 +162,7 @@ Changes from 0.1 to 0.2 (5-4-92):
-------------------------------------------------------------------------------
Copyright (C) 1992-2014 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

View file

@ -7,7 +7,7 @@ This entire test suite, including all test files, are copyright and
distributed under the following terms:
-----------------------------------------------------------------------------
Copyright (C) 1992-2014 Free Software Foundation, Inc.
Copyright (C) 1992-2016 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

View file

@ -3,7 +3,7 @@ $! config_flags_pm.com - Build config-flags.pm on VMS.
$!
$! Just good enough to run the self tests for now.
$!
$! Copyright (C) 2014 Free Software Foundation, Inc.
$! Copyright (C) 2014-2016 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

View file

@ -3,7 +3,7 @@
# Simple script to make a "shadow" test directory, using symbolic links.
# Typically you'd put the shadow in /tmp or another local disk
#
# Copyright (C) 1992-2014 Free Software Foundation, Inc.
# Copyright (C) 1992-2016 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

View file

@ -4,7 +4,7 @@ $! This is a wrapper for the GNU make perl test programs on VMS.
$!
$! Parameter "-help" for description on how to use described below.
$!
$! Copyright (C) 2014 Free Software Foundation, Inc.
$! Copyright (C) 2014-2016 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
@ -238,18 +238,18 @@ $!
$ if no_gnv .or. no_perl then exit 44
$!
$!
$ make := $bin:make.exe
$ default = f$environment("DEFAULT")
$ default_dev = f$element(0, ":", default) + ":"
$ this = f$environment("PROCEDURE")
$ on error then goto all_error
$ set default 'f$parse(this,,,"DEVICE")''f$parse(this,,,"DIRECTORY")'
$ set default 'default_dev''f$parse(this,,,"DIRECTORY")'
$!
$! Need to make sure that the config-flags.pm exists.
$ if f$search("config-flags.pm") .eqs. ""
$ then
$ @config_flags_pm.com
$ endif
$ define/user bin 'default',gnv$gnu:[bin]
$ define/user bin 'default_dev'[-],gnv$gnu:[bin]
$ define/user decc$filename_unix_noversion enable
$ define/user decc$filename_unix_report enable
$ define/user decc$readdir_dropdotnotype enable

View file

@ -11,7 +11,7 @@
# [-make <make prog>]
# (and others)
# Copyright (C) 1992-2014 Free Software Foundation, Inc.
# Copyright (C) 1992-2016 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
@ -140,6 +140,7 @@ sub subst_make_string
sub run_make_test
{
local ($makestring, $options, $answer, $err_code, $timeout) = @_;
my @call = caller;
# If the user specified a makefile string, create a new makefile to contain
# it. If the first value is not defined, use the last one (if there is
@ -171,7 +172,7 @@ sub run_make_test
}
run_make_with_options($makefile, $options, &get_logfile(0),
$err_code, $timeout);
$err_code, $timeout, @call);
&compare_output($answer, &get_logfile(1));
$old_makefile = $makefile;
@ -180,7 +181,8 @@ sub run_make_test
# The old-fashioned way...
sub run_make_with_options {
local ($filename,$options,$logname,$expected_code,$timeout) = @_;
my ($filename,$options,$logname,$expected_code,$timeout,@call) = @_;
@call = caller unless @call;
local($code);
local($command) = $make_path;
@ -231,7 +233,11 @@ sub run_make_with_options {
$command .= " $options";
}
$command_string = "$command\n";
$command_string = "";
if (@call) {
$command_string = "#$call[1]:$call[2]\n";
}
$command_string .= "$command\n";
if ($valgrind) {
print VALGRIND "\n\nExecuting: $command\n";
@ -359,6 +365,12 @@ sub set_more_defaults
elsif ($osname =~ m%OS/2%) {
$port_type = 'OS/2';
}
# VMS has a GNV Unix mode or a DCL mode.
# The SHELL environment variable should not be defined in VMS-DCL mode.
elsif ($osname eq 'VMS' && !defined $ENV{"SHELL"}) {
$port_type = 'VMS-DCL';
}
# Everything else, right now, is UNIX. Note that we should integrate
# the VOS support into this as well and get rid of $vos; we'll do
# that next time.
@ -377,6 +389,7 @@ sub set_more_defaults
# Find the full pathname of Make. For DOS systems this is more
# complicated, so we ask make itself.
if ($osname eq 'VMS') {
$port_type = 'VMS-DCL' unless defined $ENV{"SHELL"};
# On VMS pre-setup make to be found with simply 'make'.
$make_path = 'make';
} else {
@ -458,6 +471,8 @@ sub set_more_defaults
# Set up for valgrind, if requested.
$make_command = $make_path;
if ($valgrind) {
my $args = $valgrind_args;
open(VALGRIND, "> valgrind.out")

View file

@ -9,89 +9,205 @@ This only works on systems that support it.";
exists $FEATURES{archives} or return -1;
# Create some .o files to work with
utouch(-60, qw(a1.o a2.o a3.o));
if ($osname eq 'VMS') {
use Cwd;
my $pwd = getcwd;
# VMS AR needs real object files at this time.
foreach $afile ('a1', 'a2', 'a3') {
# Use non-standard extension to prevent implicit rules from recreating
# objects when the test tampers with the timestamp.
1 while unlink "$afile.c1";
1 while unlink "$afile.o";
open (MYFILE, ">$afile.c1");
print MYFILE "int $afile(void) {return 1;}\n";
close MYFILE;
system("cc $afile.c1 /object=$afile.o");
}
} else {
utouch(-60, qw(a1.o a2.o a3.o));
}
my $ar = $CONFIG_FLAGS{AR};
# Fallback if configure did not find AR, such as VMS
# which does not run configure.
$ar = 'ar' if $ar eq '';
my $redir = '2>&1';
$redir = '' if $osname eq 'VMS';
my $arflags = 'rv';
my $arvar = "AR=$ar";
# Newer versions of binutils can be built with --enable-deterministic-archives
# which forces all timestamps (among other things) to always be 0, defeating
# GNU make's archive support. See if ar supports the U option to disable it.
unlink('libxx.a');
$_ = `$ar U$arflags libxx.a a1.o $redir`;
if ($? == 0) {
$arflags = 'Urv';
$arvar = "$arvar ARFLAGS=$arflags";
}
# Some versions of ar print different things on creation. Find out.
my $created = `$ar rv libxx.a a1.o 2>&1`;
unlink('libxx.a');
my $created = `$ar $arflags libxx.a a1.o $redir`;
# Some versions of ar print different things on add. Find out.
my $add = `$ar rv libxx.a a2.o 2>&1`;
my $add = `$ar $arflags libxx.a a2.o $redir`;
$add =~ s/a2\.o/#OBJECT#/g;
# Some versions of ar print different things on replacement. Find out.
my $repl = `$ar rv libxx.a a2.o 2>&1`;
my $repl = `$ar $arflags libxx.a a2.o $redir`;
$repl =~ s/a2\.o/#OBJECT#/g;
unlink('libxx.a');
# Very simple
run_make_test('all: libxx.a(a1.o)',
'', "$ar rv libxx.a a1.o\n$created");
my $answer = "$ar $arflags libxx.a a1.o\n$created";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test('all: libxx.a(a1.o)', $arvar, $answer);
# Multiple .o's. Add a new one to the existing library
($_ = $add) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a(a1.o a2.o)',
'', "$ar rv libxx.a a2.o\n$_");
$answer = "$ar $arflags libxx.a a2.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a2.o';
}
run_make_test('all: libxx.a(a1.o a2.o)', $arvar, $answer);
# Touch one of the .o's so it's rebuilt
utouch(-40, 'a1.o');
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a1.o');
# Later time stamp than last insertion.
sleep(2);
system('cc a1.c1 /object=a1.o');
# Next insertion will have a later timestamp.
sleep(2);
} else {
utouch(-40, 'a1.o');
}
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
run_make_test(undef, '', "$ar rv libxx.a a1.o\n$_");
$answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test(undef, $arvar, $answer);
# Use wildcards
run_make_test('all: libxx.a(*.o)',
'', "#MAKE#: Nothing to be done for 'all'.\n");
$answer = "#MAKE#: Nothing to be done for 'all'.\n";
run_make_test('all: libxx.a(*.o)', $arvar, $answer);
# Touch one of the .o's so it's rebuilt
utouch(-30, 'a1.o');
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a1.o');
# Make timestamp later than last insertion.
sleep(2);
system('cc a1.c1 /object=a1.o');
} else {
utouch(-30, 'a1.o');
}
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
run_make_test(undef, '', "$ar rv libxx.a a1.o\n$_");
$answer = "$ar $arflags libxx.a a1.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a1.o';
}
run_make_test(undef, $arvar, $answer);
# Use both wildcards and simple names
utouch(-50, 'a2.o');
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a2.o');
sleep(2);
system('cc a2.c1 /object=a2.o');
} else {
utouch(-50, 'a2.o');
}
($_ = $add) =~ s/#OBJECT#/a3.o/g;
$_ .= "$ar rv libxx.a a2.o\n";
$_ .= "$ar $arflags libxx.a a2.o\n";
($_ .= $repl) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a(a3.o *.o)', '',
"$ar rv libxx.a a3.o\n$_");
$answer = "$ar $arflags libxx.a a3.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a3.o';
}
run_make_test('all: libxx.a(a3.o *.o)', $arvar, $answer);
# Check whitespace handling
utouch(-40, 'a2.o');
if ($port_type eq 'VMS-DCL') {
# utouch is not changing what VMS library compare is testing for.
# So do a real change by regenerating the file.
1 while unlink('a2.o');
sleep(2);
system('cc a2.c1 /object=a2.o');
} else {
utouch(-40, 'a2.o');
}
($_ = $repl) =~ s/#OBJECT#/a2.o/g;
run_make_test('all: libxx.a( a3.o *.o )', '',
"$ar rv libxx.a a2.o\n$_");
$answer = "$ar $arflags libxx.a a2.o\n$_";
if ($port_type eq 'VMS-DCL') {
$answer = 'library /replace libxx.a a2.o';
}
run_make_test('all: libxx.a( a3.o *.o )', $arvar, $answer);
rmfiles(qw(a1.o a2.o a3.o libxx.a));
rmfiles(qw(a1.c1 a2.c1 a3.c1 a1.o a2.o a3.o libxx.a));
# Check non-archive targets
# See Savannah bug #37878
run_make_test(q!
$mk_string = q!
all: foo(bar).baz
foo(bar).baz: ; @echo '$@'
!,
'', "foo(bar).baz\n");
!;
if ($port_type eq 'VMS-DCL') {
$mk_string =~ s/echo/write sys\$\$output/;
$mk_string =~ s/\'/\"/g;
}
run_make_test($mk_string, $arvar, "foo(bar).baz\n");
# Check renaming of archive targets.
# See Savannah bug #38442
mkdir('artest', 0777);
touch('foo.vhd');
run_make_test(q!
$mk_string = q!
DIR = artest
vpath % $(DIR)
default: lib(foo)
(%): %.vhd ; @cd $(DIR) && touch $(*F) && $(AR) $(ARFLAGS) $@ $(*F) >/dev/null 2>&1 && rm $(*F)
.PHONY: default
!,
'', "");
!;
if ($port_type eq 'VMS-DCL') {
$mk_string =~ s#= artest#= sys\$\$disk:\[.artest\]#;
$mk_string =~ s#lib\(foo\)#lib.tlb\(foo\)#;
$mk_string =~ s#; \@cd#; pipe SET DEFAULT#;
$mk_string =~
s#touch \$\(\*F\)#touch \$\(\*F\) && library/create/text sys\$\$disk:\$\@#;
$mk_string =~
s#library#if f\$\$search(\"\$\@\") \.eqs\. \"\" then library#;
# VMS needs special handling for null extension
$mk_string =~ s#\@ \$\(\*F\)#\@ \$\(\*F\)\.#;
$mk_string =~ s#>/dev/null 2>&1 ##;
}
run_make_test($mk_string, $arvar, "");
run_make_test(undef, '', "#MAKE#: Nothing to be done for 'default'.\n");
run_make_test(undef, $arvar, "#MAKE#: Nothing to be done for 'default'.\n");
unlink('foo.vhd');
remove_directory_tree('artest');
if ($osname eq 'VMS') {
remove_directory_tree("$pwd/artest");
} else {
remove_directory_tree('artest');
}
# This tells the test driver that the perl test script executed properly.
1;

View file

@ -141,6 +141,22 @@ all: ; @:',
'',
'success');
# SV 47960 : ensure variable assignments in non-taken legs don't cause problems
run_make_test('
ifneq ($(FOO),yes)
target:
else
BAR = bar
target:
endif
@echo one
',
'', "one\n");
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -151,8 +151,7 @@ two');
unlink('result','one','two');
# TEST 10: check for proper backslash handling
# Savannah bug #33399
# TEST 10: SV 33399 : check for proper backslash handling
run_make_test('
a\ xb :: ; @echo one
@ -160,5 +159,62 @@ a\ xb :: ; @echo two
',
'', "one\ntwo\n");
# Test 11: SV 44742 : All double-colon rules should be run in parallel build.
run_make_test('result :: 01
@echo update
@touch $@
result :: 02
@echo update
@touch $@
result :: 03
@echo update
@touch $@
result :: 04
@echo update
@touch $@
result :: 05
@echo update
@touch $@
01 02 03 04 05:
@touch 01 02 03 04 05
',
'-j10 result', "update\nupdate\nupdate\nupdate\nupdate\n");
unlink('result', '01', '02', '03', '04', '05');
# Test 12: SV 44742 : Double-colon rules with parallelism
run_make_test('
root: all
echo root
all::
echo all_one
all:: 3
echo all_two
%:
sleep $*
',
'-rs -j2 1 2 root', "all_one\nall_two\nroot\n");
# SV 47995 : Parallel double-colon rules with FORCE
run_make_test('
all:: ; @echo one
all:: joe ; @echo four
joe: FORCE ; touch joe-is-forced
FORCE:
',
'-j5', "one\ntouch joe-is-forced\nfour\n");
unlink('joe-is-forced');
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -30,7 +30,7 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE "clean:\n"
."\t-$rm_command cleanit\n"
."\t$rm_command foo\n"
."clean2: \n"
."clean2: \n"
."\t$rm_command cleanit\n"
."\t$rm_command foo\n";
@ -50,8 +50,7 @@ $delete_error_code = $? >> 8;
$answer = "$rm_command cleanit
$cleanit_error
$makefile:2: recipe for target 'clean' failed
$make_name: [clean] Error $delete_error_code (ignored)
$make_name: [$makefile:2: clean] Error $delete_error_code (ignored)
$rm_command foo\n";
&run_make_with_options($makefile,"",&get_logfile);
@ -78,8 +77,7 @@ if (!$vos)
$answer = "$rm_command cleanit
$cleanit_error
$makefile:5: recipe for target 'clean2' failed
$make_name: [clean2] Error $delete_error_code (ignored)
$make_name: [$makefile:5: clean2] Error $delete_error_code (ignored)
$rm_command foo\n";
&run_make_with_options($makefile,"clean2 -i",&get_logfile);
@ -92,4 +90,18 @@ if (!$vos) {
&compare_output($answer,&get_logfile(1));
}
# Test that error line offset works
run_make_test(q!
all:
@echo hi
@echo there
@exit 1
!,
'', "hi\nthere\n#MAKE#: *** [#MAKEFILE#:5: all] Error 1", 512);
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -165,6 +165,70 @@ baz: end
#MAKE#: *** No rule to make target 'end', needed by 'baz'. Stop.\n",
512);
# Test include of make-able file doesn't show an error (Savannah #102)
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
inc2:; echo > $@
!,
'', "echo > inc2\necho > inc1\nDONE\n");
rmfiles('inc1', 'inc2');
# Test include of non-make-able file does show an error (Savannah #102)
run_make_test(q!
.PHONY: default
default:; @echo DONE
inc1:; echo > $@
include inc1
include inc2
!,
'', "#MAKEFILE#:7: inc2: No such file or directory\n#MAKE#: *** No rule to make target 'inc2'. Stop.\n", 512);
rmfiles('inc1');
# Include same file multiple times
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1:; echo > $@
include inc1
!,
'', "echo > inc1\nDEFAULT\n");
rmfiles('inc1');
# Included file has a prerequisite that fails to build
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1: foo; echo > $@
foo:; exit 1
!,
'', "exit 1\n#MAKEFILE#:3: inc1: No such file or directory\n#MAKE#: *** [#MAKEFILE#:5: foo] Error 1\n", 512);
rmfiles('inc1');
# Included file has a prerequisite we don't know how to build
run_make_test(q!
default:; @echo DEFAULT
include inc1
inc1: foo; echo > $@
!,
'', "#MAKEFILE#:3: inc1: No such file or directory\n#MAKE#: *** No rule to make target 'foo', needed by 'inc1'. Stop.\n", 512);
rmfiles('inc1');
# include a directory
if ($all_tests) {
# Test that include of a rebuild-able file doesn't show a warning
# Savannah bug #102

View file

@ -12,7 +12,49 @@ if (!$parallel_jobs) {
return -1;
}
# Don't put --jobserver-fds into a re-exec'd MAKEFLAGS.
# Shorthand
my $np = '--no-print-directory';
# Simple test of MAKEFLAGS settings
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\nall: /-j2 --jobserver-auth=<auth> $np/\n");
# Setting parallelism with the environment
# Command line should take precedence over the environment
$extraENV{MAKEFLAGS} = "-j2 $np";
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
'', "recurse: /-j2 --jobserver-auth=<auth> $np/\nall: /-j2 --jobserver-auth=<auth> $np/\n");
delete $extraENV{MAKEFLAGS};
# Test override of -jN
$extraENV{MAKEFLAGS} = "-j9 $np";
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -j3 -f #MAKEFILE# recurse2
recurse2: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\n#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nrecurse2: /-j3 --jobserver-auth=<auth> $np/\nall: /-j3 --jobserver-auth=<auth> $np/\n");
delete $extraENV{MAKEFLAGS};
# Test override of -jN with -j
run_make_test(q!
SHOW = $(patsubst --jobserver-auth=%,--jobserver-auth=<auth>,$(MAKEFLAGS))
recurse: ; @echo $@: "/$(SHOW)/"; $(MAKE) -j -f #MAKEFILE# recurse2
recurse2: ; @echo $@: "/$(SHOW)/"; $(MAKE) -f #MAKEFILE# all
all:;@echo $@: "/$(SHOW)/"
!,
"-j2 $np", "recurse: /-j2 --jobserver-auth=<auth> $np/\n#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nrecurse2: /-j $np/\nall: /-j $np/\n");
# Don't put --jobserver-auth into a re-exec'd MAKEFLAGS.
# We can't test this directly because there's no way a makefile can
# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it
# by looking for "disabling jobserver mode" warnings; we should only
@ -34,7 +76,7 @@ inc.mk:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo 'FOO = bar' > $@
!,
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
"$np -j2", "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
unlink('inc.mk');
@ -52,10 +94,14 @@ close(MAKEFILE);
run_make_test(q!
default: ; @ #MAKEPATH# -f Makefile2
!,
'-j2 --no-print-directory',
"-j2 $np",
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
#MAKE#[1]: Nothing to be done for 'foo'.");
rmfiles('Makefile2');
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -56,7 +56,7 @@ load testload.so
POST := $(.LOADED)
all: ; @echo pre=$(PRE) post=$(POST) $(TESTLOAD)
!,
'', "pre= post=testload.so implicit\n");
'--warn-undefined-variables', "pre= post=testload.so implicit\n");
# TEST 2
# Load using an explicit function

View file

@ -53,6 +53,8 @@ sub output_sync_set {
@syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start);
$tmout = 30;
output_sync_clean();
mkdir('foo', 0777);
mkdir('bar', 0777);
@ -140,7 +142,7 @@ bar: start
bar: end
baz: start
baz: end
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, $tmout);
# Test per-target synchronization.
# Note we have to sleep again here after starting the foo makefile before
@ -171,7 +173,7 @@ foo: end
#MAKE#[1]: Entering directory '#PWD#/bar'
baz: start
baz: end
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, 6);
#MAKE#[1]: Leaving directory '#PWD#/bar'\n", 0, $tmout);
# Rerun but this time suppress the directory tracking
unlink(@syncfiles);
@ -183,7 +185,7 @@ bar: end
foo: start
foo: end
baz: start
baz: end\n", 0, 6);
baz: end\n", 0, $tmout);
# Test that messages from make itself are enclosed with
# "Entering/Leaving directory" messages.
@ -204,11 +206,9 @@ bar: end
#MAKE#[1]: Entering directory '#PWD#/foo'
foo-fail: start
foo-fail: end
Makefile:20: recipe for target 'foo-fail' failed
#MAKE#[1]: *** [foo-fail] Error 1
#MAKE#[1]: *** [Makefile:23: foo-fail] Error 1
#MAKE#[1]: Leaving directory '#PWD#/foo'
#MAKEFILE#:4: recipe for target 'make-foo-fail' failed
#MAKE#: *** [make-foo-fail] Error 2\n",
#MAKE#: *** [#MAKEFILE#:4: make-foo-fail] Error 2\n",
512);
# Test the per-job synchronization.
@ -238,7 +238,7 @@ bar: end
#MAKE#[1]: Leaving directory '#PWD#/bar'
#MAKE#[1]: Entering directory '#PWD#/foo'
foo: end
#MAKE#[1]: Leaving directory '#PWD#/foo'\n", 0, 6);
#MAKE#[1]: Leaving directory '#PWD#/foo'\n", 0, $tmout);
# Remove temporary directories and contents.
@ -326,7 +326,7 @@ run_make_test(qq!
all: t1
t1: ; -\@\$(MAKE) -f $m1
!,
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKEFILE#:3: recipe for target 't1' failed\n#MAKE#: [t1] Error 2 (ignored)\n");
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#: [#MAKEFILE#:3: t1] Error 2 (ignored)\n");
rmfiles($m1);
@ -337,5 +337,13 @@ foo: $(OBJS) ; echo $(or $(filter %.o,$^),$(error fail))
!,
'-O', "#MAKEFILE#:2: *** fail. Stop.\n", 512);
# SV 47365: Make sure exec failure error messages are shown
# Is "127" not always the same everywhere? We may have to detect it?
run_make_test(q!
all:: ; @./foo bar baz
!,
'-O', "#MAKE#: ./foo: Command not found\n#MAKE#: *** [#MAKEFILE#:2: all] Error 127\n", 512);
# This tells the test driver that the perl test script executed properly.
1;

View file

@ -99,15 +99,12 @@ ok:
\@$sleep_command 4
\@echo Ok done",
'-rR -j5', "Fail
#MAKEFILE#:6: recipe for target 'fail.1' failed
#MAKE#: *** [fail.1] Error 1
#MAKE#: *** [#MAKEFILE#:8: fail.1] Error 1
#MAKE#: *** Waiting for unfinished jobs....
Fail
#MAKEFILE#:6: recipe for target 'fail.2' failed
#MAKE#: *** [fail.2] Error 1
#MAKE#: *** [#MAKEFILE#:8: fail.2] Error 1
Fail
#MAKEFILE#:6: recipe for target 'fail.3' failed
#MAKE#: *** [fail.3] Error 1
#MAKE#: *** [#MAKEFILE#:8: fail.3] Error 1
Ok done",
512);
@ -214,3 +211,7 @@ rmfiles('file1', 'file2', 'file3', 'file4');
# rmfiles(qw(dependfile output));
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -110,8 +110,7 @@ $(dir)/foo.bar:
',
"dir=$dir",
"#MAKEFILE#:6: recipe for target '$dir/foo.bar' failed
#MAKE#: *** [$dir/foo.bar] Error 1",
"#MAKE#: *** [#MAKEFILE#:6: $dir/foo.bar] Error 1",
512);
unlink("$dir/foo.bar");
@ -223,3 +222,7 @@ all: foo.x foo-mt.x
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -17,6 +17,12 @@ my @files_to_touch = ("a1${pathsep}lib1.a",
"b3${pathsep}lib3.so");
&touch(@files_to_touch);
my $answer = "a1${pathsep}lib1.a a1${pathsep}libc.a " .
"a2${pathsep}lib2.a lib3.a\n";
if ($port_type eq 'VMS-DCL') {
$answer =~ s/ /,/g;
}
run_make_test('
vpath %.h b3
vpath %.a a1
@ -25,7 +31,7 @@ vpath % a2 b2
vpath % b3
all: -l1 -lc -l2 -l3; @echo $^
',
'', "a1${pathsep}lib1.a a1${pathsep}libc.a a2${pathsep}lib2.a lib3.a\n");
'', $answer);
unlink(@files_to_touch);
for my $d (@dirs_to_make) {

View file

@ -86,8 +86,7 @@ cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1
$answer = "not creating notarget.c from notarget.d
cat notarget.c > notarget.b 2>/dev/null || exit 1
$makefile:16: recipe for target 'notarget.b' failed
$make_name: *** [notarget.b] Error 1
$make_name: *** [$makefile:16: notarget.b] Error 1
";
&compare_output($answer,&get_logfile(1));
@ -127,3 +126,7 @@ rm inter.c
unlink @touchedfiles unless $keep;
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -4,11 +4,7 @@ $description = "Test the call function.\n";
$details = "Try various uses of call and ensure they all give the correct
results.\n";
open(MAKEFILE, "> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<'EOMAKE';
run_make_test(q!
# Simple, just reverse two things
#
reverse = $2 $1
@ -48,35 +44,22 @@ all: ; @echo '$(call reverse,bar,foo)'; \
echo '$(call my-foreach,a,,,)'; \
echo '$(call my-if,a,b,c)'; \
echo '$(call two,bar,baz)'; \
echo '$(call tclose,foo)'
echo '$(call tclose,foo)';
!,
"", "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n");
EOMAKE
# These won't work until/unless PR/1527 is resolved.
# echo '$(call my-foreach,a,x y z,$(a)$(a))'; \
# echo '$(call my-if,,$(warning don't print this),ok)'
# These won't work because call expands all its arguments first, before
# passing them on, then marks them as resolved/simple, so they're not
# expanded again by the function.
#
# $answer = "xx yy zz\nok\n";
# END of Contents of MAKEFILE
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
$answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n";
&compare_output($answer, &get_logfile(1));
# echo '$(call my-foreach,a,x y z,$$(a)$$(a))'; \
# echo '$(call my-if,,$$(info don't print this),$$(info do print this))'
#
# $answer = "xx yy zz\ndo print this\n";
# TEST eclipsing of arguments when invoking sub-calls
$makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile2");
print MAKEFILE <<'EOF';
run_make_test(q!
all = $1 $2 $3 $4 $5 $6 $7 $8 $9
level1 = $(call all,$1,$2,$3,$4,$5)
@ -88,13 +71,8 @@ all:
@echo $(call level1,1,2,3,4,5,6,7,8)
@echo $(call level2,1,2,3,4,5,6,7,8)
@echo $(call level3,1,2,3,4,5,6,7,8)
EOF
close(MAKEFILE);
&run_make_with_options($makefile2, "", &get_logfile);
$answer = "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n";
&compare_output($answer,&get_logfile(1));
!,
"", "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n");
# Ensure that variables are defined in global scope even in a $(call ...)
@ -108,3 +86,7 @@ all: ; @echo "$${X123-not set}"
'', "\n");
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -54,7 +54,7 @@ $answer = "Some stuff\n$makefile:12: *** error is maybe. Stop.\n";
# Test #4
&run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512);
$answer = "Some stuff\n$makefile:16: *** error is definitely. Stop.\n";
$answer = "Some stuff\n$makefile:17: *** error is definitely. Stop.\n";
&compare_output($answer,&get_logfile(1));
# Test #5
@ -66,8 +66,6 @@ $answer = "$makefile:22: *** Error found!. Stop.\n";
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -115,4 +115,47 @@ x:;@cat file.out
unlink('file.out');
# Reading files
run_make_test(q!
$(file >file.out,A = foo)
X1 := $(file <file.out)
$(file >>file.out,B = bar)
$(eval $(file <file.out))
x:;@echo '$(X1)'; echo '$(A)'; echo '$(B)'
!,
'', "A = foo\nfoo\nbar\n");
unlink('file.out');
# Reading from non-existent file
run_make_test(q!
X1 := $(file <file.out)
x:;@echo '$(X1)';
!,
'', "\n");
# Extra arguments in read mode
run_make_test(q!
X1 := $(file <file.out,foo)
x:;@echo '$(X1)';
!,
'', "#MAKEFILE#:2: *** file: too many arguments. Stop.\n", 512);
# Missing filename
run_make_test('$(file >)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
run_make_test('$(file >>)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
run_make_test('$(file <)', '',
"#MAKEFILE#:1: *** file: missing filename. Stop.\n", 512);
# Bad call
run_make_test('$(file foo)', '',
"#MAKEFILE#:1: *** file: invalid file operation: foo. Stop.\n", 512);
1;

View file

@ -53,8 +53,26 @@ $(foreach x,FOREACH,$(eval $(value mktarget)))',
'',
'FOREACH');
# Allow variable names with trailing space
run_make_test(q!
$(foreach \
a \
, b c d \
, $(info $a))
all:;@:
!,
"", "b\nc\nd\n");
# TEST 2: Check some error conditions.
# Allow empty variable names. We still expand the body.
run_make_test('
x = $(foreach ,1 2 3,a)
y := $x
all: ; @echo $y',
'', "a a a\n");
# Check some error conditions.
run_make_test('
x = $(foreach )
@ -66,12 +84,12 @@ all: ; @echo $y',
512);
run_make_test('
x = $(foreach )
x = $(foreach x,y)
y := $x
all: ; @echo $y',
'',
"#MAKEFILE#:2: *** insufficient number of arguments (1) to function 'foreach'. Stop.",
"#MAKEFILE#:2: *** insufficient number of arguments (2) to function 'foreach'. Stop.",
512);
1;

View file

@ -4,11 +4,26 @@ $description = 'Test the $(shell ...) function.';
$details = '';
# Test standard shell
run_make_test('.PHONY: all
OUT := $(shell echo hi)
all: ; @echo $(OUT)
','','hi');
# Test shells inside rules.
run_make_test('.PHONY: all
all: ; @echo $(shell echo hi)
','','hi');
','','hi');
# Verify .SHELLSTATUS
run_make_test('.PHONY: all
PRE := $(.SHELLSTATUS)
$(shell exit 0)
OK := $(.SHELLSTATUS)
$(shell exit 1)
BAD := $(.SHELLSTATUS)
all: ; @echo PRE=$(PRE) OK=$(OK) BAD=$(BAD)
','','PRE= OK=0 BAD=1');
# Test unescaped comment characters in shells. Savannah bug #20513
@ -27,6 +42,19 @@ run_make_test('
export HI = $(shell echo hi)
.PHONY: all
all: ; @echo $$HI
','','hi');
','','hi');
# Test shell errors in recipes including offset
run_make_test('
all:
@echo hi
$(shell ./basdfdfsed there)
@echo there
',
'', "#MAKE#: ./basdfdfsed: Command not found\nhi\nthere\n");
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

View file

@ -42,6 +42,10 @@ A boy captured_by days end, has jazz_and_a midnight moon_light rise
run_make_test("FOO = a b\tc\rd\fe \f \f \f \f \ff
all: ; \@echo \$(words \$(sort \$(FOO)))\n",
'', "5\n");
'', "6\n");
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End:

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