Compare commits

...

17 Commits

Author SHA1 Message Date
Paul Smith
8a3436c65d Release GNU Make version 3.99.92. 2013-09-23 00:55:55 -04:00
Paul Smith
fd30db1290 [SV 31155] Parse order-only tokens in second expansion results. 2013-09-22 17:10:35 -04:00
Paul Smith
c3524b83b9 Use explicit cast between void* and pointer-to-function. 2013-09-22 17:10:35 -04:00
Paul Smith
0296e40fc7 Allow loaded objects to opt out of the "auto-rebuild" feature. 2013-09-22 17:10:35 -04:00
Paul Smith
f69922b335 Defer Guile initialization until the first $(guile...) call. 2013-09-22 17:10:35 -04:00
Paul Smith
65931ce7a9 Regression test portability to Solaris. 2013-09-22 17:10:34 -04:00
Paul Smith
1a991ada47 Add VMS port updates from Hartmut Becker. 2013-09-22 17:10:34 -04:00
Paul Smith
7e77685bc3 Portability enhancements for Mac OSX.
Don't dup stdout into stderr in the test suite.
Don't rely on $port_type eq "UNIX" to mean case-preserving.
Check against the real output of ar when creating archives.
2013-09-22 17:09:46 -04:00
Paul Smith
300d1296fb Create a target that tests alternative configurations. 2013-09-21 18:10:08 -04:00
Paul Smith
822f8dae41 Remove obsolete tests. 2013-09-21 17:41:11 -04:00
Paul Smith
d2d44f76c4 Invert the #define for output-sync: turn it off with NO_OUTPUT_SYNC 2013-09-21 17:37:59 -04:00
Paul Smith
6c3e88e60f Ensure that output generated while reading makefiles is synced. 2013-09-21 17:24:59 -04:00
Paul Smith
9cd01958da Ensure that stderr from shell functions in recipes is synced. 2013-09-21 17:08:42 -04:00
Paul Smith
4120f91846 Don't write "Entering" every time we re-exec for remake makefiles. 2013-09-21 14:24:44 -04:00
Paul Smith
30a5ee0d85 [SV 40043] Set the current directory before printing errors. 2013-09-18 19:29:28 -04:00
Eli Zaretskii
8a6205b43f Fix a typo in a comment. 2013-09-16 11:42:20 +03:00
Eli Zaretskii
bc120f27bd Avoid compiler warnings in output.c on MS-Windows.
output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
 compiler warnings for CLOSE_ON_EXEC.
2013-09-16 11:30:01 +03:00
44 changed files with 792 additions and 454 deletions

104
ChangeLog
View File

@@ -1,3 +1,107 @@
2013-09-22 Paul Smith <psmith@gnu.org>
* configure.ac: Update version to 3.99.92.
* NEWS: Ditto.
* implicit.c (pattern_search): After second expansion be sure to
handle order-only markers inside the expansion properly.
Fixes Savannah bug #31155.
* guile.c (guile_define_module): Technically a void* cannot
contain a pointer-to-function and some compilers warn about this.
Cast the function pointers.
* load.c (load_object): Ditto.
* read.c (eval): If load_file() returns -1, don't add this to the
"to be rebuilt" list.
* doc/make.texi (load Directive): Document it.
* guile.c (guile_gmake_setup): Don't initialize Guile so early.
(func_guile): Lazily initialize Guile the first time the $(guile ..)
function is invoked. Guile can steal file descriptors which
confuses our jobserver FD checking, so we don't want to initialize
it before we have to.
VMS port updates by Hartmut Becker <becker.ismaning@freenet.de>
* makefile.com: Add output to the filelist.
* output.c (va_copy): Add an implementation of this macro for VMS.
* commands.c: Ensure filedef.h is #included before dep.h.
* dir.c: Ditto.
* file.c: Ditto.
* guile.c: Ditto.
* main.c: Ditto.
* misc.c: Ditto.
* read.c: Ditto.
* rule.c: Ditto.
* variable.c: Ditto.
* readme.vms: Renamed to README.VMS and updates for this release.
* Makefile.am: Ditto.
* NEWS: Ditto.
* README.template: Ditto.
* Makefile.DOS.template: Ditto.
2013-09-21 Paul Smith <psmith@gnu.org>
* maintMakefile (check-alt-config): Create a target to test
alternative configurations. Each one will build make with a
different configuration then run the test suite.
Invert the output-sync #define to NO_OUTPUT_SYNC
* configure.ac: Don't set OUTPUT_SYNC.
* makeint.h: Ditto.
* main.c: Use NO_OUTPUT_SYNC instead of OUTPUT_SYNC.
* output.c: Ditto.
* output.h: Ditto.
* job.h: Ditto.
* job.c: Ditto.
* config.ami.template: Set NO_OUTPUT_SYNC.
* config.h-vms.template: Ditto.
* config.h.W32.template: Ditto.
* configh.dos.template: Ditto.
Output generated while reading makefiles should be synced.
* main.c (make_sync): Define a context for syncing while reading
makefiles and other top-level operations.
(main): If we request syncing, enable it while we are parsing
options, reading makefiles, etc. to capture that output. Just
before we start to run rules, dump the output if any.
(die): Dump any output we've been syncing before we die
* output.h (OUTPUT_SET): Disable output_context if not syncout.
Stderr generated from shell functions in recipes should be synced.
* job.h (FD_STDIN, FD_STDOUT, FD_STDERR): Create new macros to
avoid magic numbers.
(child_execute_job): Take a FD for stderr.
* job.c (child_execute_job): Handle STDERR FD's in addition to
stdin and stdout.
(start_job_command): Call child_execute_job() with the new STDERR
parameter. Instead of performing the dup() here, send it to
child_execute_job() where it's already being done.
* function.c (func_shell_base): Pass the OUTPUT_CONTEXT stderr to
child_execute_job() if it's set, otherwise FD_STDERR.
* main.c (main): Pass FD_STDERR to child_execute_job().
2013-09-19 Paul Smith <psmith@gnu.org>
* main.c (main): Set MAKE_RESTARTS to negative before re-exec if
we've already generated an "Entering" message. If we are started
and notice that MAKE_RESTARTS is negative, assume we already wrote
"Entering" and don't write it again.
2013-09-18 Paul Smith <psmith@gnu.org>
* main.c (main): Set starting_directory before we write any
errors. Fixes Savannah bug #40043.
2013-09-16 Eli Zaretskii <eliz@gnu.org>
* output.c [WINDOWS32]: Include windows.h and sub_proc.h, to avoid
compiler warnings for CLOSE_ON_EXEC.
2013-09-16 Paul Smith <psmith@gnu.org>
* configure.ac: Update version to 3.99.91.

View File

@@ -88,7 +88,7 @@ INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"$(prefix)$(libdir)\" -DINCLUDEDIR=\"$(pre
BUILT_SOURCES = README build.sh-in
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms README.VMS vmsdir.h vmsfunctions.c vmsify.c gmk-default.scm gmk-default.h
SUBDIRS = glob doc
mkinstalldirs = ${exec_prefix}/bin/gmkdir -p

View File

@@ -82,7 +82,7 @@ EXTRA_DIST = README build.sh.in $(man_MANS) \
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
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 \
README.VMS makefile.vms makefile.com config.h-vms \
vmsdir.h vmsfunctions.c vmsify.c \
gmk-default.scm gmk-default.h

8
NEWS
View File

@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
16 Sep 2013
23 Sep 2013
See the end of this file for copyrights and conditions.
@@ -9,7 +9,7 @@ manual, which is contained in this distribution as the file doc/make.texi.
See the README file and the GNU make manual for instructions for
reporting bugs.
Version 3.99.91
Version 3.99.92
A complete list of bugs fixed in this version is available here:
@@ -341,7 +341,7 @@ Version 3.81 (01 Apr 2006)
could be found on the system.
* On VMS there is now support for case-sensitive filesystems such as ODS5.
See the readme.vms file for information.
See the README.VMS file for information.
* Parallel builds (-jN) no longer require a working Bourne shell on
Windows platforms. They work even with the stock Windows shells, such
@@ -491,7 +491,7 @@ Version 3.79 (04 Apr 2000)
returned.
* Hartmut Becker provided many updates for the VMS port of GNU make.
See the readme.vms file for more details.
See the README.VMS file for more details.
Version 3.78 (22 Sep 1999)

View File

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

View File

@@ -142,7 +142,7 @@ Ports
- See README.customs for details on integrating GNU make with the
Customs distributed build environment from the Pmake distribution.
- See readme.vms for details about GNU Make on OpenVMS.
- See README.VMS for details about GNU Make on OpenVMS.
- See README.Amiga for details about GNU Make on AmigaDOS.

View File

@@ -17,8 +17,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <dlfcn.h>
#include "makeint.h"
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
#include "commands.h"

View File

@@ -321,6 +321,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Define for Case Insensitve behavior */
#define HAVE_CASE_INSENSITIVE_FS

View File

@@ -411,5 +411,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#define alloca(n) __ALLOCA(n)
#endif
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Build host information. */
#define MAKE_HOST "VMS"

View File

@@ -523,5 +523,3 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CYGWIN_SHELL
#undef BATCH_MODE_ONLY_SHELL
#endif
#define OUTPUT_SYNC

View File

@@ -100,8 +100,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
/* Define to the version of this package. */
#define PACKAGE_VERSION "%VERSION%"
/* Define to 1 if the C compiler supports function prototypes. */
#define PROTOTYPES 1
/* Output sync sypport */
#define NO_OUTPUT_SYNC
/* Version number of package */
#define VERSION "%VERSION%"

View File

@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
AC_INIT([GNU make],[3.99.91],[bug-make@gnu.org])
AC_INIT([GNU make],[3.99.92],[bug-make@gnu.org])
AC_PREREQ([2.62])
@@ -62,7 +62,7 @@ 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])
AM_PROG_CC_C_O
AC_C_CONST
@@ -90,12 +90,12 @@ AC_CACHE_CHECK([whether to use high resolution file timestamps],
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif]],
[[char a[0x7fffffff < (uintmax_t)-1 >> 30 ? 1 : -1];]])],
[[char a[0x7fffffff < (uintmax_t)-1 >> 30 ? 1 : -1];]])],
[make_cv_file_timestamp_hi_res=yes])
])])
AS_IF([test "$make_cv_file_timestamp_hi_res" = yes], [val=1], [val=0])
AC_DEFINE_UNQUOTED([FILE_TIMESTAMP_HI_RES], [$val],
[Use high resolution file timestamps if nonzero.])
[Use high resolution file timestamps if nonzero.])
AS_IF([test "$make_cv_file_timestamp_hi_res" = yes],
[ # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
@@ -103,7 +103,7 @@ AS_IF([test "$make_cv_file_timestamp_hi_res" = yes],
AC_SEARCH_LIBS([clock_gettime], [rt posix4])
AS_IF([test "$ac_cv_search_clock_gettime" != no],
[ AC_DEFINE([HAVE_CLOCK_GETTIME], [1],
[Define to 1 if you have the clock_gettime function.])
[Define to 1 if you have the clock_gettime function.])
])
])
@@ -117,24 +117,24 @@ AC_CACHE_CHECK([for standard gettimeofday], [ac_cv_func_gettimeofday],
[ac_cv_func_gettimeofday=no
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <sys/time.h>
int main ()
{
struct timeval t; t.tv_sec = -1; t.tv_usec = -1;
exit (gettimeofday (&t, 0) != 0
|| t.tv_sec < 0 || t.tv_usec < 0);
}]])],
[ac_cv_func_gettimeofday=yes],
[ac_cv_func_gettimeofday=no],
[ac_cv_func_gettimeofday="no (cross-compiling)"])])
{
struct timeval t; t.tv_sec = -1; t.tv_usec = -1;
exit (gettimeofday (&t, 0) != 0
|| t.tv_sec < 0 || t.tv_usec < 0);
}]])],
[ac_cv_func_gettimeofday=yes],
[ac_cv_func_gettimeofday=no],
[ac_cv_func_gettimeofday="no (cross-compiling)"])])
AS_IF([test "$ac_cv_func_gettimeofday" = yes],
[ AC_DEFINE([HAVE_GETTIMEOFDAY], [1],
[Define to 1 if you have a standard gettimeofday function])
[Define to 1 if you have a standard gettimeofday function])
])
AC_CHECK_FUNCS([strdup strndup mkstemp mktemp fdopen fileno \
dup dup2 getcwd realpath sigsetmask sigaction \
dup dup2 getcwd realpath sigsetmask sigaction \
getgroups seteuid setegid setlinebuf setreuid setregid \
getrlimit setrlimit setvbuf pipe strerror strsignal \
lstat readlink atexit])
lstat readlink atexit])
# We need to check declarations, not just existence, because on Tru64 this
# function is not declared without special flags, which themselves cause
@@ -181,11 +181,11 @@ AC_FUNC_GETLOADAVG
AS_IF([test "$ac_cv_header_nlist_h" = yes],
[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <nlist.h>]],
[[struct nlist nl;
[[struct nlist nl;
nl.n_name = "string";
return 0;]])],
[make_cv_nlist_struct=yes],
[make_cv_nlist_struct=no])
[make_cv_nlist_struct=yes],
[make_cv_nlist_struct=no])
AS_IF([test "$make_cv_nlist_struct" = yes],
[ AC_DEFINE([NLIST_STRUCT], [1],
[Define to 1 if struct nlist.n_name is a pointer rather than an array.])
@@ -244,7 +244,7 @@ AC_SUBST([REMOTE]) REMOTE=stub
use_customs=false
AC_ARG_WITH([customs],
[ AC_HELP_STRING([--with-customs=DIR],
[enable remote jobs via Customs--see README.customs])],
[enable remote jobs via Customs--see README.customs])],
[ AS_CASE([$withval], [n|no], [:],
[make_cppflags="$CPPFLAGS"
AS_CASE([$withval],
@@ -254,7 +254,7 @@ AC_ARG_WITH([customs],
CF_NETLIBS
AC_CHECK_HEADER([customs.h],
[use_customs=true
REMOTE=cstms
REMOTE=cstms
LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags"],
[with_customs=no
CPPFLAGS="$make_cppflags" make_badcust=yes])
@@ -268,7 +268,7 @@ AM_CONDITIONAL([USE_CUSTOMS], [test "$use_customs" = true])
AH_TEMPLATE([HAVE_CASE_INSENSITIVE_FS], [Use case insensitive file names])
AC_ARG_ENABLE([case-insensitive-file-system],
AC_HELP_STRING([--enable-case-insensitive-file-system],
[assume file systems are case insensitive]),
[assume file systems are case insensitive]),
[AS_IF([test "$enableval" = yes], [AC_DEFINE([HAVE_CASE_INSENSITIVE_FS])])])
# See if we can handle the job server feature, and if the user wants it.
@@ -368,7 +368,7 @@ AC_CACHE_CHECK([for location of SCCS get command], [make_cv_path_sccs_get], [
[make_cv_path_sccs_get=get])
])
AC_DEFINE_UNQUOTED([SCCS_GET], ["$make_cv_path_sccs_get"],
[Define to the name of the SCCS 'get' command.])
[Define to the name of the SCCS 'get' command.])
ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later.
AS_IF([(/usr/sccs/admin -n s.conftest || admin -n s.conftest) >/dev/null 2>&1 &&
@@ -428,7 +428,6 @@ AS_CASE([$host],
[AM_CONDITIONAL([WINDOWSENV], [true])
w32_target_env=yes
AC_DEFINE([WINDOWS32], [1], [Use platform specific coding])
AC_DEFINE([OUTPUT_SYNC], [1], [Support synchronized output])
AC_DEFINE([HAVE_DOS_PATHS], [1], [Use platform specific coding])
])

1
dir.c
View File

@@ -16,6 +16,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "hash.h"
#include "filedef.h"
#include "dep.h"
#ifdef HAVE_DIRENT_H

View File

@@ -10910,7 +10910,8 @@ The @code{load} directive and extension capability is considered a
``technology preview'' in this release of GNU make. We encourage you
to experiment with this feature and we appreciate any feedback on it.
However we cannot guarantee to maintain backward-compatibility in the
next release.
next release. Consider using GNU Guile instead for extending GNU make
(@pxref{Guile Function, ,The @code{guile} Function}).
@end quotation
@end cartouche
@@ -10978,7 +10979,9 @@ same directive.
The initializing function will be provided the file name and line
number of the invocation of the @code{load} operation. It should
return a value of type @code{int}, which must be @code{0} on failure
and non-@code{0} on success.
and non-@code{0} on success. If the return value is @code{-1}, then
GNU make will @emph{not} attempt to rebuild the object file
(@pxref{Remaking Loaded Objects, ,How Loaded Objects Are Remade}).
For example:

2
file.c
View File

@@ -18,8 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"

View File

@@ -1710,7 +1710,7 @@ func_shell_base (char *o, char **argv, int trim_newlines)
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 (0, pipedes[1], command_argv, envp);
pid = child_execute_job (FD_STDIN, pipedes[1], FD_STDOUT, command_argv, envp);
if (pid < 0)
perror_with_name (error_prefix, "spawn");
# else /* ! __EMX__ */
@@ -1719,12 +1719,14 @@ func_shell_base (char *o, char **argv, int trim_newlines)
perror_with_name (error_prefix, "fork");
else if (pid == 0)
{
#ifdef SET_STACK_SIZE
# ifdef SET_STACK_SIZE
/* Reset limits, if necessary. */
if (stack_limit.rlim_cur)
setrlimit (RLIMIT_STACK, &stack_limit);
#endif
child_execute_job (0, pipedes[1], command_argv, envp);
# endif
child_execute_job (FD_STDIN, pipedes[1],
output_context ? output_context->err : FD_STDERR,
command_argv, envp);
}
else
# endif

17
guile.c
View File

@@ -18,6 +18,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include "gnumake.h"
#include "debug.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
@@ -71,10 +72,10 @@ guile_define_module (void *data UNUSED)
#include "gmk-default.h"
/* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, guile_expand_wrapper);
scm_c_define_gsubr ("gmk-expand", 1, 0, 0, (scm_t_subr) guile_expand_wrapper);
/* Register a subr for GNU make's eval capability. */
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, guile_eval_wrapper);
scm_c_define_gsubr ("gmk-eval", 1, 0, 0, (scm_t_subr) guile_eval_wrapper);
/* Define the rest of the module. */
scm_c_eval_string (GUILE_module_defn);
@@ -106,6 +107,15 @@ internal_guile_eval (void *arg)
static char *
func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
{
static int init = 0;
if (! init)
{
/* Initialize the Guile interpreter. */
scm_with_guile (guile_init, NULL);
init = 1;
}
if (argv[0] && argv[0][0] != '\0')
return scm_with_guile (internal_guile_eval, argv[0]);
@@ -119,9 +129,6 @@ func_guile (const char *funcname UNUSED, int argc UNUSED, char **argv)
int
guile_gmake_setup (const gmk_floc *flocp UNUSED)
{
/* Initialize the Guile interpreter. */
scm_with_guile (guile_init, NULL);
/* Create a make function "guile". */
gmk_add_function ("guile", func_guile, 0, 1, 1);

View File

@@ -574,6 +574,7 @@ pattern_search (struct file *file, int archive,
{
int add_dir = 0;
unsigned int len;
struct dep **dptr;
nptr = get_next_word (nptr, &len);
if (nptr == 0)
@@ -616,6 +617,9 @@ pattern_search (struct file *file, int archive,
add_dir = 1;
}
/* Set up for the next word. */
nptr += len;
/* Initialize and set file variables if we haven't already
done so. */
if (!file_vars_initialized)
@@ -634,20 +638,33 @@ pattern_search (struct file *file, int archive,
/* Perform the 2nd expansion. */
p = variable_expand_for_file (depname, file);
dptr = &dl;
/* Parse the expanded string. */
dl = PARSE_FILE_SEQ (&p, struct dep, order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, PARSEFS_NONE);
for (d = dl; d != NULL; d = d->next)
/* Parse the results into a deps list. */
do
{
++deps_found;
if (order_only)
d->ignore_mtime = 1;
}
/* Parse the expanded string. */
struct dep *dp = PARSE_FILE_SEQ (&p, struct dep,
order_only ? MAP_NUL : MAP_PIPE,
add_dir ? dir : NULL, PARSEFS_NONE);
*dptr = dp;
/* Set up for the next word. */
nptr += len;
for (d = dp; d != NULL; d = d->next)
{
++deps_found;
if (order_only)
d->ignore_mtime = 1;
dptr = &d->next;
}
/* If we stopped due to an order-only token, note it. */
if (*p == '|')
{
order_only = 1;
++p;
}
}
while (*p != '\0');
}
/* If there are more than max_pattern_deps prerequisites (due to

157
job.c
View File

@@ -894,7 +894,7 @@ reap_children (int block, int err)
}
else
{
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* If we're sync'ing per line, write the previous line's
output before starting the next one. */
if (output_sync == OUTPUT_SYNC_LINE)
@@ -930,10 +930,10 @@ reap_children (int block, int err)
/* When we get here, all the commands for c->file are finished. */
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* Synchronize any remaining parallel output. */
output_dump (&c->output);
#endif /* OUTPUT_SYNC */
#endif
/* At this point c->file->update_status is success or failed. But
c->file->command_state is still cs_running if all the commands
@@ -1267,12 +1267,12 @@ start_job_command (struct child *child)
OUTPUT_SET (&child->output);
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
if (! child->output.syncout)
/* We don't want to sync this command: to avoid misordered
output ensure any already-synced content is written. */
output_dump (&child->output);
#endif /* OUTPUT_SYNC */
#endif
/* Print the command if appropriate. */
if (just_print_flag || trace_flag
@@ -1438,7 +1438,8 @@ start_job_command (struct child *child)
CLOSE_ON_EXEC (job_rfd);
/* Never use fork()/exec() here! Use spawn() instead in exec_command() */
child->pid = child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
child->pid = child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
FD_STDOUT, FD_STDERR,
argv, child->environment);
if (child->pid < 0)
{
@@ -1463,6 +1464,9 @@ start_job_command (struct child *child)
environ = parent_environ; /* Restore value child may have clobbered. */
if (child->pid == 0)
{
int outfd = FD_STDOUT;
int errfd = FD_STDERR;
/* We are the child side. */
unblock_sigs ();
@@ -1482,26 +1486,17 @@ start_job_command (struct child *child)
setrlimit (RLIMIT_STACK, &stack_limit);
#endif
#ifdef OUTPUT_SYNC
/* Divert child output if output_sync in use. Don't capture
recursive make output unless we are synchronizing "make" mode. */
/* Divert child output if output_sync in use. */
if (child->output.syncout)
{
int outfd = fileno (stdout);
int errfd = fileno (stderr);
if ((child->output.out >= 0
&& (close (outfd) == -1
|| dup2 (child->output.out, outfd) == -1))
|| (child->output.err >= 0
&& (close (errfd) == -1
|| dup2 (child->output.err, errfd) == -1)))
perror_with_name ("output-sync: ", "dup2()");
if (child->output.out >= 0)
outfd = child->output.out;
if (child->output.err >= 0)
errfd = child->output.err;
}
#endif /* OUTPUT_SYNC */
child_execute_job (child->good_stdin ? 0 : bad_stdin, 1,
argv, child->environment);
child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
outfd, errfd, argv, child->environment);
}
else if (child->pid < 0)
{
@@ -1597,7 +1592,7 @@ start_job_command (struct child *child)
/* make sure CreateProcess() has Path it needs */
sync_Path_environment ();
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* Divert child output if output_sync in use. Don't capture
recursive make output unless we are synchronizing "make" mode. */
if (child->output.syncout)
@@ -2185,59 +2180,82 @@ start_waiting_jobs (void)
/* EMX: Start a child process. This function returns the new pid. */
# if defined __EMX__
int
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp)
{
int pid;
/* stdin_fd == 0 means: nothing to do for stdin;
stdout_fd == 1 means: nothing to do for stdout */
int save_stdin = (stdin_fd != 0) ? dup (0) : 0;
int save_stdout = (stdout_fd != 1) ? dup (1): 1;
int save_stdin = -1;
int save_stdout = -1;
int save_stderr = -1;
/* < 0 only if dup() failed */
if (save_stdin < 0)
fatal (NILF, _("no more file handles: could not duplicate stdin\n"));
if (save_stdout < 0)
fatal (NILF, _("no more file handles: could not duplicate stdout\n"));
/* For each FD which needs to be redirected first make a dup of the standard
FD to save and mark it close on exec so our child won't see it. Then
dup2() the standard FD to the redirect FD, and also mark the redirect FD
as close on exec. */
if (stdin_fd != FD_STDIN)
{
save_stdin = dup (FD_STDIN);
if (save_stdin < 0)
fatal (NILF, _("no more file handles: could not duplicate stdin\n"));
CLOSE_ON_EXEC (save_stdin);
/* Close unnecessary file handles for the child. */
if (save_stdin != 0)
CLOSE_ON_EXEC (save_stdin);
if (save_stdout != 1)
CLOSE_ON_EXEC (save_stdout);
dup2 (stdin_fd, FD_STDIN);
CLOSE_ON_EXEC (stdin_fd);
}
/* Connect the pipes to the child process. */
if (stdin_fd != 0)
(void) dup2 (stdin_fd, 0);
if (stdout_fd != 1)
(void) dup2 (stdout_fd, 1);
if (stdout_fd != FD_STDOUT)
{
save_stdout = dup (FD_STDOUT);
if (save_stdout < 0)
fatal (NILF, _("no more file handles: could not duplicate stdout\n"));
CLOSE_ON_EXEC (save_stdout);
/* stdin_fd and stdout_fd must be closed on exit because we are
still in the parent process */
if (stdin_fd != 0)
CLOSE_ON_EXEC (stdin_fd);
if (stdout_fd != 1)
CLOSE_ON_EXEC (stdout_fd);
dup2 (stdout_fd, FD_STDOUT);
CLOSE_ON_EXEC (stdout_fd);
}
if (stderr_fd != FD_STDERR)
{
if (stderr_fd != stdout_fd)
{
save_stderr = dup (FD_STDERR);
if (save_stderr < 0)
fatal (NILF, _("no more file handles: could not duplicate stderr\n"));
CLOSE_ON_EXEC (save_stderr);
}
dup2 (stderr_fd, FD_STDERR);
CLOSE_ON_EXEC (stderr_fd);
}
/* Run the command. */
pid = exec_command (argv, envp);
/* Restore stdout/stdin of the parent and close temporary FDs. */
if (stdin_fd != 0)
/* Restore stdout/stdin/stderr of the parent and close temporary FDs. */
if (save_stdin >= 0)
{
if (dup2 (save_stdin, 0) != 0)
if (dup2 (save_stdin, FD_STDIN) != 0)
fatal (NILF, _("Could not restore stdin\n"));
else
close (save_stdin);
}
if (stdout_fd != 1)
if (save_stdout >= 0)
{
if (dup2 (save_stdout, 1) != 1)
if (dup2 (save_stdout, FD_STDOUT) != 0)
fatal (NILF, _("Could not restore stdout\n"));
else
close (save_stdout);
}
if (save_stderr >= 0)
{
if (dup2 (save_stderr, FD_STDERR) != 0)
fatal (NILF, _("Could not restore stderr\n"));
else
close (save_stderr);
}
return pid;
}
@@ -2245,19 +2263,28 @@ child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
/* UNIX:
Replace the current process with one executing the command in ARGV.
STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is
the environment of the new program. This function does not return. */
STDIN_FD/STDOUT_FD/STDERR_FD are used as the process's stdin/stdout/stderr;
ENVP is the environment of the new program. This function does not return. */
void
child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp)
child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp)
{
if (stdin_fd != 0)
(void) dup2 (stdin_fd, 0);
if (stdout_fd != 1)
(void) dup2 (stdout_fd, 1);
if (stdin_fd != 0)
(void) close (stdin_fd);
if (stdout_fd != 1)
(void) close (stdout_fd);
/* For any redirected FD, dup2() it to the standard FD then close it. */
if (stdin_fd != FD_STDIN)
{
dup2 (stdin_fd, FD_STDIN);
close (stdin_fd);
}
if (stdout_fd != FD_STDOUT)
dup2 (stdout_fd, FD_STDOUT);
if (stderr_fd != FD_STDERR)
dup2 (stderr_fd, FD_STDERR);
if (stdout_fd != FD_STDOUT)
close (stdout_fd);
if (stderr_fd != FD_STDERR && stderr_fd != stdout_fd)
close (stderr_fd);
/* Run the command. */
exec_command (argv, envp);

26
job.h
View File

@@ -37,7 +37,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
#endif
#ifdef OUTPUT_SYNC
#ifdef NO_OUTPUT_SYNC
# define RECORD_SYNC_MUTEX(m) \
error (NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#else
# ifdef WINDOWS32
/* For emulations in w32/compat/posixfcn.c. */
# define F_GETFD 1
@@ -69,7 +73,6 @@ int same_stream (FILE *f1, FILE *f2);
# define RECORD_SYNC_MUTEX(m) record_sync_mutex(m)
void record_sync_mutex (const char *str);
void prepare_mutex_handle_string (intptr_t hdl);
# else /* !WINDOWS32 */
typedef int sync_handle_t; /* file descriptor */
@@ -77,11 +80,7 @@ typedef int sync_handle_t; /* file descriptor */
# define RECORD_SYNC_MUTEX(m) (void)(m)
# endif
#else /* !OUTPUT_SYNC */
#define RECORD_SYNC_MUTEX(m) \
error (NILF, \
_("-O[TYPE] (--output-sync[=TYPE]) is not configured for this build."));
#endif /* OUTPUT_SYNC */
#endif /* !OUTPUT_SYNC */
/* Structure describing a running or dead child process. */
@@ -123,10 +122,17 @@ 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);
#elif defined(__EMX__)
int child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
#else
void child_execute_job (int stdin_fd, int stdout_fd, char **argv, char **envp);
# define FD_STDIN (fileno (stdin))
# define FD_STDOUT (fileno (stdout))
# define FD_STDERR (fileno (stderr))
# if defined(__EMX__)
int child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp)
# else
void child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
char **argv, char **envp) __attribute__ ((noreturn));
# endif
#endif
#ifdef _AMIGA
void exec_command (char **argv) __attribute__ ((noreturn));

4
load.c
View File

@@ -82,12 +82,12 @@ load_object (const gmk_floc *flocp, int noerror,
}
/* Assert that the GPL license symbol is defined. */
symp = dlsym (dlp, "plugin_is_GPL_compatible");
symp = (load_func_t) dlsym (dlp, "plugin_is_GPL_compatible");
if (! symp)
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
ldname);
symp = dlsym (dlp, symname);
symp = (load_func_t) dlsym (dlp, symname);
if (! symp)
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
symname, ldname, dlerror ());

94
main.c
View File

@@ -15,8 +15,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/>. */
#include "makeint.h"
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "variable.h"
#include "job.h"
#include "commands.h"
@@ -550,6 +550,11 @@ int clock_skew_detected;
#endif
unsigned short stopchar_map[UCHAR_MAX + 1] = {0};
/* If output-sync is enabled we'll collect all the output generated due to
options, while reading makefiles, etc. */
struct output make_sync;
/* Mask of signals that are being caught with fatal_error_signal. */
@@ -784,7 +789,7 @@ decode_output_sync_flags (void)
#ifdef WINDOWS32
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* This is called from start_job_command when it detects that
output_sync option is in effect. The handle to the synchronization
@@ -809,7 +814,7 @@ prepare_mutex_handle_string (sync_handle_t handle)
}
}
#endif /* OUTPUT_SYNC */
#endif /* NO_OUTPUT_SYNC */
/*
* HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture
@@ -1041,6 +1046,7 @@ main (int argc, char **argv, char **envp)
struct dep *read_files;
PATH_VAR (current_directory);
unsigned int restarts = 0;
unsigned int syncing = 0;
#ifdef WINDOWS32
char *unix_path = NULL;
char *windows32_path = NULL;
@@ -1052,6 +1058,8 @@ main (int argc, char **argv, char **envp)
no_default_sh_exe = 1;
#endif
output_init (&make_sync);
initialize_stopchar_map();
#ifdef SET_STACK_SIZE
@@ -1255,7 +1263,7 @@ main (int argc, char **argv, char **envp)
#ifdef MAKE_JOBSERVER
" jobserver"
#endif
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
" output-sync"
#endif
#ifdef MAKE_SYMLINKS
@@ -1332,11 +1340,17 @@ main (int argc, char **argv, char **envp)
shell_var.value = xstrdup (ep + 1);
}
/* If MAKE_RESTARTS is set, remember it but don't export it. */
if (streq (v->name, "MAKE_RESTARTS"))
/* If MAKE_RESTARTS is set, remember it but don't export it.
If it's negative, it means the "enter" message was printed. */
else if (streq (v->name, "MAKE_RESTARTS"))
{
v->export = v_noexport;
restarts = (unsigned int) atoi (ep + 1);
if (*(++ep) == '-')
{
OUTPUT_TRACED ();
++ep;
}
restarts = (unsigned int) atoi (ep);
}
}
}
@@ -1384,6 +1398,13 @@ main (int argc, char **argv, char **envp)
decode_env_switches (STRING_SIZE_TUPLE ("GNUMAKEFLAGS"));
decode_env_switches (STRING_SIZE_TUPLE ("MAKEFLAGS"));
/* In output sync mode we need to sync any output generated by reading the
makefiles, such as in $(info ...) or stderr from $(shell ...) etc. */
syncing = make_sync.syncout = (output_sync == OUTPUT_SYNC_LINE
|| output_sync == OUTPUT_SYNC_TARGET);
OUTPUT_SET (&make_sync);
#if 0
/* People write things like:
MFLAGS="CC=gcc -pipe" "CFLAGS=-g"
@@ -1393,6 +1414,16 @@ main (int argc, char **argv, char **envp)
decode_switches (argc, argv, 0);
/* Reset in case the switches changed our minds. */
syncing = (output_sync == OUTPUT_SYNC_LINE
|| output_sync == OUTPUT_SYNC_TARGET);
if (make_sync.syncout && ! syncing)
output_close (&make_sync);
make_sync.syncout = syncing;
OUTPUT_SET (&make_sync);
/* Figure out the level of recursion. */
{
struct variable *v = lookup_variable (STRING_SIZE_TUPLE (MAKELEVEL_NAME));
@@ -1477,6 +1508,9 @@ main (int argc, char **argv, char **envp)
#endif /* WINDOWS32 */
#endif
/* We may move, but until we do, here we are. */
starting_directory = current_directory;
#ifdef MAKE_JOBSERVER
/* If the jobserver-fds option is seen, make sure that -j is reasonable.
This can't be usefully set in the makefile, and we want to verify the
@@ -1526,7 +1560,11 @@ main (int argc, char **argv, char **envp)
error (NILF, _("warning: -jN forced in submake: disabling jobserver mode."));
}
#ifndef WINDOWS32
#define FD_OK(_f) ((fcntl ((_f), F_GETFD) != -1) || (errno != EBADF))
#ifdef HAVE_FCNTL
# define FD_OK(_f) ((fcntl ((_f), F_GETFD) != -1) || (errno != EBADF))
#else
# define FD_OK(_f) 1
#endif
/* 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, print a
@@ -1667,11 +1705,8 @@ main (int argc, char **argv, char **envp)
construct_include_path (include_directories == 0
? 0 : include_directories->list);
/* Figure out where we are now, after chdir'ing. */
if (directories == 0)
/* We didn't move, so we're still in the same place. */
starting_directory = current_directory;
else
/* If we chdir'ed, figure out where we are now. */
if (directories)
{
#ifdef WINDOWS32
if (getcwd_fs (current_directory, GET_PATH_MAX) == 0)
@@ -1901,6 +1936,16 @@ main (int argc, char **argv, char **envp)
decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS"));
#endif
/* Reset in case the switches changed our minds. */
syncing = (output_sync == OUTPUT_SYNC_LINE
|| output_sync == OUTPUT_SYNC_TARGET);
if (make_sync.syncout && ! syncing)
output_close (&make_sync);
make_sync.syncout = syncing;
OUTPUT_SET (&make_sync);
/* If we've disabled builtin rules, get rid of them. */
if (no_builtin_rules_flag && ! old_builtin_rules_flag)
{
@@ -2071,6 +2116,11 @@ main (int argc, char **argv, char **envp)
/* Initialize the remote job module. */
remote_setup ();
/* Dump any output we've collected. */
OUTPUT_UNSET ();
output_close (&make_sync);
if (read_files != 0)
{
/* Update any makefiles if necessary. */
@@ -2309,7 +2359,8 @@ main (int argc, char **argv, char **envp)
else if (strneq (*p, "MAKE_RESTARTS=", CSTRLEN ("MAKE_RESTARTS=")))
{
*p = alloca (40);
sprintf (*p, "MAKE_RESTARTS=%u", restarts);
sprintf (*p, "MAKE_RESTARTS=%s%u",
OUTPUT_IS_TRACED () ? "-" : "", restarts);
restarts = 0;
}
}
@@ -2321,7 +2372,7 @@ main (int argc, char **argv, char **envp)
sprintf (buffer, "%u", makelevel);
SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY);
sprintf (buffer, "%u", restarts);
sprintf (buffer, "%s%u", OUTPUT_IS_TRACED () ? "-" : "", restarts);
SetVar ("MAKE_RESTARTS", buffer, -1, GVF_GLOBAL_ONLY);
restarts = 0;
}
@@ -2331,7 +2382,8 @@ main (int argc, char **argv, char **envp)
if (restarts)
{
char *b = alloca (40);
sprintf (b, "MAKE_RESTARTS=%u", restarts);
sprintf (b, "MAKE_RESTARTS=%s%u",
OUTPUT_IS_TRACED () ? "-" : "", restarts);
putenv (b);
}
@@ -2355,7 +2407,8 @@ main (int argc, char **argv, char **envp)
termination. */
int pid;
int r;
pid = child_execute_job (0, 1, nargv, environ);
pid = child_execute_job (FD_STDIN, FD_STDOUT, FD_STDERR,
nargv, environ);
/* is this loop really necessary? */
do {
@@ -3349,6 +3402,13 @@ die (int status)
clean_jobserver (status);
if (output_context)
{
assert (output_context == &make_sync);
OUTPUT_UNSET ();
output_close (&make_sync);
}
output_close (NULL);
/* Try to move back to the original directory. This is essential on

View File

@@ -184,10 +184,41 @@ scm-update: get-config/texinfo.tex get-config/config.guess get-config/config.sub
update: po-update scm-update
# ---------------------------------- #
# Alternative configuration checks. #
# ---------------------------------- #
.PHONY: check-alt-config
check-alt-config: \
checkcfg.--disable-job-server \
checkcfg.--disable-load \
checkcfg.--without-guile \
checkcfg.CPPFLAGS^-DNO_OUTPUT_SYNC \
checkcfg.CPPFLAGS^-DNO_ARCHIVES
checkcfg.%: distdir
@ rm -rf $(distdir)/_build \
&& mkdir $(distdir)/_build \
&& cd $(distdir)/_build \
&& echo "Testing configure with $(subst ^,=,$*)" \
&& ../configure --srcdir=.. $(subst ^,=,$*) \
$(AM_DISTCHECK_CONFIGURE_FLAGS) $(DISTCHECK_CONFIGURE_FLAGS) \
CFLAGS='$(AM_CFLAGS)' \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) check
.PHONY: update
update: po-update scm-update
## --------------- ##
## Sanity checks. ##
## --------------- ##
# Before we build a distribution be sure we run our local checks
#distdir: local-check
# Checks that don't require Git. Run 'changelog-check' last as
# previous test may reveal problems requiring new ChangeLog entries.
local-check: po-check changelog-check

View File

@@ -68,7 +68,7 @@ $ gosub check_cc_qual
$ endif
$ filelist = "alloca ar arscan commands default dir expand file function " + -
"hash implicit job load main misc read remake remote-stub rule " + -
"signame variable version vmsfunctions vmsify vpath " + -
"output signame variable version vmsfunctions vmsify vpath " + -
"[.glob]glob [.glob]fnmatch getopt1 getopt strcache"
$ copy config.h-vms config.h
$ n=0

View File

@@ -556,10 +556,6 @@ int strncasecmp (const char *s1, const char *s2, int n);
# endif
#endif
#ifdef POSIX
# define OUTPUT_SYNC
#endif
#define OUTPUT_SYNC_NONE 0
#define OUTPUT_SYNC_LINE 1
#define OUTPUT_SYNC_TARGET 2

1
misc.c
View File

@@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
#include "makeint.h"
#include "filedef.h"
#include "dep.h"
#include "debug.h"

View File

@@ -30,20 +30,34 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# include <sys/file.h>
#endif
#ifdef WINDOWS32
# include <windows.h>
# include "sub_proc.h"
#endif /* WINDOWS32 */
struct output *output_context = NULL;
static unsigned int stdio_traced = 0;
unsigned int stdio_traced = 0;
#define OUTPUT_NONE (-1)
#define OUTPUT_ISSET(_out) ((_out)->out >= 0 || (_out)->err >= 0)
#ifdef HAVE_FCNTL
# define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#else
# define STREAM_OK(_s) 1
#endif
/* I really want to move to gnulib. However, this is a big undertaking
especially for non-UNIX platforms: how to get bootstrapping to work, etc.
I don't want to take the time to do it right now. Use a hack to get a
useful version of vsnprintf() for Windows. */
#ifdef __VMS
# define va_copy(_d, _s) ((_d) = (_s))
#endif
#ifdef _MSC_VER
#define va_copy(_d, _s) ((_d) = (_s))
#define snprintf msc_vsnprintf
# define va_copy(_d, _s) ((_d) = (_s))
# define snprintf msc_vsnprintf
static int
msc_vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
@@ -173,13 +187,11 @@ set_append_mode (int fd)
}
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
/* Semaphore for use in -j mode with output_sync. */
static sync_handle_t sync_handle = -1;
#define STREAM_OK(_s) ((fcntl (fileno (_s), F_GETFD) != -1) || (errno != EBADF))
#define FD_NOT_EMPTY(_f) ((_f) != OUTPUT_NONE && lseek ((_f), 0, SEEK_END) > 0)
/* Set up the sync handle. Disables output_sync on error. */
@@ -369,15 +381,14 @@ output_dump (struct output *out)
int traced = 0;
/* Try to acquire the semaphore. If it fails, dump the output
unsynchronized; still better than silently discarding it. */
unsynchronized; still better than silently discarding it.
We want to keep this lock for as little time as possible. */
void *sem = acquire_semaphore ();
/* Log the working directory for this dump. */
if (print_directory_flag && output_sync != OUTPUT_SYNC_RECURSE)
traced = log_working_directory (output_context, 1);
/* We've entered the "critical section" during which a lock is held. We
want to keep it as short as possible. */
if (outfd_not_empty)
pump_from_tmp (out->out, stdout);
if (errfd_not_empty && out->err != out->out)
@@ -405,7 +416,7 @@ output_dump (struct output *out)
}
}
}
#endif /* OUTPUT_SYNC */
#endif /* NO_OUTPUT_SYNC */
/* Provide support for temporary files. */
@@ -551,7 +562,7 @@ output_close (struct output *out)
return;
}
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
output_dump (out);
#endif
@@ -567,7 +578,7 @@ output_close (struct output *out)
void
output_start ()
{
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
if (output_context && output_context->syncout && ! OUTPUT_ISSET(output_context))
setup_tmpfile (output_context);
#endif

View File

@@ -22,10 +22,14 @@ struct output
};
extern struct output *output_context;
extern unsigned int stdio_traced;
#define OUTPUT_SET(_new) do{ if ((_new)->syncout) output_context = (_new); }while(0)
#define OUTPUT_SET(_new) do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
#define OUTPUT_UNSET() do{ output_context = NULL; }while(0)
#define OUTPUT_TRACED() do{ stdio_traced = 1; }while(0)
#define OUTPUT_IS_TRACED() (!!stdio_traced)
FILE *output_tmpfile (char **, const char *);
/* Initialize and close a child output structure: if NULL do this program's
@@ -40,7 +44,7 @@ void output_start (void);
/* Show a message on stdout or stderr. Will start the output if needed. */
void outputs (int is_err, const char *msg);
#ifdef OUTPUT_SYNC
#ifndef NO_OUTPUT_SYNC
int output_tmpfd (void);
/* Dump any child output content to stdout, and reset it. */
void output_dump (struct output *out);

16
read.c
View File

@@ -20,8 +20,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <glob.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"
@@ -947,19 +947,27 @@ eval (struct ebuffer *ebuf, int set_default)
PARSEFS_NOAR);
free (p);
/* Load each file and add it to the list "to be rebuilt". */
/* Load each file. */
while (files != 0)
{
struct nameseq *next = files->next;
const char *name = files->name;
struct dep *deps;
int r;
/* Load the file. 0 means failure. */
r = load_file (&ebuf->floc, &name, noerror);
if (! r && ! noerror)
fatal (&ebuf->floc, _("%s: failed to load"), name);
free_ns (files);
files = next;
if (! load_file (&ebuf->floc, &name, noerror) && ! noerror)
fatal (&ebuf->floc, _("%s: failed to load"), name);
/* Return of -1 means a special load: don't rebuild it. */
if (r == -1)
continue;
/* It succeeded, so add it to the list "to be rebuilt". */
deps = alloc_dep ();
deps->next = read_files;
read_files = deps;

2
rule.c
View File

@@ -18,8 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"

View File

@@ -1,3 +1,52 @@
2013-09-22 Paul Smith <psmith@gnu.org>
* scripts/features/se_implicit: Verify that order-only tokens
inside second expansion are parsed correctly.
Test for Savannah bug #31155.
* run_make_tests.pl (set_more_defaults): If we can't find
gnumake.h based on the make program we might be running from a
remote build directory. Parse the Makefile for the right path.
Fix some test issues on Solaris.
* scripts/features/archives: Determine what output ar gives when
adding and replacing objects and compare with that.
* scripts/features/escape: Solaris /bin/sh doesn't properly handle
backslashes inside single quotes, so don't rely on it.
* scripts/features/output-sync: false(1) gives different exit
codes on different systems; use "exit 1" instead.
* scripts/features/parallelism: Increase the timeout for slower systems.
2013-09-21 Paul Smith <psmith@gnu.org>
* scripts/features/archives: Some versions of ar (MacOSX) generate
different output when creating archives. Run it and verify the
real output.
* scripts/features/default_names: MacOSX is, like Windows,
case-preserving / case-insensitive. Redo the test to avoid
checking for "UNIX".
* test_driver.pl (attach_default_output): Don't dup stdout into
stderr. Reported by Denis Excoffier <bug-tar@Denis-Excoffier.org>
* scripts/features/se_explicit: Fix a test that behaves
differently with/without archive capability enabled.
* scripts/features/output-sync: Don't test output-sync if it's not
enabled. We also skip it if parallelism is not enabled, although
strictly speaking some of the output-sync tests are valid even
without parallelism.
* scripts/features/jobserver: Move some tests that require the
jobserver from features/parallelism to a separate suite. Only run
this if jobserver mode is enabled.
* scripts/features/output-sync: Test shell functions writing to
stderr in recipes: ensure it's captured via output-sync. Test
output generated while reading makefiles and make sure it's
captured via output-sync. Make sure that fatal errors dump the
output so it's not lost.
* scripts/options/dash-w: Add a test for -w flag.
2013-09-15 Paul Smith <psmith@gnu.org>
* scripts/misc/fopen-fail: Check for failure on infinite recursion.

View File

@@ -369,6 +369,15 @@ sub set_more_defaults
-f "${d}gnumake.h" and $srcdir = $d;
}
# Not with the make program, so see if we can get it out of the makefile
if (! $srcdir && open(MF, "< ../Makefile")) {
local $/ = undef;
$_ = <MF>;
close(MF);
/^abs_srcdir\s*=\s*(.*?)\s*$/m;
-f "$1/gnumake.h" and $srcdir = $1;
}
# Get Purify log info--if any.
if (exists $ENV{PURIFYOPTIONS}

View File

@@ -11,17 +11,32 @@ exists $FEATURES{archives} or return -1;
# Create some .o files to work with
utouch(-60, qw(a1.o a2.o a3.o));
# Some versions of ar print different things on creation. Find out.
my $created = `ar rv libxx.a a1.o 2>&1`;
# Some versions of ar print different things on add. Find out.
my $add = `ar rv libxx.a a2.o 2>&1`;
$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`;
$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\nar: creating libxx.a\na - a1.o\n");
'', "ar rv libxx.a a1.o\n$created");
# 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\na - a2.o\n");
'', "ar rv libxx.a a2.o\n$_");
# Touch one of the .o's so it's rebuilt
utouch(-40, 'a1.o');
run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
# Use wildcards
run_make_test('all: libxx.a(*.o)',
@@ -29,17 +44,22 @@ run_make_test('all: libxx.a(*.o)',
# Touch one of the .o's so it's rebuilt
utouch(-30, 'a1.o');
run_make_test(undef, '', "ar rv libxx.a a1.o\nr - a1.o\n");
($_ = $repl) =~ s/#OBJECT#/a1.o/g;
run_make_test(undef, '', "ar rv libxx.a a1.o\n$_");
# Use both wildcards and simple names
utouch(-50, 'a2.o');
($_ = $add) =~ s/#OBJECT#/a3.o/g;
$_ .= "ar rv 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\na - a3.o\nar rv libxx.a a2.o\nr - a2.o\n");
"ar rv libxx.a a3.o\n$_");
# Check whitespace handling
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\nr - a2.o\n");
"ar rv libxx.a a2.o\n$_");
rmfiles(qw(a1.o a2.o a3.o libxx.a));

View File

@@ -10,32 +10,33 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n";
close(MAKEFILE);
# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile.
# Just test what we can here (avoid Makefile versus makefile test).
if ($port_type eq 'UNIX') {
# Create another makefile called "makefile"
open(MAKEFILE,"> makefile");
print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
close(MAKEFILE);
}
# Create another makefile called "Makefile"
open(MAKEFILE,"> Makefile");
print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
# Create another makefile called "makefile"
open(MAKEFILE,"> makefile");
print MAKEFILE "SECOND: ; \@echo It chose makefile\n";
close(MAKEFILE);
# DOS/WIN32/MacOSX platforms are case-insensitive / case-preserving, so
# Makefile is the same file as makefile. Just test what we can here.
&run_make_with_options("","",&get_logfile);
&compare_output("It chose GNUmakefile\n",&get_logfile(1));
unlink $makefile;
if ($port_type eq 'UNIX') {
&run_make_with_options("","",&get_logfile);
&compare_output("It chose makefile\n",&get_logfile(1));
unlink "makefile";
my $case_sensitive = 0;
if (! -f 'Makefile') {
# Create another makefile called "Makefile"
$case_sensitive = 1;
open(MAKEFILE,"> Makefile");
print MAKEFILE "THIRD: ; \@echo It chose Makefile\n";
close(MAKEFILE);
}
&run_make_with_options("","",&get_logfile);
&compare_output("It chose Makefile\n",&get_logfile(1));
unlink "Makefile";
run_make_with_options("","",&get_logfile);
compare_output("It chose GNUmakefile\n",&get_logfile(1));
unlink($makefile);
run_make_with_options("","",&get_logfile);
compare_output("It chose makefile\n",&get_logfile(1));
unlink("makefile");
if ($case_sensitive) {
run_make_with_options("","",&get_logfile);
compare_output("It chose Makefile\n",&get_logfile(1));
unlink("Makefile");
}

View File

@@ -54,19 +54,21 @@ run_make_test(undef,
# Test escaped colons in prerequisites
# Quoting of backslashes in q!! is kind of messy.
# Solaris sh does not properly handle backslashes even in '' so just
# check the output make prints, not what the shell interprets.
run_make_test(q!
foo: foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; @echo '$@'
foo foo\\:bar foo\\\\\\:bar foo\\\\\\\\\\:bar: ; : '$@'
!,
'', "foo:bar\nfoo\\:bar\nfoo\\\\:bar\nfoo\n");
'', ": 'foo:bar'\n: 'foo\\:bar'\n: 'foo\\\\:bar'\n: 'foo'\n");
# Test backslash before non-special chars: should be kept as-is
run_make_test(q!
all: ..\foo
.DEFAULT: ; @echo '$@'
.DEFAULT: ; : '$@'
!,
'', '..\foo');
'', ": '..\\foo'\n");
# This tells the test driver that the perl test script executed properly.
1;

View File

@@ -0,0 +1,61 @@
# -*-perl-*-
$description = "Test jobserver.";
$details = "These tests are ones that specifically are different when the
jobserver feature is available. Most -j tests are the same whether or not
jobserver is available, and those appear in the 'parallelism' test suite.";
exists $FEATURES{'jobserver'} or return -1;
if (!$parallel_jobs) {
return -1;
}
# Don't put --jobserver-fds 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
# get one from the original invocation and none from the re-exec.
# See Savannah bug #18124
unlink('inc.mk');
run_make_test(q!
-include inc.mk
recur:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@rm -f inc.mk
@$(MAKE) -j2 -f #MAKEFILE# all
all:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo $@
inc.mk:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo 'FOO = bar' > $@
!,
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
unlink('inc.mk');
# Test recursion when make doesn't think it exists.
# See Savannah bug #39934
# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
open(MAKEFILE,"> Makefile2");
print MAKEFILE <<EOF;
vpath %.c $ENV{HOME}/
foo:
EOF
close(MAKEFILE);
run_make_test(q!
default: ; @ #MAKEPATH# -f Makefile2
!,
'-j2 --no-print-directory',
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
#MAKE#[1]: Nothing to be done for 'foo'.");
rmfiles('Makefile2');
1;

View File

@@ -4,9 +4,12 @@ $description = "Test --output-sync (-O) option.";
$details = "Test the synchronization of output from parallel jobs.";
if (!$parallel_jobs) {
return -1;
}
# If we don't have output sync support, never mind.
exists $FEATURES{'output-sync'} or return -1;
# Output sync can't be tested without parallelization
$parallel_jobs or return -1;
if ($vos) {
$sleep_command = "sleep -seconds";
@@ -88,7 +91,7 @@ foo-fail:
\t\@echo foo-fail: start
\t\@$wait_bar
\t\@echo foo-fail: end
\t\@false
\t\@exit 1
EOF
close(MAKEFILE);
@@ -261,5 +264,71 @@ all:
run_make_test(undef, '-j -Otarget', "foobar\ntrue\n");
# Ensure that shell functions inside recipes write stderr to the sync file
run_make_test(q!
all: ; @: $(shell echo foo 1>&2)
!,
'-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n");
# Ensure that output generated while parsing makefiles is synced
# when appropriate.
run_make_test(q!
$(shell echo foo 1>&2)
all: ; echo bar
!,
'-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n");
# Test recursion
$m1 = get_tmpfile();
$m2 = get_tmpfile();
open(M1, "> $m1");
print M1 <<'EOF';
$(shell echo d1 stderr 1>&2)
$(info d1 stdout)
all:; @:
EOF
close(M1);
open(M2, "> $m2");
print M2 <<'EOF';
$(shell echo d2 stderr 1>&2)
$(info d2 stdout)
all:; @:
# Force an ordering on the output
$(shell sleep 1)
EOF
close(M2);
run_make_test(qq!
all: t1 t2
t1: ; \@\$(MAKE) -f $m1
t2: ; \@\$(MAKE) -f $m2
!,
"-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n");
rmfiles($m1, $m2);
# Ensure that output generated while parsing makefiles is synced
# when appropriate.
$m1 = get_tmpfile();
open(M1, "> $m1");
print M1 <<'EOF';
$(shell echo d1 stderr 1>&2)
$(info d1 stdout)
$(error d1 failed)
all:; @:
EOF
close(M1);
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");
rmfiles($m1);
# This tells the test driver that the perl test script executed properly.
1;

View File

@@ -41,7 +41,7 @@ all: 1 2; \@echo success
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
"-j4",
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -60,7 +60,7 @@ endif
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@",
"-j4",
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n");
"ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n", 0, 7);
rmfiles(qw(1.inc 2.inc));
@@ -143,30 +143,6 @@ intermed: | phony ; touch $@
phony: ; : phony', '-rR -j', ': phony');
rmfiles('target');
# TEST #10: Don't put --jobserver-fds 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
# get one from the original invocation and none from the re-exec.
# See Savannah bug #18124
run_make_test(q!
-include inc.mk
recur:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@rm -f inc.mk
@$(MAKE) -j2 -f #MAKEFILE# all
all:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo $@
inc.mk:
# @echo 'MAKEFLAGS = $(MAKEFLAGS)'
@echo 'FOO = bar' > $@
!,
'--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n");
rmfiles('inc.mk');
# TEST #11: Make sure -jN from MAKEFLAGS is processed even when we re-exec
# See Savannah bug #33873
@@ -185,36 +161,6 @@ inc.mk: ; @touch $@
delete $extraENV{MAKEFLAGS};
rmfiles('inc.mk');
if ($all_tests) {
# Implicit files aren't properly recreated during parallel builds
# Savannah bug #26864
# The first run works fine
run_make_test(q!
%.bar: %.x foo.y ; cat $^ > $@
%.x: ; touch $@
foo.y: foo.y.in ; cp $< $@
foo.y.in: ; touch $@
!,
'-j2 main.bar',
"touch foo.y.in
touch main.x
cp foo.y.in foo.y
cat main.x foo.y > main.bar
rm main.x");
# Now we touch the .in file and make sure it still works
touch('foo.y.in');
run_make_test(undef, '-j2 main.bar', "cp foo.y.in foo.y
touch main.x
cat main.x foo.y > main.bar
rm main.x");
# Clean up
rmfiles(qw(foo.y foo.y.in main.bar));
}
# Ensure intermediate/secondary files are not pruned incorrectly.
# See Savannah bug #30653
@@ -232,48 +178,6 @@ file2: file1 ; @touch $@
rmfiles('file1', 'file2', 'file3', 'file4');
if ($all_tests) {
# Jobserver FD handling is messed up in some way.
# Savannah bug #28189
# It doesn't look like that bug anymore but this is the code it runs
run_make_test(q!
ifdef EXTRA
vpath %.dst /
xxx.dst: ; true
yyy.dst: ; true
endif
M := $(MAKE)
xx: ; $M --no-print-directory -j2 -f $(MAKEFILE_LIST) xxx.dst yyy.dst EXTRA=1
!,
'-j2',
'#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.
true
true
');
}
# Test recursion when make doesn't think it exists.
# See Savannah bug #39934
# Or Red Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=885474
open(MAKEFILE,"> Makefile2");
print MAKEFILE <<EOF;
vpath %.c $ENV{HOME}/
foo:
EOF
close(MAKEFILE);
run_make_test(q!
default: ; @ #MAKEPATH# -f Makefile2
!,
'-j2 --no-print-directory',
"#MAKE#[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
#MAKE#[1]: Nothing to be done for 'foo'.");
unlink('Makefile2');
# Make sure that all jobserver FDs are closed if we need to re-exec the
# master copy.
#

View File

@@ -6,6 +6,9 @@ $details = "";
# TEST #0: Test handing of '$' in prerequisites with and without second
# expansion.
# If we don't support archives then the prerequisite is different
my $prereq = exists $FEATURES{'archives'} ? '$' : '$(PRE)';
run_make_test(q!
ifdef SE
.SECONDEXPANSION:
@@ -18,7 +21,7 @@ PRE = three four
.DEFAULT: ; @echo '$@'
!,
'',
"\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
"$prereq\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz");
run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz");

View File

@@ -244,5 +244,17 @@ sim_%: \
unlink('a');
# Ensure that order-only tokens embedded in second expansions are parsed
run_make_test(q!
.SECONDEXPANSION:
PREREQS=p1|p2
P2=p2
all : foo bar
f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
p% : ; : $@
!,
"", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
# This tells the test driver that the perl test script executed properly.
1;

View File

@@ -0,0 +1,33 @@
# -*-perl-*-
$description = "Test the -w option to GNU make.";
# Simple test without -w
run_make_test(q!
all: ; @echo hi
!,
"", "hi\n");
# Simple test with -w
run_make_test(undef, "-w",
"#MAKE#: Entering directory '#PWD#'\nhi\n#MAKE#: Leaving directory '#PWD#'\n");
# Test makefile rebuild to ensure no enter/leave
run_make_test(q!
include foo
all: ;@:
foo: ; touch foo
!,
"", "#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n");
unlink('foo');
# Test makefile rebuild with -w
run_make_test(q!
include foo
all: ;@:
foo: ; touch foo
!,
"-w", "#MAKE#: Entering directory '#PWD#'\n#MAKEFILE#:2: foo: No such file or directory\ntouch foo\n#MAKE#: Leaving directory '#PWD#'\n");
unlink('foo');
1;

View File

@@ -220,7 +220,7 @@ sub toplevel
print "s" unless $total_tests_failed == 1;
print " in $categories_failed Categor";
print ($categories_failed == 1 ? "y" : "ies");
print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n";
print " Failed (See .$diffext* files in $workdir dir for details) :-(\n\n";
return 0;
}
else
@@ -752,6 +752,7 @@ sub attach_default_output
open($dup, '>&', STDOUT) or error("ado: $! duping STDOUT\n", 1);
push @OUTSTACK, $dup;
$dup = undef;
open($dup, '>&', STDERR) or error("ado: $! duping STDERR\n", 1);
push @ERRSTACK, $dup;

View File

@@ -18,8 +18,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "dep.h"
#include "filedef.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "variable.h"

View File

@@ -229,7 +229,7 @@ same_stream (FILE *f1, FILE *f2)
/* Each process on Windows can have at most 1 console,
so if both handles are for the console device, they
are the same. We also compare the console mode to
distinguish between tsdin and stdout/stderr. */
distinguish between stdin and stdout/stderr. */
if (GetConsoleMode (fh1, &conmode1)
&& GetConsoleMode (fh2, &conmode2)
&& conmode1 == conmode2)