mirror of
https://github.com/mirror/make.git
synced 2026-08-21 17:33:28 +08:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d66a65ad5a | ||
|
|
8093e2eee3 | ||
|
|
74dab224b3 | ||
|
|
8b8cc3a825 | ||
|
|
9b6fedef1c | ||
|
|
8ddb628927 | ||
|
|
e9dd614d73 | ||
|
|
f5dc17ac2d | ||
|
|
ac159491da | ||
|
|
4436655568 | ||
|
|
549fc56102 | ||
|
|
37e0010743 | ||
|
|
536c3e2b37 | ||
|
|
4c9b922560 | ||
|
|
2449ef3c88 | ||
|
|
fbf8c940e5 | ||
|
|
62194015fa | ||
|
|
c85f68c4e9 | ||
|
|
ffa28f3914 | ||
|
|
8f03e69af0 | ||
|
|
e819fc2022 | ||
|
|
f21cd822a3 | ||
|
|
2f336608d8 | ||
|
|
faedfdb0af | ||
|
|
9709d273b2 | ||
|
|
eb0bd1aaec | ||
|
|
d2bf740e77 | ||
|
|
a8890796a4 | ||
|
|
be6bb0fd68 |
@@ -171,7 +171,8 @@ errorpre = makeerror-$(PACKAGE_VERSION)-$(host_triplet)
|
||||
testfiles = $(testlog) $(testresult) $(errorfile)
|
||||
MOSTLYCLEANFILES = $(testfiles)
|
||||
|
||||
errordetails = config.status config.log src/config.h $(testlog) tests/work
|
||||
errordetails = config.status config.log src/config.h src/mkconfig.h \
|
||||
$(testlog) tests/work
|
||||
|
||||
# Create a 4-letter random sequence
|
||||
rand_value = c = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
16
NEWS
16
NEWS
@@ -1,6 +1,6 @@
|
||||
GNU Make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
14 January 2023
|
||||
26 February 2023
|
||||
|
||||
See the end of this file for copyrights and conditions.
|
||||
|
||||
@@ -10,7 +10,7 @@ See the README file and the GNU Make manual for instructions for
|
||||
reporting bugs.
|
||||
|
||||
|
||||
Version 4.4.0.90 (14 Jan 2023)
|
||||
Version 4.4.1 (26 Feb 2023)
|
||||
|
||||
This release is primarily a bug-fix release.
|
||||
A complete list of bugs fixed in this version is available here:
|
||||
@@ -32,18 +32,22 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=110&se
|
||||
builds with archive creation. See the "Dangers When Using Archives" section
|
||||
of the GNU Make manual, and https://savannah.gnu.org/bugs/index.php?14927
|
||||
|
||||
* New platform: GNU Make is supported on z/OS
|
||||
Thanks to Igor Todorovski <itodorov@ca.ibm.com> for the patches and testing
|
||||
assistance.
|
||||
|
||||
* Previously target-specific variables would inherit their "export" capability
|
||||
from parent target-specific variables even if they were marked private. Now
|
||||
private parent target-specific variables have no affect. For more details
|
||||
see https://savannah.gnu.org/bugs/index.php?61463
|
||||
|
||||
* Disable FIFO jobserver on GNU/Hurd and Cygwin
|
||||
Experimentation shows that the new FIFO-based jobserver doesn't work well on
|
||||
GNU/Hurd or Cygwin: revert these systems to use the pipe-based jobserver.
|
||||
|
||||
* Updates to allow building on OS/2
|
||||
Provided by KO Myung-Hun <komh78@gmail.com>
|
||||
|
||||
* New platform: GNU Make is supported on z/OS
|
||||
Thanks to Igor Todorovski <itodorov@ca.ibm.com> for the patches and testing
|
||||
assistance.
|
||||
|
||||
|
||||
Version 4.4 (31 Oct 2022)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
This version of GNU Make has been tested on:
|
||||
Microsoft Windows 2000/XP/2003/Vista/7/8/10
|
||||
Microsoft Windows 2000/XP/2003/Vista/7/8/10/11
|
||||
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, 4.8.1,
|
||||
|
||||
@@ -251,6 +251,7 @@ consistent (that's why we don't finalize the Git tag, etc. until the end).
|
||||
|
||||
* Update the configure.ac file with the new release number.
|
||||
* Update the EDITION value in the doc/make.texi file.
|
||||
* Update the doc/make.1 file with the release date.
|
||||
* Update the NEWS file with the release number and date.
|
||||
* Ensure the Savannah bug list URL in the NEWS file uses the correct
|
||||
"Fixed Release" ID number.
|
||||
|
||||
@@ -184,6 +184,8 @@ Ports
|
||||
|
||||
- See README.Amiga for details about GNU Make on AmigaDOS.
|
||||
|
||||
- See README.zOS for details about GNU Make on z/OS.
|
||||
|
||||
- See README.W32 for details about GNU Make on Windows NT, 95, or 98.
|
||||
|
||||
- See README.DOS for compilation instructions on MS-DOS and MS-Windows
|
||||
|
||||
@@ -28,7 +28,7 @@ if "%1" == "-h" goto Usage
|
||||
if "%1" == "--help" goto Usage
|
||||
|
||||
echo.
|
||||
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8/10
|
||||
echo Creating GNU Make for Windows 9X/NT/2K/XP/Vista/7/8/10/11
|
||||
echo.
|
||||
|
||||
set MAKE=gnumake
|
||||
|
||||
12
configure.ac
12
configure.ac
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
AC_INIT([GNU Make],[4.4.0.90],[bug-make@gnu.org])
|
||||
AC_INIT([GNU Make],[4.4.1],[bug-make@gnu.org])
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
@@ -37,6 +37,8 @@ AM_INIT_AUTOMAKE([1.16.1 foreign -Werror -Wall])
|
||||
# Checks for programs.
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_DEFINE_UNQUOTED(MAKE_CXX, ["$CXX"], [Default C++ compiler.])
|
||||
|
||||
# Configure gnulib
|
||||
gl_EARLY
|
||||
@@ -183,7 +185,7 @@ AS_IF([test "x$with_guile" != xno],
|
||||
CPPFLAGS="$CPPFLAGS $GUILE_CFLAGS"
|
||||
LIBS="$LIBS $GUILE_LIBS"
|
||||
AC_CHECK_HEADER([libguile.h],
|
||||
[AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])],
|
||||
[have_guile=yes],
|
||||
[have_guile=no],
|
||||
[/* Avoid configuration error warnings. */])
|
||||
AS_IF([test "$have_guile" = yes],
|
||||
@@ -207,6 +209,8 @@ guile_init (void *arg)
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test "$have_guile" = yes],
|
||||
[AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])])
|
||||
AM_CONDITIONAL([HAVE_GUILE], [test "$have_guile" = "yes"])
|
||||
|
||||
AC_CHECK_DECLS([sys_siglist, _sys_siglist, __sys_siglist], , ,
|
||||
@@ -349,14 +353,14 @@ AS_CASE([/$make_cv_load/$user_load/],
|
||||
# For example passing -rdynamic to the SunPRO linker gives a warning
|
||||
# but succeeds and creates a shared object, not an executable!
|
||||
AS_IF([test "$make_cv_load" = yes], [
|
||||
AC_MSG_CHECKING([If the linker accepts -Wl,--export-dynamic])
|
||||
AC_MSG_CHECKING([if the linker accepts -Wl,--export-dynamic])
|
||||
old_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_SUBST([AM_LDFLAGS], [-Wl,--export-dynamic])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_MSG_CHECKING([If the linker accepts -rdynamic])
|
||||
AC_MSG_CHECKING([if the linker accepts -rdynamic])
|
||||
LDFLAGS="$old_LDFLAGS -rdynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([int main(){}])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
|
||||
11
doc/make.1
11
doc/make.1
@@ -1,4 +1,4 @@
|
||||
.TH MAKE 1 "31 May 2022" "GNU" "User Commands"
|
||||
.TH MAKE 1 "26 May 2023" "GNU" "User Commands"
|
||||
.SH NAME
|
||||
make \- GNU Make utility to maintain groups of programs
|
||||
.SH SYNOPSIS
|
||||
@@ -76,9 +76,8 @@ listing, right near other important files such as
|
||||
The first name checked,
|
||||
.IR GNUmakefile ,
|
||||
is not recommended for most makefiles. You should use this name if you have a
|
||||
makefile that is specific to GNU
|
||||
.BR make ,
|
||||
and will not be understood by other versions of
|
||||
makefile that is specific to GNU Make, and will not be understood by other
|
||||
versions of
|
||||
.BR make .
|
||||
If
|
||||
.I makefile
|
||||
@@ -368,9 +367,7 @@ except that the modification time is changed only in the imagination of
|
||||
.B \-\-warn\-undefined\-variables
|
||||
Warn when an undefined variable is referenced.
|
||||
.SH "EXIT STATUS"
|
||||
GNU
|
||||
.B make
|
||||
exits with a status of zero if all makefiles were successfully parsed
|
||||
GNU Make exits with a status of zero if all makefiles were successfully parsed
|
||||
and no targets that were built failed. A status of one will be returned
|
||||
if the
|
||||
.B \-q
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@setfilename make.info
|
||||
|
||||
@include version.texi
|
||||
@set EDITION 0.76
|
||||
@set EDITION 0.77
|
||||
|
||||
@settitle GNU @code{make}
|
||||
@setchapternewpage odd
|
||||
@@ -2153,7 +2153,7 @@ The wildcard characters in @code{make} are @samp{*}, @samp{?} and
|
||||
specifies a list of all the files (in the working directory) whose names
|
||||
end in @samp{.c}.
|
||||
|
||||
If an expression matches multiple files than the results will be
|
||||
If an expression matches multiple files then the results will be
|
||||
sorted.@footnote{Some older versions of GNU @code{make} did not sort the
|
||||
results of wildcard expansion.} However multiple expressions will not be
|
||||
globally sorted. For example, @file{*.c *.h} will list all the files whose
|
||||
@@ -11529,7 +11529,7 @@ rules by adding these lines to your makefile:
|
||||
|
||||
@example
|
||||
(%) : % ;
|
||||
%.a : ; $(AR) $(ARFLAGS) $@ $?
|
||||
%.a : ; $(AR) $(ARFLAGS) $@@ $?
|
||||
@end example
|
||||
|
||||
The first line changes the rule that updates an individual object in the
|
||||
@@ -11548,7 +11548,7 @@ If you prefer to write an explicit rule you can use:
|
||||
|
||||
@example
|
||||
libfoo.a: libfoo.a(x.o y.o @dots{})
|
||||
$(AR) $(ARFLAGS) $@ $?
|
||||
$(AR) $(ARFLAGS) $@@ $?
|
||||
@end example
|
||||
|
||||
@node Archive Suffix Rules, , Archive Pitfalls, Archives
|
||||
|
||||
@@ -10,21 +10,59 @@ lib/glob.in.h
|
||||
|
||||
configure.ac:
|
||||
# Check the system to see if it provides GNU glob. If not, use our
|
||||
# local version.
|
||||
AC_CACHE_CHECK([if system libc has GNU glob], [make_cv_sys_gnu_glob],
|
||||
[ AC_EGREP_CPP([gnu glob],[
|
||||
#include <features.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2
|
||||
gnu glob
|
||||
# endif
|
||||
#endif],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no])])
|
||||
# local version. Also avoid versions of glibc which have symlink bug
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=866 (test from gnulib)
|
||||
AC_CACHE_CHECK([if system libc has working GNU glob], [make_cv_sys_gnu_glob],[
|
||||
if ln -s conf-doesntexist conf$$-globtest 2>/dev/null; then
|
||||
make_check_symlink=yes
|
||||
else
|
||||
make_check_symlink=no
|
||||
fi
|
||||
if test $cross_compiling = yes || test $make_check_symlink = no; then
|
||||
# When cross-compiling or without symlink support, check the version
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <features.h>
|
||||
#include <gnu-versions.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
]],
|
||||
[[
|
||||
#if _GNU_GLOB_INTERFACE_VERSION == 0
|
||||
GNU glob not available in libc
|
||||
#elif __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 27)
|
||||
GNU glob in libc has dangling symlink bug
|
||||
#endif
|
||||
]])],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no])
|
||||
else
|
||||
# Check for GNU glob, and that it handles dangling symlinks properly
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <features.h>
|
||||
#include <gnu-versions.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
]],
|
||||
[[
|
||||
#if _GNU_GLOB_INTERFACE_VERSION == 0
|
||||
return 1;
|
||||
#else
|
||||
glob_t found;
|
||||
if (glob ("conf*-globtest", 0, 0, &found) == GLOB_NOMATCH)
|
||||
return 1;
|
||||
globfree (&found);
|
||||
#endif
|
||||
]])],
|
||||
[make_cv_sys_gnu_glob=yes],
|
||||
[make_cv_sys_gnu_glob=no],
|
||||
[dnl We don't get here.
|
||||
:
|
||||
])
|
||||
fi
|
||||
test $make_check_symlink = no || rm -f conf$$-globtest
|
||||
])
|
||||
|
||||
# Tell automake about this, so it can build the right .c files.
|
||||
AM_CONDITIONAL([USE_SYSTEM_GLOB], [test "$make_cv_sys_gnu_glob" = yes])
|
||||
|
||||
@@ -274,6 +274,7 @@ CFGCHECK_MAKEFLAGS = # CFLAGS='$(AM_CFLAGS)'
|
||||
checkcfg.strict-c90: CFGCHECK_CONFIGFLAGS = CFLAGS='-std=c90 -pedantic'
|
||||
checkcfg.strict-c90: CFGCHECK_MAKEFLAGS =
|
||||
|
||||
checkcfg.job-pipe: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DJOBSERVER_USE_FIFO=0
|
||||
checkcfg.no-jobserver:CFGCHECK_CONFIGFLAGS = --disable-job-server
|
||||
checkcfg.no-load: CFGCHECK_CONFIGFLAGS = --disable-load
|
||||
checkcfg.no-guile: CFGCHECK_CONFIGFLAGS = --without-guile
|
||||
@@ -289,6 +290,7 @@ checkcfg.no-archives: CFGCHECK_CONFIGFLAGS = CPPFLAGS=-DNO_ARCHIVES
|
||||
|
||||
CONFIG_CHECKS := \
|
||||
checkcfg.strict-c90 \
|
||||
checkcfg.job-pipe \
|
||||
checkcfg.no-jobserver \
|
||||
checkcfg.no-load \
|
||||
checkcfg.no-guile \
|
||||
|
||||
@@ -527,18 +527,24 @@ static const char *default_variables[] =
|
||||
"AS", "as",
|
||||
#ifdef GCC_IS_NATIVE
|
||||
"CC", "gcc",
|
||||
# ifdef __MSDOS__
|
||||
"CXX", "gpp", /* g++ is an invalid name on MSDOS */
|
||||
# else
|
||||
"CXX", "gcc",
|
||||
# endif /* __MSDOS__ */
|
||||
"OBJC", "gcc",
|
||||
#else
|
||||
"CC", "cc",
|
||||
"CXX", "g++",
|
||||
"OBJC", "cc",
|
||||
#endif
|
||||
|
||||
#ifdef MAKE_CXX
|
||||
"CXX", MAKE_CXX,
|
||||
#else
|
||||
# ifdef GCC_IS_NATIVE
|
||||
# ifdef __MSDOS__
|
||||
"CXX", "gpp", /* g++ is an invalid name on MSDOS */
|
||||
# else
|
||||
"CXX", "gcc",
|
||||
# endif /* __MSDOS__ */
|
||||
# else
|
||||
"CXX", "g++",
|
||||
# endif
|
||||
#endif
|
||||
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
|
||||
and to the empty string if $@ does exist. */
|
||||
"CHECKOUT,v", "+$(if $(wildcard $@),,$(CO) $(COFLAGS) $< $@)",
|
||||
@@ -701,7 +707,7 @@ set_default_suffixes (void)
|
||||
installed after. */
|
||||
|
||||
void
|
||||
install_default_suffix_rules (void)
|
||||
install_default_suffix_rules ()
|
||||
{
|
||||
const char **s;
|
||||
|
||||
@@ -711,14 +717,16 @@ install_default_suffix_rules (void)
|
||||
for (s = default_suffix_rules; *s != 0; s += 2)
|
||||
{
|
||||
struct file *f = enter_file (strcache_add (s[0]));
|
||||
/* This function should run before any makefile is parsed. */
|
||||
assert (f->cmds == 0);
|
||||
f->cmds = xmalloc (sizeof (struct commands));
|
||||
f->cmds->fileinfo.filenm = 0;
|
||||
f->cmds->commands = xstrdup (s[1]);
|
||||
f->cmds->command_lines = 0;
|
||||
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
f->builtin = 1;
|
||||
/* Install the default rule only if there is no user defined rule. */
|
||||
if (!f->cmds)
|
||||
{
|
||||
f->cmds = xmalloc (sizeof (struct commands));
|
||||
f->cmds->fileinfo.filenm = NULL;
|
||||
f->cmds->commands = xstrdup (s[1]);
|
||||
f->cmds->command_lines = NULL;
|
||||
f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
f->builtin = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
PATH_VAR (stem_str); /* @@ Need to get rid of stem, stemlen, etc. */
|
||||
|
||||
++depth;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
if (archive || ar_name (filename))
|
||||
lastslash = 0;
|
||||
@@ -893,7 +895,7 @@ pattern_search (struct file *file, int archive,
|
||||
|
||||
if (pattern_search (int_file,
|
||||
0,
|
||||
depth + 1,
|
||||
depth,
|
||||
recursions + 1,
|
||||
allow_compat_rules))
|
||||
{
|
||||
@@ -1139,6 +1141,8 @@ pattern_search (struct file *file, int archive,
|
||||
free (tryrules);
|
||||
free (deplist);
|
||||
|
||||
--depth;
|
||||
|
||||
if (rule)
|
||||
{
|
||||
DBS (DB_IMPLICIT, (_("Found implicit rule '%s' for '%s'.\n"),
|
||||
|
||||
44
src/job.c
44
src/job.c
@@ -1193,7 +1193,7 @@ start_job_command (struct child *child)
|
||||
| child->file->cmds->lines_flags[child->command_line - 1]);
|
||||
|
||||
p = child->command_ptr;
|
||||
child->noerror = ((flags & COMMANDS_NOERROR) != 0);
|
||||
child->noerror = ANY_SET (flags, COMMANDS_NOERROR);
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
@@ -1209,7 +1209,7 @@ start_job_command (struct child *child)
|
||||
++p;
|
||||
}
|
||||
|
||||
child->recursive = ((flags & COMMANDS_RECURSE) != 0);
|
||||
child->recursive = ANY_SET (flags, COMMANDS_RECURSE);
|
||||
|
||||
/* Update the file's command flags with any new ones we found. We only
|
||||
keep the COMMANDS_RECURSE setting. Even this isn't 100% correct; we are
|
||||
@@ -1294,7 +1294,7 @@ start_job_command (struct child *child)
|
||||
command line, or 'succeeded' otherwise. The exit status of 1 tells the
|
||||
user that -q is saying 'something to do'; the exit status for a random
|
||||
error is 2. */
|
||||
if (argv != 0 && question_flag && !(flags & COMMANDS_RECURSE))
|
||||
if (argv != 0 && question_flag && NONE_SET (flags, COMMANDS_RECURSE))
|
||||
{
|
||||
FREE_ARGV (argv);
|
||||
#ifdef VMS
|
||||
@@ -1310,7 +1310,7 @@ start_job_command (struct child *child)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (touch_flag && !(flags & COMMANDS_RECURSE))
|
||||
if (touch_flag && NONE_SET (flags, COMMANDS_RECURSE))
|
||||
{
|
||||
/* Go on to the next command. It might be the recursive one.
|
||||
We construct ARGV only to find the end of the command line. */
|
||||
@@ -1344,7 +1344,7 @@ start_job_command (struct child *child)
|
||||
in SYNC_RECURSE mode or this command is not recursive. We'll also check
|
||||
output_sync separately below in case it changes due to error. */
|
||||
child->output.syncout = output_sync && (output_sync == OUTPUT_SYNC_RECURSE
|
||||
|| !(flags & COMMANDS_RECURSE));
|
||||
|| NONE_SET (flags, COMMANDS_RECURSE));
|
||||
|
||||
OUTPUT_SET (&child->output);
|
||||
|
||||
@@ -1355,7 +1355,7 @@ start_job_command (struct child *child)
|
||||
|
||||
/* Print the command if appropriate. */
|
||||
if (just_print_flag || ISDB (DB_PRINT)
|
||||
|| (!(flags & COMMANDS_SILENT) && !run_silent))
|
||||
|| (NONE_SET (flags, COMMANDS_SILENT) && !run_silent))
|
||||
OS (message, 0, "%s", p);
|
||||
|
||||
/* Tell update_goal_chain that a command has been started on behalf of
|
||||
@@ -1395,7 +1395,7 @@ start_job_command (struct child *child)
|
||||
|
||||
/* If -n was given, recurse to get the next line in the sequence. */
|
||||
|
||||
if (just_print_flag && !(flags & COMMANDS_RECURSE))
|
||||
if (just_print_flag && NONE_SET (flags, COMMANDS_RECURSE))
|
||||
{
|
||||
FREE_ARGV (argv);
|
||||
goto next_command;
|
||||
@@ -1420,9 +1420,16 @@ start_job_command (struct child *child)
|
||||
child->deleted = 0;
|
||||
|
||||
#ifndef _AMIGA
|
||||
/* Set up the environment for the child. */
|
||||
/* Set up the environment for the child.
|
||||
It's a slight inaccuracy to set the environment for recursive make even
|
||||
for command lines that aren't recursive, but I don't want to have to
|
||||
recompute the target environment for each command. Better would be to
|
||||
keep a separate entry for MAKEFLAGS in the environment so it could be
|
||||
replaced on its own. For now just set it for all lines.
|
||||
*/
|
||||
if (child->environment == 0)
|
||||
child->environment = target_environment (child->file, child->recursive);
|
||||
child->environment = target_environment (child->file,
|
||||
child->file->cmds->any_recurse);
|
||||
#endif
|
||||
|
||||
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
@@ -1464,12 +1471,12 @@ start_job_command (struct child *child)
|
||||
|
||||
#else
|
||||
|
||||
jobserver_pre_child (flags & COMMANDS_RECURSE);
|
||||
jobserver_pre_child (ANY_SET (flags, COMMANDS_RECURSE));
|
||||
|
||||
child->pid = child_execute_job ((struct childbase *)child,
|
||||
child->good_stdin, argv);
|
||||
|
||||
jobserver_post_child (flags & COMMANDS_RECURSE);
|
||||
jobserver_post_child (ANY_SET (flags, COMMANDS_RECURSE));
|
||||
|
||||
#endif /* !VMS */
|
||||
}
|
||||
@@ -2886,7 +2893,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
|
||||
return 0;
|
||||
|
||||
if (shellflags == 0)
|
||||
shellflags = posix_pedantic ? "-ec" : "-c";
|
||||
shellflags = posix_pedantic && NONE_SET (flags, COMMANDS_NOERROR) ? "-ec" : "-c";
|
||||
|
||||
/* See if it is safe to parse commands internally. */
|
||||
if (shell == 0)
|
||||
@@ -3538,7 +3545,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
|
||||
/* Some shells do not work well when invoked as 'sh -c xxx' to run a
|
||||
command line (e.g. Cygnus GNUWIN32 sh.exe on W32 systems). In these
|
||||
cases, run commands via a script file. */
|
||||
if (just_print_flag && !(flags & COMMANDS_RECURSE))
|
||||
if (just_print_flag && NONE_SET (flags, COMMANDS_RECURSE))
|
||||
{
|
||||
/* Need to allocate new_argv, although it's unused, because
|
||||
start_job_command will want to free it and its 0'th element. */
|
||||
@@ -3710,6 +3717,7 @@ construct_command_argv (char *line, char **restp, struct file *file,
|
||||
char **argv;
|
||||
|
||||
{
|
||||
struct variable *var;
|
||||
/* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
|
||||
int save = warn_undefined_variables_flag;
|
||||
warn_undefined_variables_flag = 0;
|
||||
@@ -3770,7 +3778,15 @@ construct_command_argv (char *line, char **restp, struct file *file,
|
||||
}
|
||||
#endif /* __EMX__ */
|
||||
|
||||
shellflags = allocated_variable_expand_for_file ("$(.SHELLFLAGS)", file);
|
||||
var = lookup_variable_for_file (STRING_SIZE_TUPLE (".SHELLFLAGS"), file);
|
||||
if (!var)
|
||||
shellflags = xstrdup ("");
|
||||
else if (posix_pedantic && var->origin == o_default)
|
||||
/* In POSIX mode we default to -ec, unless we're ignoring errors. */
|
||||
shellflags = xstrdup (ANY_SET (cmd_flags, COMMANDS_NOERROR) ? "-c" : "-ec");
|
||||
else
|
||||
shellflags = allocated_variable_expand_for_file (var->value, file);
|
||||
|
||||
ifs = allocated_variable_expand_for_file ("$(IFS)", file);
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
|
||||
15
src/main.c
15
src/main.c
@@ -234,6 +234,7 @@ static const int inf_jobs = 0;
|
||||
char *jobserver_auth = NULL;
|
||||
|
||||
/* Style for the jobserver. */
|
||||
|
||||
static char *jobserver_style = NULL;
|
||||
|
||||
/* Shuffle mode for goals and prerequisites. */
|
||||
@@ -1447,7 +1448,7 @@ main (int argc, char **argv, char **envp)
|
||||
#endif
|
||||
#ifdef MAKE_JOBSERVER
|
||||
" jobserver"
|
||||
# ifdef HAVE_MKFIFO
|
||||
# if JOBSERVER_USE_FIFO
|
||||
" jobserver-fifo"
|
||||
# endif
|
||||
#endif
|
||||
@@ -2027,13 +2028,6 @@ main (int argc, char **argv, char **envp)
|
||||
/* Define the initial list of suffixes for old-style rules. */
|
||||
set_default_suffixes ();
|
||||
|
||||
/* Define the file rules for the built-in suffix rules. These will later
|
||||
be converted into pattern rules. We used to do this in
|
||||
install_default_implicit_rules, but since that happens after reading
|
||||
makefiles, it results in the built-in pattern rules taking precedence
|
||||
over makefile-specified suffix rules, which is wrong. */
|
||||
install_default_suffix_rules ();
|
||||
|
||||
/* Define some internal and special variables. */
|
||||
define_automatic_variables ();
|
||||
|
||||
@@ -2284,6 +2278,11 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
snap_deps ();
|
||||
|
||||
/* Define the file rules for the built-in suffix rules. These will later
|
||||
be converted into pattern rules. */
|
||||
|
||||
install_default_suffix_rules ();
|
||||
|
||||
/* Convert old-style suffix rules to pattern rules. It is important to
|
||||
do this before installing the built-in pattern rules below, so that
|
||||
makefile-specified suffix rules take precedence over built-in pattern
|
||||
|
||||
@@ -83,6 +83,12 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
/* Define macros specifying which OS we are building for. */
|
||||
#if __gnu_hurd__
|
||||
# define MK_OS_HURD 1
|
||||
#endif
|
||||
#if __CYGWIN__
|
||||
# define MK_OS_CYGWIN 1
|
||||
#endif
|
||||
#if defined(__MVS__)
|
||||
# define MK_OS_ZOS 1
|
||||
#endif
|
||||
@@ -390,7 +396,9 @@ extern int unixy_shell;
|
||||
# endif
|
||||
|
||||
/* Include only the minimal stuff from windows.h. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
/* ALL_SET() evaluates the second argument twice. */
|
||||
@@ -742,6 +750,14 @@ extern char cmd_prefix;
|
||||
|
||||
extern unsigned int no_intermediates;
|
||||
|
||||
#if HAVE_MKFIFO
|
||||
/* It seems that mkfifo() is not working correctly, or at least not the way
|
||||
GNU make wants it to work, on GNU/Hurd and Cygwin so don't use it there. */
|
||||
# if !defined(JOBSERVER_USE_FIFO) && !MK_OS_HURD && !MK_OS_CYGWIN
|
||||
# define JOBSERVER_USE_FIFO 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define JOBSERVER_AUTH_OPT "jobserver-auth"
|
||||
|
||||
extern char *jobserver_auth;
|
||||
|
||||
39
src/misc.c
39
src/misc.c
@@ -28,6 +28,11 @@ this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
# define INCL_DOS
|
||||
# include <os2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#else
|
||||
@@ -781,6 +786,40 @@ get_tmpfile (char **name)
|
||||
}
|
||||
|
||||
|
||||
#if HAVE_TTYNAME && defined(__EMX__)
|
||||
/* OS/2 kLIBC has a declaration for ttyname(), so configure finds it.
|
||||
But, it is not implemented! Roll our own. */
|
||||
char *ttyname (int fd)
|
||||
{
|
||||
ULONG type;
|
||||
ULONG attr;
|
||||
ULONG rc;
|
||||
|
||||
rc = DosQueryHType (fd, &type, &attr);
|
||||
if (rc)
|
||||
{
|
||||
errno = EBADF;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type == HANDTYPE_DEVICE)
|
||||
{
|
||||
if (attr & 3) /* 1 = KBD$, 2 = SCREEN$ */
|
||||
return (char *) "/dev/con";
|
||||
|
||||
if (attr & 4) /* 4 = NUL */
|
||||
return (char *) "/dev/nul";
|
||||
|
||||
if (attr & 8) /* 8 = CLOCK$ */
|
||||
return (char *) "/dev/clock$";
|
||||
}
|
||||
|
||||
errno = ENOTTY;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
|
||||
/* If we don't have strcasecmp() (from POSIX), or anything that can substitute
|
||||
for it, define our own version. */
|
||||
|
||||
@@ -147,8 +147,8 @@ jobserver_setup (int slots, const char *style)
|
||||
{
|
||||
int r;
|
||||
|
||||
#if HAVE_MKFIFO
|
||||
if (style == NULL || strcmp (style, "fifo") == 0)
|
||||
#if JOBSERVER_USE_FIFO
|
||||
if (!style || strcmp (style, "fifo") == 0)
|
||||
{
|
||||
/* Unfortunately glibc warns about uses of mktemp even though we aren't
|
||||
using it in dangerous way here. So avoid this by generating our own
|
||||
|
||||
33
src/remake.c
33
src/remake.c
@@ -109,6 +109,7 @@ check_also_make (const struct file *file)
|
||||
enum update_status
|
||||
update_goal_chain (struct goaldep *goaldeps)
|
||||
{
|
||||
unsigned long last_cmd_count = 0;
|
||||
int t = touch_flag, q = question_flag, n = just_print_flag;
|
||||
enum update_status status = us_none;
|
||||
|
||||
@@ -134,9 +135,12 @@ update_goal_chain (struct goaldep *goaldeps)
|
||||
|
||||
start_waiting_jobs ();
|
||||
|
||||
/* Wait for a child to die. */
|
||||
/* Check for exited children. If no children have finished since the
|
||||
last time we looked, then block until one exits. If some have
|
||||
exited don't block, so we can possibly do more work. */
|
||||
|
||||
reap_children (1, 0);
|
||||
reap_children (last_cmd_count == command_count, 0);
|
||||
last_cmd_count = command_count;
|
||||
|
||||
lastgoal = 0;
|
||||
gu = goals;
|
||||
@@ -491,8 +495,6 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
fail. */
|
||||
file->no_diag = file->dontcare;
|
||||
|
||||
++depth;
|
||||
|
||||
/* Notice recursive update of the same file. */
|
||||
start_updating (file);
|
||||
|
||||
@@ -500,6 +502,9 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
remember this one to turn off updating. */
|
||||
ofile = file;
|
||||
|
||||
/* Increase the depth for reporting how we build the file. */
|
||||
++depth;
|
||||
|
||||
/* Looking at the file's modtime beforehand allows the possibility
|
||||
that its name may be changed by a VPATH search, and thus it may
|
||||
not need an implicit rule. If this were not done, the file
|
||||
@@ -734,16 +739,18 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
finish_updating (file);
|
||||
finish_updating (ofile);
|
||||
|
||||
DBF (DB_VERBOSE, _("Finished prerequisites of target file '%s'.\n"));
|
||||
/* We've decided what we need to do to build the file. */
|
||||
--depth;
|
||||
|
||||
if (running)
|
||||
{
|
||||
set_command_state (file, cs_deps_running);
|
||||
--depth;
|
||||
DBF (DB_VERBOSE, _("The prerequisites of '%s' are being made.\n"));
|
||||
return us_success;
|
||||
}
|
||||
|
||||
DBF (DB_VERBOSE, _("Finished prerequisites of target file '%s'.\n"));
|
||||
|
||||
/* If any dependency failed, give up now. */
|
||||
|
||||
if (dep_status)
|
||||
@@ -752,8 +759,6 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
file->update_status = dep_status == us_none ? us_failed : dep_status;
|
||||
notice_finished_file (file);
|
||||
|
||||
--depth;
|
||||
|
||||
DBF (DB_VERBOSE, _("Giving up on target file '%s'.\n"));
|
||||
|
||||
if (depth == 0 && keep_going_flag
|
||||
@@ -828,16 +833,13 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
|
||||
if (fmt)
|
||||
{
|
||||
print_spaces (depth);
|
||||
print_spaces (depth+1);
|
||||
printf (fmt, dep_name (d), file->name);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here depth returns to the value it had when we were called. */
|
||||
depth--;
|
||||
|
||||
if (file->double_colon && file->deps == 0)
|
||||
{
|
||||
must_make = 1;
|
||||
@@ -958,7 +960,7 @@ notice_finished_file (struct file *file)
|
||||
we don't want to do the touching. */
|
||||
unsigned int i;
|
||||
for (i = 0; i < file->cmds->ncommand_lines; ++i)
|
||||
if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
|
||||
if (NONE_SET (file->cmds->lines_flags[i], COMMANDS_RECURSE))
|
||||
goto have_nonrecursing;
|
||||
}
|
||||
else
|
||||
@@ -999,7 +1001,7 @@ notice_finished_file (struct file *file)
|
||||
if ((question_flag || just_print_flag || touch_flag) && file->cmds)
|
||||
{
|
||||
for (i = file->cmds->ncommand_lines; i > 0; --i)
|
||||
if (! (file->cmds->lines_flags[i-1] & COMMANDS_RECURSE))
|
||||
if (NONE_SET (file->cmds->lines_flags[i-1], COMMANDS_RECURSE))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1084,7 +1086,6 @@ check_dep (struct file *file, unsigned int depth,
|
||||
struct dep *d;
|
||||
enum update_status dep_status = us_success;
|
||||
|
||||
++depth;
|
||||
start_updating (file);
|
||||
|
||||
/* We might change file if we find a different one via vpath;
|
||||
@@ -1182,7 +1183,7 @@ check_dep (struct file *file, unsigned int depth,
|
||||
|
||||
d->file->parent = file;
|
||||
maybe_make = *must_make_ptr;
|
||||
new = check_dep (d->file, depth, this_mtime, &maybe_make);
|
||||
new = check_dep (d->file, depth+1, this_mtime, &maybe_make);
|
||||
if (new > dep_status)
|
||||
dep_status = new;
|
||||
|
||||
|
||||
@@ -538,6 +538,29 @@ lookup_variable (const char *name, size_t length)
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Lookup a variable whose name is a string starting at NAME
|
||||
and with LENGTH chars. NAME need not be null-terminated.
|
||||
Returns address of the 'struct variable' containing all info
|
||||
on the variable, or nil if no such variable is defined. */
|
||||
|
||||
struct variable *
|
||||
lookup_variable_for_file (const char *name, size_t length, struct file *file)
|
||||
{
|
||||
struct variable *var;
|
||||
struct variable_set_list *savev;
|
||||
|
||||
if (file == NULL)
|
||||
return lookup_variable (name, length);
|
||||
|
||||
savev = current_variable_set_list;
|
||||
current_variable_set_list = file->variables;
|
||||
|
||||
var = lookup_variable (name, length);
|
||||
|
||||
current_variable_set_list = savev;
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/* Lookup a variable whose name is a string starting at NAME
|
||||
and with LENGTH chars in set SET. NAME need not be null-terminated.
|
||||
|
||||
@@ -182,6 +182,8 @@ void define_new_function(const floc *flocp, const char *name,
|
||||
unsigned int min, unsigned int max, unsigned int flags,
|
||||
gmk_func_ptr func);
|
||||
struct variable *lookup_variable (const char *name, size_t length);
|
||||
struct variable *lookup_variable_for_file (const char *name, size_t length,
|
||||
struct file *file);
|
||||
struct variable *lookup_variable_in_set (const char *name, size_t length,
|
||||
const struct variable_set *set);
|
||||
|
||||
|
||||
@@ -671,6 +671,7 @@ sub set_more_defaults
|
||||
|
||||
create_file('features.mk', 'all:;$(info $(.FEATURES))');
|
||||
%FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`;
|
||||
print "$make_path FEATURES: @{[%FEATURES]}\n" if $verbose;
|
||||
unlink('features.mk');
|
||||
|
||||
# Find the default values for different built-in variables
|
||||
|
||||
@@ -35,7 +35,7 @@ $redir = '' if $osname eq 'VMS';
|
||||
|
||||
# This is the value from src/default.c
|
||||
my $arflags = $osname eq 'aix' ? '-Xany -rv' : '-rv';
|
||||
my $arvar = "AR=$ar";
|
||||
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
|
||||
@@ -44,7 +44,7 @@ unlink('libxx.a');
|
||||
$_ = `$ar ${arflags}U libxx.a a1.o $redir`;
|
||||
if ($? == 0) {
|
||||
$arflags = "${arflags}U";
|
||||
$arvar = "$arvar ARFLAGS=$arflags";
|
||||
$arvar = "$arvar ARFLAGS=\"$arflags\"";
|
||||
}
|
||||
|
||||
# Some versions of ar print different things on creation. Find out.
|
||||
@@ -254,23 +254,27 @@ create_file('a.c', 'int i;');
|
||||
create_file('b.c', 'int j;');
|
||||
utouch(-20, 'a.c', 'b.c');
|
||||
|
||||
my $cc = get_config('CC') || 'cc';
|
||||
my $vars = "CC=\"$cc\" $arvar";
|
||||
|
||||
run_make_test(q!
|
||||
mylib.a: mylib.a(a.o b.o)
|
||||
(%): % ;
|
||||
%.a: ; $(AR) $(ARFLAGS) $@ $?
|
||||
%.o : %.c ; @echo Compile $<; $(COMPILE.c) -o $@ $<
|
||||
!, $arvar, "Compile a.c\nCompile b.c\n$ar $arflags mylib.a a.o b.o\n${create2}rm b.o a.o");
|
||||
!,
|
||||
$vars, "Compile a.c\nCompile b.c\n$ar $arflags mylib.a a.o b.o\n${create2}rm b.o a.o");
|
||||
|
||||
run_make_test(undef, $arvar, "#MAKE#: 'mylib.a' is up to date.");
|
||||
run_make_test(undef, $vars, "#MAKE#: 'mylib.a' is up to date.");
|
||||
|
||||
# Now update one of the source files and it should be compiled and archived
|
||||
|
||||
sleep(2);
|
||||
touch('b.c');
|
||||
|
||||
run_make_test(undef, $arvar, "Compile b.c\n$ar $arflags mylib.a b.o\n${add2}rm b.o");
|
||||
run_make_test(undef, $vars, "Compile b.c\n$ar $arflags mylib.a b.o\n${add2}rm b.o");
|
||||
|
||||
run_make_test(undef, $arvar, "#MAKE#: 'mylib.a' is up to date.");
|
||||
run_make_test(undef, $vars, "#MAKE#: 'mylib.a' is up to date.");
|
||||
|
||||
unlink('a.c', 'b.c', 'a.o', 'b.o', 'mylib.a');
|
||||
}
|
||||
|
||||
@@ -476,14 +476,16 @@ all: ;
|
||||
# Test that included makefiles are not intermediate.
|
||||
# Here 'test.foo' is mentioned explicitly and cannot be considered
|
||||
# intermediate.
|
||||
&touch('test.foo', 'test.x', 'test');
|
||||
utouch(-10, 'test.foo');
|
||||
utouch(-5, 'test.x');
|
||||
touch('test');
|
||||
run_make_test(q!
|
||||
.PHONY: force
|
||||
include test.foo
|
||||
%.foo: force; touch -a $@
|
||||
%.foo: force; @echo force $@
|
||||
%.x: %.foo; touch $@
|
||||
test: test.x; touch $@
|
||||
!, '', "touch -a test.foo\n#MAKE#: 'test' is up to date.\n");
|
||||
!, '', "force test.foo\n#MAKE#: 'test' is up to date.\n");
|
||||
|
||||
unlink('test.foo', 'test.x', 'test');
|
||||
|
||||
|
||||
@@ -132,6 +132,42 @@ all a: ; @echo $@
|
||||
'--jobserver-style=foo -j8',
|
||||
"#MAKE#: *** unknown jobserver auth style 'foo'. Stop.", 512);
|
||||
|
||||
# Ensure the jobserver is not disabled even if only later commands are recursive
|
||||
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
all:
|
||||
> @echo $@ 1
|
||||
> @echo $@ 2
|
||||
> @$(MAKE) -f #MAKEFILE# recurse
|
||||
|
||||
recurse: ; @echo $@
|
||||
!,
|
||||
"$np -j8", "all 1\nall 2\nrecurse");
|
||||
|
||||
if ($port_type ne 'W32') {
|
||||
run_make_test(undef, "$np --jobserver-style=pipe -j8",
|
||||
"all 1\nall 2\nrecurse");
|
||||
}
|
||||
|
||||
# And with + instead of $(MAKE)
|
||||
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
all:
|
||||
> @echo $@ 1
|
||||
> @echo $@ 2
|
||||
> @+#MAKEPATH# -f #MAKEFILE# recurse
|
||||
|
||||
recurse: ; @echo $@
|
||||
!,
|
||||
"$np -j8", "all 1\nall 2\nrecurse");
|
||||
|
||||
if ($port_type ne 'W32') {
|
||||
run_make_test(undef, "$np --jobserver-style=pipe -j8",
|
||||
"all 1\nall 2\nrecurse");
|
||||
}
|
||||
|
||||
if (exists $FEATURES{'jobserver-fifo'}) {
|
||||
# sv 62908.
|
||||
# Test that when mkfifo fails, make switches to pipe and succeeds.
|
||||
|
||||
@@ -38,10 +38,10 @@ sub output_sync_clean {
|
||||
# reliable. If things are too fast, then sometimes a different job will steal
|
||||
# the output sync lock and the output is mis-ordered from what we expect.
|
||||
sub output_sync_wait {
|
||||
return subst_make_string("#HELPER# -q wait ../mksync.$_[0] sleep 1");
|
||||
return subst_make_string("#HELPER# \$Q wait ../mksync.$_[0] sleep 1");
|
||||
}
|
||||
sub output_sync_set {
|
||||
return subst_make_string("#HELPER# -q file ../mksync.$_[0]");
|
||||
return subst_make_string("#HELPER# \$Q file ../mksync.$_[0]");
|
||||
}
|
||||
|
||||
@syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start);
|
||||
@@ -66,27 +66,32 @@ open(MAKEFILE,"> foo/Makefile");
|
||||
print MAKEFILE <<EOF;
|
||||
all: foo
|
||||
|
||||
foo: foo-base ; \@$set_foo
|
||||
foo: foo-base ; $set_foo
|
||||
|
||||
foo-base:
|
||||
\t\@echo foo: start
|
||||
\t\@$wait_bar
|
||||
\t$wait_bar
|
||||
\t\@echo foo: end
|
||||
|
||||
foo-job: foo-job-base ; \@$set_foo
|
||||
foo-job: foo-job-base ; $set_foo
|
||||
|
||||
foo-job-base:
|
||||
\t\@$wait_bar_start
|
||||
\t$wait_bar_start
|
||||
\t\@echo foo: start
|
||||
\t\@$set_foo_start
|
||||
\t\@$wait_bar
|
||||
\t$set_foo_start
|
||||
\t$wait_bar
|
||||
\t\@echo foo: end
|
||||
|
||||
foo-fail:
|
||||
\t\@echo foo-fail: start
|
||||
\t\@$wait_bar
|
||||
\t$wait_bar
|
||||
\t\@echo foo-fail: end
|
||||
\t\@exit 1
|
||||
\texit 1
|
||||
|
||||
V :=
|
||||
\$V.SILENT:
|
||||
Q :=
|
||||
\$VQ := -q
|
||||
EOF
|
||||
close(MAKEFILE);
|
||||
|
||||
@@ -94,24 +99,29 @@ open(MAKEFILE,"> bar/Makefile");
|
||||
print MAKEFILE <<EOF;
|
||||
all: bar baz
|
||||
|
||||
bar: bar-base ; \@$set_bar
|
||||
bar: bar-base ; $set_bar
|
||||
bar-base:
|
||||
\t\@echo bar: start
|
||||
\t\@echo bar: end
|
||||
|
||||
bar-job: bar-job-base ; \@$set_bar
|
||||
bar-job: bar-job-base ; $set_bar
|
||||
|
||||
bar-job-base:
|
||||
\t\@echo bar: start
|
||||
\t\@$set_bar_start
|
||||
\t\@$wait_foo_start
|
||||
\t$set_bar_start
|
||||
\t$wait_foo_start
|
||||
\t\@echo bar: end
|
||||
|
||||
baz: baz-base
|
||||
baz-base:
|
||||
\t\@echo baz: start
|
||||
\t\@$wait_foo
|
||||
\t$wait_foo
|
||||
\t\@echo baz: end
|
||||
|
||||
V :=
|
||||
\$V.SILENT:
|
||||
Q :=
|
||||
\$VQ := -q
|
||||
EOF
|
||||
close(MAKEFILE);
|
||||
|
||||
@@ -353,15 +363,15 @@ s/\r?\n//g;
|
||||
if (/^[0-9]+$/) {
|
||||
use POSIX ();
|
||||
# SV 63157.
|
||||
# Test that make removes temporary files, even when a signal is received.
|
||||
# The general test_driver postprocessing will ensure the temporary file used
|
||||
# to synchronize output and the jobserver fifo are both removed.
|
||||
# sleep is needed to let make write its "... Terminated" message to the log
|
||||
# file.
|
||||
# Test that make removes temporary files, even when a signal is received. The
|
||||
# general test_driver postprocessing will ensure the temporary file used to
|
||||
# synchronize output and the jobserver fifo are both removed. sleep is needed
|
||||
# to let make write its "... Terminated" message to the log file. Must use
|
||||
# REGEX because some systems (MacOS) add extra text after Terminated.
|
||||
run_make_test(q!
|
||||
pid:=$(shell echo $$PPID)
|
||||
all:; @#HELPER# -q term $(pid) sleep 10
|
||||
!, '-O -j2', '#MAKE#: *** [#MAKEFILE#:3: all] Terminated', POSIX::SIGTERM);
|
||||
!, '-O -j2', '/#MAKE#: \*\*\* \[#MAKEFILE#:3: all] Terminated/', POSIX::SIGTERM);
|
||||
}
|
||||
unlink($fout);
|
||||
|
||||
|
||||
@@ -95,5 +95,70 @@ run_make_test(undef,
|
||||
|
||||
unlink('foo.baz', 'foo.biz', 'foo.bar');
|
||||
|
||||
|
||||
touch('hello.c');
|
||||
unlink('hello.o');
|
||||
|
||||
# sv 63821.
|
||||
# Default suffix rule .c.o.
|
||||
|
||||
run_make_test('all: hello.o', 'COMPILE.c=@echo OUTPUT_OPTION=', 'hello.c');
|
||||
|
||||
# User defined rules beat built-in rules.
|
||||
|
||||
run_make_test(q!
|
||||
all: hello.o
|
||||
.c.o:; $(info $@ user defined .c.o rule)
|
||||
!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n");
|
||||
|
||||
# sv 63821.
|
||||
# The same as above, but suffixes are cleared.
|
||||
|
||||
run_make_test(q!
|
||||
all: hello.o
|
||||
.SUFFIXES:
|
||||
.c.o:; $(info $@ user defined .c.o rule)
|
||||
!, '', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512);
|
||||
|
||||
# sv 63821.
|
||||
# Suffixes are cleared and defined in the makefile.
|
||||
|
||||
run_make_test(q!
|
||||
all: hello.o
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
.c.o:; $(info $@ user defined .c.o rule)
|
||||
!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n");
|
||||
|
||||
# sv 63821.
|
||||
# When built-in rules are disabled, but certain suffixes are added to
|
||||
# .SUFFIXES, make should exit with the 'No rule...' error message.
|
||||
|
||||
run_make_test(q!
|
||||
.SUFFIXES: .c .o
|
||||
all: hello.o
|
||||
!, '-r', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512);
|
||||
|
||||
# sv 63821.
|
||||
# Same as above, but this time built-in rules are disabled inside the makefile.
|
||||
|
||||
run_make_test(q!
|
||||
MAKEFLAGS += -r
|
||||
.SUFFIXES: .c .o
|
||||
all: hello.o
|
||||
!, '', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512);
|
||||
|
||||
# sv 63821.
|
||||
# Same as above, but this time there is a rule.
|
||||
|
||||
run_make_test(q!
|
||||
all: hello.o
|
||||
MAKEFLAGS += -r
|
||||
.SUFFIXES: .c .o
|
||||
.c.o:; $(info $@ user defined .c.o rule)
|
||||
!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n");
|
||||
|
||||
unlink('hello.c', 'hello.o');
|
||||
|
||||
# Complete
|
||||
1;
|
||||
|
||||
@@ -58,12 +58,11 @@ use POSIX ();
|
||||
|
||||
# sv 63157.
|
||||
# Test that make removes the temporary file which holds make code from stdin,
|
||||
# even when a signal is received.
|
||||
# include bye.mk and bye.mk: rule is needed to cause make to keep the temporary
|
||||
# file for re-exec. Without re-exec make will remove the file before the signal
|
||||
# arrives.
|
||||
# sleep is needed to let make write its "... Terminated" message to the log
|
||||
# file.
|
||||
# even when a signal is received. include bye.mk and bye.mk: rule is needed
|
||||
# to cause make to keep the temporary file for re-exec. Without re-exec make
|
||||
# will remove the file before the signal arrives. sleep is needed to let make
|
||||
# write its "... Terminated" message to the log file. Must use REGEX because
|
||||
# some systems (MacOS) add extra text after Terminated.
|
||||
&utouch(-600, 'bye.mk');
|
||||
close(STDIN);
|
||||
open(STDIN, "<", 'input.mk') || die "$0: cannot open input.mk for reading: $!";
|
||||
@@ -75,7 +74,7 @@ all:;
|
||||
bye.mk: force; @#HELPER# -q term $(pid) sleep 10
|
||||
force:
|
||||
!,
|
||||
'-f-', '#MAKE#: *** [#MAKEFILE#:5: bye.mk] Terminated', POSIX::SIGTERM);
|
||||
'-f-', '/#MAKE#: \*\*\* \[#MAKEFILE#:5: bye.mk] Terminated/', POSIX::SIGTERM);
|
||||
}
|
||||
unlink($fout);
|
||||
|
||||
|
||||
@@ -136,11 +136,13 @@ all: ; $sname
|
||||
|
||||
unlink($sname);
|
||||
|
||||
# SV 57674: ensure we use a system default PATH if one is not set
|
||||
delete $ENV{PATH};
|
||||
run_make_test(q!
|
||||
if ($port_type eq 'UNIX') {
|
||||
# SV 57674: ensure we use a system default PATH if one is not set
|
||||
delete $ENV{PATH};
|
||||
run_make_test(q!
|
||||
a: ; @echo hi
|
||||
!,
|
||||
'', "hi\n");
|
||||
'', "hi\n");
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -20,32 +20,27 @@ also specified on the command line.";
|
||||
$port_type eq 'W32' and return -1;
|
||||
|
||||
open(MAKEFILE,"> $makefile");
|
||||
printf MAKEFILE q,
|
||||
define test
|
||||
if [ ! -f test-file ]; then \
|
||||
echo >> test-file; sleep 2; %s test-file; \
|
||||
else \
|
||||
echo $@ FAILED; \
|
||||
fi
|
||||
endef
|
||||
printf MAKEFILE subst_make_string(q!
|
||||
test = #HELPER# noexist test-file file test-file sleep 2 rm test-file
|
||||
|
||||
all : ONE TWO THREE
|
||||
ONE : ; @$(test)
|
||||
TWO : ; @$(test)
|
||||
THREE : ; @$(test)
|
||||
,, $CMD_rmfile;
|
||||
!);
|
||||
close(MAKEFILE);
|
||||
my $ans = "noexist test-file\nfile test-file\nsleep 2\nrm test-file\n";
|
||||
|
||||
$mkoptions = "-l 0.0001";
|
||||
$mkoptions .= " -j 4" if ($parallel_jobs);
|
||||
|
||||
# We have to wait longer than the default (5s).
|
||||
&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 8);
|
||||
&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 10);
|
||||
|
||||
$slurp = &read_file_into_string(&get_logfile(1));
|
||||
if ($slurp =~ /cannot enforce load limit/) {
|
||||
return -1;
|
||||
}
|
||||
&compare_output("", &get_logfile(1));
|
||||
&compare_output("$ans$ans$ans", &get_logfile(1));
|
||||
|
||||
1;
|
||||
|
||||
@@ -7,12 +7,52 @@ $details = "";
|
||||
|
||||
# Ensure turning on .POSIX enables the -e flag for the shell
|
||||
|
||||
run_make_test(qq!
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; \@#HELPER# -q fail 1; true
|
||||
all: ; @#HELPER# -q fail 1; #HELPER# out hello
|
||||
!,
|
||||
'', "#MAKE#: *** [#MAKEFILE#:3: all] Error 1\n", 512);
|
||||
|
||||
# But explicit settings must still take precedence
|
||||
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; @-#HELPER# -q fail 1; #HELPER# out hello
|
||||
.SHELLFLAGS = -c
|
||||
!,
|
||||
'', "hello");
|
||||
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; @-#HELPER# -q fail 1; #HELPER# out hello
|
||||
all: .SHELLFLAGS = -c
|
||||
!,
|
||||
'', "hello");
|
||||
|
||||
# SV 63667: We shouldn't add -e to sh if errors are ignored
|
||||
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; @-#HELPER# -q fail 1; #HELPER# out hello
|
||||
!,
|
||||
'', "hello\n");
|
||||
|
||||
# But explicit settings must still take precedence
|
||||
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; @-#HELPER# -q fail 1; #HELPER# out hello
|
||||
.SHELLFLAGS = -ec
|
||||
!,
|
||||
'', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)\n");
|
||||
|
||||
run_make_test(q!
|
||||
.POSIX:
|
||||
all: ; @-#HELPER# -q fail 1; #HELPER# out hello
|
||||
all: .SHELLFLAGS = -ec
|
||||
!,
|
||||
'', "#MAKE#: [#MAKEFILE#:3: all] Error 1 (ignored)\n");
|
||||
|
||||
# User settings must override .POSIX
|
||||
# In the standard .POSIX must be the first thing in the makefile
|
||||
# but we relax that rule in GNU Make.
|
||||
|
||||
@@ -209,7 +209,7 @@ $answer
|
||||
# sv 63347.
|
||||
# Same as above, with makefile setting the value of the same variables as
|
||||
# defined on the cli.
|
||||
my $answer = 'erR -- hello:=world FOO=bar';
|
||||
$answer = 'erR -- hello:=world FOO=bar';
|
||||
run_make_test(q!
|
||||
$(info $(MAKEFLAGS))
|
||||
FOO=moon
|
||||
@@ -224,7 +224,7 @@ $answer
|
||||
|
||||
# sv 63347.
|
||||
# Same as above, with makefile overriding the value of cli definition.
|
||||
my $answer = 'erR -- hello:=world FOO=bar';
|
||||
$answer = 'erR -- hello:=world FOO=bar';
|
||||
run_make_test(q!
|
||||
$(info $(MAKEFLAGS))
|
||||
override FOO=moon
|
||||
@@ -240,7 +240,7 @@ $answer
|
||||
|
||||
# Same as above, and makefile overrides the value of cli definition.
|
||||
# resets MAKEOVERRIDES.
|
||||
my $answer = 'rR -- hello:=world FOO=bar';
|
||||
$answer = 'rR -- hello:=world FOO=bar';
|
||||
run_make_test(q!
|
||||
$(info $(MAKEFLAGS))
|
||||
override FOO=moon
|
||||
@@ -259,7 +259,7 @@ rR -- \nrR
|
||||
# sv 63347.
|
||||
# MAKEFLAGS set is env and makefile sets MAKEFLAGS and there is a command
|
||||
# line definition.
|
||||
my $answer = ' -- bye=moon hello=world';
|
||||
$answer = ' -- bye=moon hello=world';
|
||||
$ENV{'MAKEFLAGS'} = 'hello=world';
|
||||
run_make_test(q!
|
||||
$(info $(MAKEFLAGS))
|
||||
@@ -271,7 +271,7 @@ all:; $(info $(MAKEFLAGS))
|
||||
|
||||
# sv 63347.
|
||||
# Conditional assignment and MAKEFLAGS.
|
||||
my $answer = 'B -- bye=moon hello=world';
|
||||
$answer = 'B -- bye=moon hello=world';
|
||||
$ENV{'MAKEFLAGS'} = 'hello=world';
|
||||
run_make_test(q!
|
||||
$(info $(MAKEFLAGS))
|
||||
@@ -389,7 +389,7 @@ all:; $(info good)
|
||||
# contains the winning switch at parse and build time.
|
||||
# 9. MAKEFLAGS does not contain the beaten switch.
|
||||
|
||||
my @flavors = ('=', ':=', ':::=', '+=');
|
||||
@flavors = ('=', ':=', ':::=', '+=');
|
||||
|
||||
# sv 63537
|
||||
# -w vs --no-print-directory
|
||||
@@ -489,8 +489,8 @@ run_make_test("
|
||||
MAKEFLAGS${fl}--no-print-directory
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
\$(MAKE) -C lib2
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t \$(MAKE) -C lib2
|
||||
", '-w',
|
||||
"#MAKE#: Entering directory '#PWD#'
|
||||
w
|
||||
@@ -511,8 +511,8 @@ run_make_test("
|
||||
MAKEFLAGS${fl}--no-print-directory
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
\$(MAKE) -C lib2
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t \$(MAKE) -C lib2
|
||||
", '',
|
||||
"#MAKE#: Entering directory '#PWD#'
|
||||
w
|
||||
@@ -535,66 +535,70 @@ rmdir('lib2');
|
||||
# -S in env.
|
||||
$ENV{'MAKEFLAGS'} = '-S';
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
$(info $(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
$(info $(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
> $(info $(MAKEFLAGS))
|
||||
> #HELPER# -q fail 1
|
||||
two:; $(info $@)
|
||||
!, '',
|
||||
"S
|
||||
S
|
||||
#HELPER# -q fail 1
|
||||
#MAKE#: *** [#MAKEFILE#:6: one] Error 1", 512);
|
||||
#MAKE#: *** [#MAKEFILE#:7: one] Error 1", 512);
|
||||
|
||||
# -S in env, -k on the command line.
|
||||
$ENV{'MAKEFLAGS'} = '-S';
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
$(info $(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
$(info $(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
> $(info $(MAKEFLAGS))
|
||||
> #HELPER# -q fail 1
|
||||
two:; $(info $@)
|
||||
!, '-k',
|
||||
"k
|
||||
k
|
||||
#HELPER# -q fail 1
|
||||
#MAKE#: *** [#MAKEFILE#:6: one] Error 1
|
||||
#MAKE#: *** [#MAKEFILE#:7: one] Error 1
|
||||
two
|
||||
#MAKE#: Target 'all' not remade because of errors.", 512);
|
||||
|
||||
# -k in env.
|
||||
$ENV{'MAKEFLAGS'} = '-k';
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
$(info $(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
$(info $(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
> $(info $(MAKEFLAGS))
|
||||
> #HELPER# -q fail 1
|
||||
two:; $(info $@)
|
||||
!, '',
|
||||
"k
|
||||
k
|
||||
#HELPER# -q fail 1
|
||||
#MAKE#: *** [#MAKEFILE#:6: one] Error 1
|
||||
#MAKE#: *** [#MAKEFILE#:7: one] Error 1
|
||||
two
|
||||
#MAKE#: Target 'all' not remade because of errors.", 512);
|
||||
|
||||
# -k in env, -S on the command line.
|
||||
$ENV{'MAKEFLAGS'} = '-k';
|
||||
run_make_test(q!
|
||||
.RECIPEPREFIX := >
|
||||
$(info $(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
$(info $(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
> $(info $(MAKEFLAGS))
|
||||
> #HELPER# -q fail 1
|
||||
two:; $(info $@)
|
||||
!, '-S',
|
||||
"S
|
||||
S
|
||||
#HELPER# -q fail 1
|
||||
#MAKE#: *** [#MAKEFILE#:6: one] Error 1", 512);
|
||||
#MAKE#: *** [#MAKEFILE#:7: one] Error 1", 512);
|
||||
|
||||
delete $ENV{'MAKEFLAGS'};
|
||||
|
||||
@@ -605,8 +609,8 @@ MAKEFLAGS${fl}-k
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '',
|
||||
"k
|
||||
@@ -625,8 +629,8 @@ MAKEFLAGS${fl}-k
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '-S',
|
||||
"S
|
||||
@@ -644,8 +648,8 @@ MAKEFLAGS${fl}-k
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '',
|
||||
"S
|
||||
@@ -664,8 +668,8 @@ MAKEFLAGS${fl}-S
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '',
|
||||
"S
|
||||
@@ -681,8 +685,8 @@ MAKEFLAGS${fl}-S
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '-k',
|
||||
"k
|
||||
@@ -702,8 +706,8 @@ MAKEFLAGS${fl}-S
|
||||
\$(info \$(MAKEFLAGS))
|
||||
all: one two
|
||||
one:
|
||||
\$(info \$(MAKEFLAGS))
|
||||
#HELPER# -q fail 1
|
||||
\t \$(info \$(MAKEFLAGS))
|
||||
\t #HELPER# -q fail 1
|
||||
two:; \$(info \$@)
|
||||
", '',
|
||||
"k
|
||||
|
||||
@@ -413,7 +413,6 @@ sub get_osname
|
||||
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"}) {
|
||||
@@ -908,9 +907,9 @@ sub compare_answer_vms
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub compare_answer_zos
|
||||
sub convert_answer_zos
|
||||
{
|
||||
my ($kgo, $log) = @_;
|
||||
my ($log) = @_;
|
||||
|
||||
# z/OS emits "Error 143" or "SIGTERM" instead of terminated
|
||||
$log =~ s/Error 143/Terminated/gm;
|
||||
@@ -920,7 +919,7 @@ sub compare_answer_zos
|
||||
$log =~ s/EDC5129I No such file or directory\./No such file or directory/gm;
|
||||
$log =~ s/FSUM7351 not found/not found/gm;
|
||||
|
||||
return $log eq $kgo;
|
||||
return $log;
|
||||
}
|
||||
|
||||
sub compare_answer
|
||||
@@ -939,10 +938,16 @@ sub compare_answer
|
||||
$log =~ s,\r\n,\n,gs;
|
||||
return 1 if ($log eq $kgo);
|
||||
|
||||
# Keep these in case it's a regex
|
||||
# Keep the originals in case it's a regex
|
||||
$mkgo = $kgo;
|
||||
$mlog = $log;
|
||||
|
||||
# z/OS has quirky outputs
|
||||
if ($osname eq 'os390') {
|
||||
$mlog = convert_answer_zos($mlog);
|
||||
return 1 if ($mlog eq $kgo);
|
||||
}
|
||||
|
||||
# Some versions of Perl on Windows use /c instead of C:
|
||||
$mkgo =~ s,\b([A-Z]):,/\L$1,g;
|
||||
$mlog =~ s,\b([A-Z]):,/\L$1,g;
|
||||
@@ -956,9 +961,6 @@ sub compare_answer
|
||||
# VMS is a whole thing...
|
||||
return 1 if ($osname eq 'VMS' && compare_answer_vms($kgo, $log));
|
||||
|
||||
# z/OS has its own quirks
|
||||
return 1 if ($osname eq 'os390' && compare_answer_zos($kgo, $log));
|
||||
|
||||
# See if the answer might be a regex.
|
||||
if ($kgo =~ m,^/(.+)/$,) {
|
||||
# Check the regex against both the original and modified strings
|
||||
|
||||
@@ -8,17 +8,19 @@
|
||||
# Each step consists of an operator and argument.
|
||||
#
|
||||
# It supports the following operators:
|
||||
# out <word> : echo <word> to stdout with a newline
|
||||
# raw <word> : echo <word> to stdout without adding anything
|
||||
# env <word> : echo the value of the env.var. <word>, or "<unset>"
|
||||
# file <word> : echo <word> to stdout AND create the file <word>
|
||||
# dir <word> : echo <word> to stdout AND create the directory <word>
|
||||
# rm <word> : echo <word> to stdout AND delete the file/directory <word>
|
||||
# wait <word> : wait for a file named <word> to exist
|
||||
# tmout <secs> : Change the timeout for waiting. Default is 4 seconds.
|
||||
# sleep <secs> : Sleep for <secs> seconds then echo <secs>
|
||||
# term <pid> : send SIGTERM to PID <pid>
|
||||
# fail <err> : echo <err> to stdout then exit with error code err
|
||||
# out <word> : echo <word> to stdout with a newline
|
||||
# raw <word> : echo <word> to stdout without adding anything
|
||||
# env <word> : echo the value of the env.var. <word>, or "<unset>"
|
||||
# file <word> : echo <word> to stdout AND create the file <word>
|
||||
# dir <word> : echo <word> to stdout AND create the directory <word>
|
||||
# rm <word> : echo <word> to stdout AND delete the file/directory <word>
|
||||
# wait <word> : wait for a file named <word> to exist
|
||||
# exist <word> : echo <word> AND fail if a file named <word> doesn't exist
|
||||
# noexist <word> : echo <word> AND fail if a file named <word> exists
|
||||
# tmout <secs> : Change the timeout for waiting. Default is 4 seconds.
|
||||
# sleep <secs> : Sleep for <secs> seconds then echo <secs>
|
||||
# term <pid> : send SIGTERM to PID <pid>
|
||||
# fail <err> : echo <err> to stdout then exit with error code err
|
||||
#
|
||||
# If given -q only the "out", "raw", and "env" commands generate output.
|
||||
|
||||
@@ -60,6 +62,18 @@ sub op {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($op eq 'exist') {
|
||||
-f "$nm" || die "$nm: file should exist: $!\n";
|
||||
print "exist $nm\n" unless $quiet;
|
||||
return 1
|
||||
}
|
||||
|
||||
if ($op eq 'noexist') {
|
||||
-f "$nm" && die "$nm: file exists\n";
|
||||
print "noexist $nm\n" unless $quiet;
|
||||
return 1
|
||||
}
|
||||
|
||||
# Show the output before creating the directory
|
||||
if ($op eq 'dir') {
|
||||
print "dir $nm\n" unless $quiet;
|
||||
|
||||
Reference in New Issue
Block a user