summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2004-05-16 19:16:52 +0000
committerPaul Smith <psmith@gnu.org>2004-05-16 19:16:52 +0000
commit08c8105c5468ff743d2f2ff2fdf3b77a6313b53e (patch)
tree51954f0469a6d70c1b58fd30a5955aa5e4b65c86
parente334942e573ea8a4416eca0afafcaf45c3bba06f (diff)
downloadgunmake-08c8105c5468ff743d2f2ff2fdf3b77a6313b53e.tar.gz
Various enhancements
- OS/2 Patches - OpenVMS updates - Sanitize the handling of -include/sinclude with and without -k - Fix the setting of $< for order-only rules.
-rw-r--r--ChangeLog55
-rw-r--r--Makefile.am4
-rw-r--r--commands.c12
-rw-r--r--configure.in3
-rw-r--r--default.c6
-rw-r--r--dep.h2
-rw-r--r--doc/make.texi26
-rw-r--r--file.c6
-rw-r--r--getloadavg.c2
-rw-r--r--job.c36
-rw-r--r--main.c18
-rw-r--r--make.h2
-rw-r--r--makefile.vms4
-rw-r--r--read.c8
-rw-r--r--readme.vms51
-rw-r--r--remake.c100
-rwxr-xr-xtests/run_make_tests.pl132
-rw-r--r--tests/scripts/features/echoing9
-rw-r--r--tests/scripts/features/errors25
-rw-r--r--tests/scripts/features/include33
-rw-r--r--tests/scripts/features/order_only11
-rw-r--r--tests/scripts/functions/wildcard7
-rw-r--r--tests/scripts/options/dash-C9
-rw-r--r--tests/scripts/options/dash-k14
-rw-r--r--tests/scripts/targets/FORCE13
-rw-r--r--tests/scripts/targets/PHONY15
-rw-r--r--tests/scripts/targets/SILENT12
-rw-r--r--tests/scripts/targets/clean5
-rw-r--r--tests/scripts/variables/special22
-rw-r--r--tests/test_driver.pl47
30 files changed, 458 insertions, 231 deletions
diff --git a/ChangeLog b/ChangeLog
index 30f13b9..759c4e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2004-05-16 Paul D. Smith <psmith@gnu.org>
+
+ * remake.c (update_goal_chain): Change the argument specifying
+ whether we're rebuilding makefiles to be a global variable,
+ REBUILDING_MAKEFILES.
+ (complain): Extract the code that complains about no rules to make
+ a target into a separate function.
+ (update_file_1): If we tried to rebuild a file during the makefile
+ rebuild phase and it was dontcare, then no message was printed.
+ If we then try to build the same file during the normal build,
+ print a message this time.
+ (remake_file): Don't complain about un-remake-able files when
+ we're rebuilding makefiles.
+
+2004-05-11 Paul D. Smith <psmith@gnu.org>
+
+ * job.c (construct_command_argv_internal): OS/2 patches from
+ Andreas Buening <andreas.buening@nexgo.de>.
+
+2004-05-10 Paul D. Smith <psmith@gnu.org>
+
+ * remake.c (update_file): Don't walk the double-colon chain unless
+ this is a double-colon rule. Fix suggested by Boris Kolpackov
+ <boris@kolpackov.net>.
+
+ * makefile.vms (CFLAGS): Remove glob/globfree (see readme.vms docs)
+ * readme.vms: New section describing OpenVMS support and issues.
+ * default.c (default_variables): Add support for IA64.
+ * job.c (tryToSetupYAst) [VMS]: On VMS running make in batch mode
+ without some privilege aborts make with the error
+ %SYSTEM-F-NOPRIV. It happens when setting up a handler for
+ pressing Ctrl+Y and the input device is no terminal. The change
+ catches this error and just continues.
+
+ Patches by Hartmut Becker <Hartmut.Becker@hp.com>
+
+2004-04-25 Paul D. Smith <psmith@gnu.org>
+
+ * commands.c (set_file_variables): Set $< properly in the face of
+ order-only prerequisites.
+ Patch from Boris Kolpackov <boris@kolpackov.net>
+
+2004-04-21 Bob Byrnes <byrnes@curl.com>
+
+ * main.c (main): Notice failures to remake makefiles.
+
+2004-03-28 Paul D. Smith <psmith@gnu.org>
+
+ Patches for Acorn RISC OS by Peter Naulls <peter@chocky.org>
+
+ * job.c: No default shell for RISC OS.
+ (load_too_high): Hard-code the return to 1.
+ (construct_command_argv_internal): No sh_chars or sh_cmds.
+ * getloadavg.c: Don't set LOAD_AVE_TYPE on RISC OS.
+
2004-03-20 Paul D. Smith <psmith@gnu.org>
* variable.c (do_variable_definition): Don't append from the
diff --git a/Makefile.am b/Makefile.am
index 77ebdf6..96fb188 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -114,11 +114,11 @@ check-local: check-regression check-loadavg
.PHONY: check-loadavg check-regression
-check-loadavg: loadavg
+check-loadavg: loadavg$(EXEEXT)
@echo The system uptime program believes the load average to be:
-uptime
@echo The GNU load average checking code thinks:
- -./loadavg
+ -./loadavg$(EXEEXT)
# The loadavg function is invoked during "make check" to test getloadavg.
noinst_PROGRAMS = loadavg
diff --git a/commands.c b/commands.c
index a1766b4..b202f6c 100644
--- a/commands.c
+++ b/commands.c
@@ -41,6 +41,7 @@ extern int getpid ();
static void
set_file_variables (struct file *file)
{
+ struct dep *d;
char *at, *percent, *star, *less;
#ifndef NO_ARCHIVES
@@ -105,8 +106,14 @@ set_file_variables (struct file *file)
}
star = file->stem;
- /* $< is the first dependency. */
- less = file->deps != 0 ? dep_name (file->deps) : "";
+ /* $< is the first not order-only dependency. */
+ less = "";
+ for (d = file->deps; d != 0; d = d->next)
+ if (!d->ignore_mtime)
+ {
+ less = dep_name (d);
+ break;
+ }
if (file->cmds == default_file->cmds)
/* This file got its commands from .DEFAULT.
@@ -134,7 +141,6 @@ set_file_variables (struct file *file)
char *caret_value;
char *qp;
char *bp;
- struct dep *d;
unsigned int len;
/* Compute first the value for $+, which is supposed to contain
diff --git a/configure.in b/configure.in
index b28c3fb..15c2b88 100644
--- a/configure.in
+++ b/configure.in
@@ -259,7 +259,8 @@ if test "$make_cv_sa_restart" != no; then
[Define if <signal.h> defines the SA_RESTART constant.])
fi
-# enable make_cv_sa_restart for OS/2
+# enable make_cv_sa_restart for OS/2 so that the jobserver will be enabled,
+# but do it after HAVE_SA_RESTART has been defined.
case "$host_os" in
os2*) make_cv_sa_restart=yes ;;
esac
diff --git a/default.c b/default.c
index b07f152..58855c6 100644
--- a/default.c
+++ b/default.c
@@ -308,7 +308,11 @@ static char *default_variables[] =
#ifdef VMS
#ifdef __ALPHA
"ARCH", "ALPHA",
-#else
+#endif
+#ifdef __ia64
+ "ARCH", "IA64",
+#endif
+#ifdef __VAX
"ARCH", "VAX",
#endif
"AR", "library/obj",
diff --git a/dep.h b/dep.h
index 7f4380b..4c9a152 100644
--- a/dep.h
+++ b/dep.h
@@ -74,5 +74,5 @@ extern char *dep_name ();
extern struct dep *copy_dep_chain PARAMS ((struct dep *d));
extern struct dep *read_all_makefiles PARAMS ((char **makefiles));
extern int eval_buffer PARAMS ((char *buffer));
-extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles));
+extern int update_goal_chain PARAMS ((struct dep *goals));
extern void uniquize_deps PARAMS ((struct dep *));
diff --git a/doc/make.texi b/doc/make.texi
index 7270134..e694068 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -9,11 +9,11 @@
@set RCSID $Id$
@set EDITION 0.61
-@set VERSION 3.81
-@set UPDATED 02 May 2003
-@set UPDATE-MONTH May 2003
-@comment The ISBN number might need to change on next publication.
-@set ISBN 1-882114-81-7 @c From Brian Youmans <3diff@gnu.org>, 25 Apr 2000
+@set VERSION 3.80
+@set UPDATED 23 Feb 2003
+@set UPDATE-MONTH Feb 2003
+@c ISBN provided by Lisa M. Opus Goldstein <opus@gnu.org>, 5 May 2004
+@set ISBN 1-882114-83-5
@c finalout
@@ -6637,7 +6637,8 @@ files := $(shell echo *.c)
@noindent
sets @code{files} to the expansion of @samp{*.c}. Unless @code{make} is
using a very strange shell, this has the same result as
-@w{@samp{$(wildcard *.c)}}.@refill
+@w{@samp{$(wildcard *.c)}} (as long as at least one @samp{.c} file
+exists).@refill
@node Make Control Functions, , Shell Function, Functions
@section Functions That Control Make
@@ -7519,8 +7520,8 @@ retained for compatibility.
* Implicit Variables:: How to change what predefined rules do.
* Chained Rules:: How to use a chain of implicit rules.
* Pattern Rules:: How to define new implicit rules.
-* Last Resort:: How to defining commands for rules
- which cannot find any.
+* Last Resort:: How to define commands for rules which
+ cannot find any.
* Suffix Rules:: The old-fashioned style of implicit rule.
* Implicit Rule Search:: The precise algorithm for applying
implicit rules.
@@ -9445,6 +9446,7 @@ Various new built-in implicit rules.
@item
The built-in variable @samp{MAKE_VERSION} gives the version number of
@code{make}.
+@vindex MAKE_VERSION
@end itemize
@node Missing, Makefile Conventions, Features, Top
@@ -10220,9 +10222,11 @@ AUX = README COPYING ChangeLog Makefile.in \
level-0 level-1 backup-specs testpad.c
@end group
+.PHONY: all
all: tar rmt tar.info
@group
+.PHONY: tar
tar: $(OBJS)
$(CC) $(LDFLAGS) -o $@@ $(OBJS) $(LIBS)
@end group
@@ -10238,6 +10242,7 @@ tar.info: tar.texinfo
@end group
@group
+.PHONY: install
install: all
$(INSTALL) tar $(bindir)/$(binprefix)tar
-test ! -f rmt || $(INSTALL) rmt /etc/rmt
@@ -10266,21 +10271,25 @@ TAGS: $(SRCS)
@end group
@group
+.PHONY: clean
clean:
rm -f *.o tar rmt testpad testpad.h core
@end group
@group
+.PHONY: distclean
distclean: clean
rm -f TAGS Makefile config.status
@end group
@group
+.PHONY: realclean
realclean: distclean
rm -f tar.info*
@end group
@group
+.PHONY: shar
shar: $(SRCS) $(AUX)
shar $(SRCS) $(AUX) | compress \
> tar-`sed -e '/version_string/!d' \
@@ -10290,6 +10299,7 @@ shar: $(SRCS) $(AUX)
@end group
@group
+.PHONY: dist
dist: $(SRCS) $(AUX)
echo tar-`sed \
-e '/version_string/!d' \
diff --git a/file.c b/file.c
index 0d577d1..8f89503 100644
--- a/file.c
+++ b/file.c
@@ -342,6 +342,10 @@ remove_intermediates (int sig)
if (! HASH_VACANT (*file_slot))
{
register struct file *f = *file_slot;
+ /* Is this file eligible for automatic deletion?
+ Yes, IFF: it's marked intermediate, it's not secondary, it wasn't
+ given on the command-line, and it's either a -include makefile or
+ it's not precious. */
if (f->intermediate && (f->dontcare || !f->precious)
&& !f->secondary && !f->cmd_target)
{
@@ -679,7 +683,7 @@ print_file (const void *item)
if (f->cmd_target)
puts (_("# Command-line target."));
if (f->dontcare)
- puts (_("# A default or MAKEFILES makefile."));
+ puts (_("# A default, MAKEFILES, or -include/sinclude makefile."));
puts (f->tried_implicit
? _("# Implicit rule search has been done.")
: _("# Implicit rule search has not been done."));
diff --git a/getloadavg.c b/getloadavg.c
index c4d9746..16deff5 100644
--- a/getloadavg.c
+++ b/getloadavg.c
@@ -355,7 +355,7 @@ extern int errno;
/* LOAD_AVE_TYPE should only get defined if we're going to use the
nlist method. */
-# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL))
+# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) && !defined(__riscos__)
# define LOAD_AVE_TYPE double
# endif
diff --git a/job.c b/job.c
index 0153995..13431d3 100644
--- a/job.c
+++ b/job.c
@@ -63,6 +63,11 @@ int batch_mode_shell = 0;
char default_shell[] = "";
int batch_mode_shell = 0;
+#elif defined (__riscos__)
+
+char default_shell[] = "";
+int batch_mode_shell = 0;
+
#else
char default_shell[] = "/bin/sh";
@@ -1725,7 +1730,7 @@ job_next_command (struct child *child)
static int
load_too_high (void)
{
-#if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA)
+#if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA) || defined(__riscos__)
return 1;
#else
static double last_sec;
@@ -1953,7 +1958,9 @@ static void tryToSetupYAst(void) {
}
status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
astHandler,0,0,0,0,0);
- if (status==SS$_ILLIOFUNC) {
+ if (status==SS$_NORMAL)
+ status= iosb.status;
+ if (status==SS$_ILLIOFUNC || status==SS$_NOPRIV) {
sys$dassgn(chan);
#ifdef CTRLY_ENABLED_ANYWAY
fprintf (stderr,
@@ -1962,9 +1969,8 @@ static void tryToSetupYAst(void) {
return;
#endif
}
- if (status==SS$_NORMAL)
- status= iosb.status;
- if (!(status&SS$_NORMAL)) {
+ else if (!(status&SS$_NORMAL)) {
+ sys$dassgn(chan);
lib$signal(status);
return;
}
@@ -2773,6 +2779,9 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
0 };
char* sh_chars;
char** sh_cmds;
+#elif defined(__riscos__)
+ static char sh_chars[] = "";
+ static char *sh_cmds[] = { 0 };
#else /* must be UNIX-ish */
static char sh_chars[] = "#;\"*?[]&|<>(){}$`^~!";
static char *sh_cmds[] = { ".", ":", "break", "case", "cd", "continue",
@@ -3295,7 +3304,22 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
We use line here instead of new_line because we run the shell
manually. */
size_t line_len = strlen (line);
+ char *p = new_line;
+ char *q = new_line;
memcpy (new_line, line, line_len + 1);
+ /* replace all backslash-newline combination and also following tabs */
+ while (*q != '\0')
+ {
+ if (q[0] == '\\' && q[1] == '\n')
+ {
+ q += 2; /* remove '\\' and '\n' */
+ if (q[0] == '\t')
+ q++; /* remove 1st tab in the next line */
+ }
+ else
+ *p++ = *q++;
+ }
+ *p = '\0';
# ifndef NO_CMD_DEFAULT
if (strnicmp (new_line, "echo", 4) == 0
@@ -3338,7 +3362,7 @@ construct_command_argv_internal (char *line, char **restp, char *shell,
new_argv[1] = new_argv[0] + sh_len + 1;
memcpy (new_argv[1], "/c", 3);
new_argv[2] = new_argv[1] + 3;
- memcpy (new_argv[2], new_line, line_len);
+ memcpy (new_argv[2], new_line, line_len + 1);
new_argv[3] = NULL;
}
}
diff --git a/main.c b/main.c
index d17e576..13c3415 100644
--- a/main.c
+++ b/main.c
@@ -259,6 +259,11 @@ int warn_undefined_variables_flag;
they appear out of date or not. */
int always_make_flag = 0;
+
+/* If nonzero, we're in the "try to rebuild makefiles" phase. */
+
+int rebuilding_makefiles = 0;
+
/* The usage output. We write it this way to make life easier for the
translators, especially those trying to translate to right-to-left
@@ -839,6 +844,7 @@ main (int argc, char **argv, char **envp)
static char *stdin_nm = 0;
struct file *f;
int i;
+ int makefile_status = MAKE_SUCCESS;
char **p;
struct dep *read_makefiles;
PATH_VAR (current_directory);
@@ -1666,6 +1672,7 @@ main (int argc, char **argv, char **envp)
char **nargv = argv;
int nargc = argc;
int orig_db_level = db_level;
+ int status;
if (! ISDB (DB_MAKEFILES))
db_level = DB_NONE;
@@ -1726,7 +1733,11 @@ main (int argc, char **argv, char **envp)
/* Set up `MAKEFLAGS' specially while remaking makefiles. */
define_makeflags (1, 1);
- switch (update_goal_chain (read_makefiles, 1))
+ rebuilding_makefiles = 1;
+ status = update_goal_chain (read_makefiles);
+ rebuilding_makefiles = 0;
+
+ switch (status)
{
case 1:
/* The only way this can happen is if the user specified -q and asked
@@ -1775,6 +1786,7 @@ main (int argc, char **argv, char **envp)
mtime = file_mtime_no_search (d->file);
any_remade |= (mtime != NONEXISTENT_MTIME
&& mtime != makefile_mtimes[i]);
+ makefile_status = MAKE_FAILURE;
}
}
else
@@ -1985,13 +1997,13 @@ main (int argc, char **argv, char **envp)
DB (DB_BASIC, (_("Updating goal targets....\n")));
- switch (update_goal_chain (goals, 0))
+ switch (update_goal_chain (goals))
{
case -1:
/* Nothing happened. */
case 0:
/* Updated successfully. */
- status = MAKE_SUCCESS;
+ status = makefile_status;
break;
case 1:
/* We are under -q and would run some commands. */
diff --git a/make.h b/make.h
index ea8f07c..ce88d5c 100644
--- a/make.h
+++ b/make.h
@@ -496,7 +496,7 @@ extern int print_data_base_flag, question_flag, touch_flag, always_make_flag;
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
extern int print_version_flag, print_directory_flag;
extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;
-extern int clock_skew_detected;
+extern int clock_skew_detected, rebuilding_makefiles;
/* can we run commands via 'sh -c xxx' or must we use batch files? */
extern int batch_mode_shell;
diff --git a/makefile.vms b/makefile.vms
index 3ada831..6ed86c1 100644
--- a/makefile.vms
+++ b/makefile.vms
@@ -5,6 +5,7 @@
# Klaus Kämpf (kkaempf@rmi.de)
# Modified for version 3.78.1 by Hartmut.Becker@compaq.com.
# Modified for version 3.80 by zinser@decus.de
+# Modified for version 3.81 by Hartmut Becker
#
# GNU Make is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -31,7 +32,7 @@ CP = copy
#
ifeq ($(CC),cc)
-CFLAGS = $(defines) /include=([],[.glob])/prefix=all/standard=relaxed
+CFLAGS = $(defines) /include=([],[.glob])/prefix=(all,except=(glob,globfree))/standard=relaxed
else
CFLAGS = $(defines) /include=([],[.glob])
endif
@@ -111,7 +112,6 @@ make.exe: $(objs)
clean:
$$ purge [...]
-$(RM) make.exe;,*.obj;
- -$(RM) *.opt;
-$(RM) [.glob]*.obj;
# Automatically generated dependencies.
diff --git a/read.c b/read.c
index 1da2eac..e2ad630 100644
--- a/read.c
+++ b/read.c
@@ -367,16 +367,14 @@ eval_makefile (char *filename, int flags)
deps->name = 0;
deps->file = lookup_file (filename);
if (deps->file == 0)
- {
- deps->file = enter_file (xstrdup (filename));
- if (flags & RM_DONTCARE)
- deps->file->dontcare = 1;
- }
+ deps->file = enter_file (xstrdup (filename));
if (filename != ebuf.floc.filenm)
free (filename);
filename = deps->file->name;
deps->changed = flags;
deps->ignore_mtime = 0;
+ if (flags & RM_DONTCARE)
+ deps->file->dontcare = 1;
/* If the makefile can't be found at all, give up entirely. */
diff --git a/readme.vms b/readme.vms
index d4a9667..6e1436f 100644
--- a/readme.vms
+++ b/readme.vms
@@ -1,3 +1,54 @@
+This is the VMS version of GNU Make, updated by Hartmut Becker
+
+Changes are based on GNU make 3.80. Latest changes are for OpenVMS/I64
+and new VMS CRTLs.
+
+This version was tested on OpenVMS/I64 V8.2 (field test) with hp C
+X7.1-024 OpenVMS/Alpha V7.3-2 with Compaq C V6.5-001 and OpenVMS/VAX 7.1
+with Compaq C V6.2-003 There are still some warning and informational
+message issued by the compilers.
+
+Build instructions
+Make a 1st version
+ $ @makefile.com
+ $ rena make.exe 1st-make.exe
+Use the 1st version to generate a 2nd version
+ $ mc sys$disk:[]1st-make clean
+ $ mc sys$disk:[]1st-make
+Verify your 2nd version
+ $ rena make.exe 2nd-make.exe
+ $ mc sys$disk:[]2nd-make clean
+ $ mc sys$disk:[]2nd-make
+
+Changes:
+
+. 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.
+
This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
diff --git a/remake.c b/remake.c
index 619aec0..b0c76dc 100644
--- a/remake.c
+++ b/remake.c
@@ -73,19 +73,20 @@ static int library_search PARAMS ((char **lib, FILE_TIMESTAMP *mtime_ptr));
/* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing
was done, 0 if all goals were updated successfully, or 1 if a goal failed.
- If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should
- be disabled for them unless they were also command-line targets, and we
- should only make one goal at a time and return as soon as one goal whose
- `changed' member is nonzero is successfully made. */
+
+ If rebuilding_makefiles is nonzero, these goals are makefiles, so -t, -q,
+ and -n should be disabled for them unless they were also command-line
+ targets, and we should only make one goal at a time and return as soon as
+ one goal whose `changed' member is nonzero is successfully made. */
int
-update_goal_chain (struct dep *goals, int makefiles)
+update_goal_chain (struct dep *goals)
{
int t = touch_flag, q = question_flag, n = just_print_flag;
unsigned int j = job_slots;
int status = -1;
-#define MTIME(file) (makefiles ? file_mtime_no_search (file) \
+#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
: file_mtime (file))
/* Duplicate the chain so we can remove things from it. */
@@ -135,7 +136,7 @@ update_goal_chain (struct dep *goals, int makefiles)
unsigned int ocommands_started;
int x;
check_renamed (file);
- if (makefiles)
+ if (rebuilding_makefiles)
{
if (file->cmd_target)
{
@@ -152,7 +153,7 @@ update_goal_chain (struct dep *goals, int makefiles)
actually run. */
ocommands_started = commands_started;
- x = update_file (file, makefiles ? 1 : 0);
+ x = update_file (file, rebuilding_makefiles ? 1 : 0);
check_renamed (file);
/* Set the goal's `changed' flag if any commands were started
@@ -176,7 +177,7 @@ update_goal_chain (struct dep *goals, int makefiles)
matter how much more we run, since we already know
the answer to return. */
stop = (!keep_going_flag && !question_flag
- && !makefiles);
+ && !rebuilding_makefiles);
}
else
{
@@ -192,10 +193,10 @@ update_goal_chain (struct dep *goals, int makefiles)
as a command-line target), don't change STATUS.
If STATUS is changed, we will get re-exec'd, and
enter an infinite loop. */
- if (!makefiles
+ if (!rebuilding_makefiles
|| (!just_print_flag && !question_flag))
status = 0;
- if (makefiles && file->dontcare)
+ if (rebuilding_makefiles && file->dontcare)
/* This is a default makefile; stop remaking. */
stop = 1;
}
@@ -218,7 +219,7 @@ update_goal_chain (struct dep *goals, int makefiles)
/* If we have found nothing whatever to do for the goal,
print a message saying nothing needs doing. */
- if (!makefiles
+ if (!rebuilding_makefiles
/* If the update_status is zero, we updated successfully
or not at all. G->changed will have been set above if
any commands were actually started for this goal. */
@@ -257,7 +258,7 @@ update_goal_chain (struct dep *goals, int makefiles)
considered = !considered;
}
- if (makefiles)
+ if (rebuilding_makefiles)
{
touch_flag = t;
question_flag = q;
@@ -321,19 +322,44 @@ update_file (struct file *file, unsigned int depth)
/* Process the remaining rules in the double colon chain so they're marked
considered. Start their prerequisites, too. */
- for (; f != 0 ; f = f->prev)
- {
- struct dep *d;
+ if (file->double_colon)
+ for (; f != 0 ; f = f->prev)
+ {
+ struct dep *d;
- f->considered = considered;
+ f->considered = considered;
- for (d = f->deps; d != 0; d = d->next)
- status |= update_file (d->file, depth + 1);
- }
+ for (d = f->deps; d != 0; d = d->next)
+ status |= update_file (d->file, depth + 1);
+ }
return status;
}
+/* Show a message stating the target failed to build. */
+
+static void
+complain (const struct file *file)
+{
+ const char *msg_noparent
+ = _("%sNo rule to make target `%s'%s");
+ const char *msg_parent
+ = _("%sNo rule to make target `%s', needed by `%s'%s");
+
+ if (!keep_going_flag)
+ {
+ if (file->parent == 0)
+ fatal (NILF, msg_noparent, "", file->name, "");
+
+ fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
+ }
+
+ if (file->parent == 0)
+ error (NILF, msg_noparent, "*** ", file->name, ".");
+ else
+ error (NILF, msg_parent, "*** ", file->name, file->parent->name, ".");
+}
+
/* Consider a single `struct file' and update it as appropriate. */
static int
@@ -353,6 +379,17 @@ update_file_1 (struct file *file, unsigned int depth)
{
DBF (DB_VERBOSE,
_("Recently tried and failed to update file `%s'.\n"));
+
+ /* If the file we tried to make is marked dontcare then no message
+ was printed about it when it failed during the makefile rebuild.
+ If we're trying to build it again in the normal rebuild, print a
+ message now. */
+ if (file->dontcare && !rebuilding_makefiles)
+ {
+ file->dontcare = 0;
+ complain (file);
+ }
+
return file->update_status;
}
@@ -1008,28 +1045,9 @@ remake_file (struct file *file)
file->update_status = 0;
else
{
- const char *msg_noparent
- = _("%sNo rule to make target `%s'%s");
- const char *msg_parent
- = _("%sNo rule to make target `%s', needed by `%s'%s");
-
/* This is a dependency file we cannot remake. Fail. */
- if (!keep_going_flag && !file->dontcare)
- {
- if (file->parent == 0)
- fatal (NILF, msg_noparent, "", file->name, "");
-
- fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
- }
-
- if (!file->dontcare)
- {
- if (file->parent == 0)
- error (NILF, msg_noparent, "*** ", file->name, ".");
- else
- error (NILF, msg_parent, "*** ",
- file->name, file->parent->name, ".");
- }
+ if (!rebuilding_makefiles || !file->dontcare)
+ complain (file);
file->update_status = 2;
}
}
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl
index 4389d43..8452c6b 100755
--- a/tests/run_make_tests.pl
+++ b/tests/run_make_tests.pl
@@ -48,66 +48,100 @@ sub valid_option
return 0;
}
-sub run_make_with_options
+
+# This is an "all-in-one" function. Arguments are as follows:
+#
+# [0] (string): The makefile to be tested.
+# [1] (string): Arguments to pass to make.
+# [2] (string): Answer we should get back.
+# [3] (integer): Exit code we expect. A missing code means 0 (success)
+
+sub run_make_test
{
- local ($filename,$options,$logname,$expected_code) = @_;
- local($code);
- local($command) = $make_path;
+ local ($makestring, $options, $answer, $err_code) = @_;
- $expected_code = 0 unless defined($expected_code);
+ if (! defined($makefile)) {
+ $makefile = &get_tmpfile();
+ }
- if ($filename)
- {
- $command .= " -f $filename";
- }
+ # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
+ # make in both $makestring and $answer.
- if ($options)
- {
- $command .= " $options";
- }
+ $makestring =~ s/#MAKEFILE#/$makefile/g;
+ $makestring =~ s/#MAKE#/$make_name/g;
- if ($valgrind) {
- print VALGRIND "\n\nExecuting: $command\n";
- }
+ $answer =~ s/#MAKEFILE#/$makefile/g;
+ $answer =~ s/#MAKE#/$make_name/g;
- $code = &run_command_with_output($logname,$command);
+ open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
+ print MAKEFILE $makestring, "\n";
+ close(MAKEFILE) || die "Failed to write $makefile: $!\n";
- # Check to see if we have Purify errors. If so, keep the logfile.
- # For this to work you need to build with the Purify flag -exit-status=yes
+ &run_make_with_options($makefile, $options, &get_logfile(0), $err_code);
+ &compare_output($answer, &get_logfile(1));
- if ($pure_log && -f $pure_log) {
- if ($code & 0x7000) {
- $code &= ~0x7000;
+ $makefile = undef;
+}
- # If we have a purify log, save it
- $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
- print("Renaming purify log file to $tn\n") if $debug;
- rename($pure_log, "$tn")
- || die "Can't rename $log to $tn: $!\n";
- ++$purify_errors;
- }
- else {
- unlink($pure_log);
- }
- }
+# The old-fashioned way...
+sub run_make_with_options {
+ local ($filename,$options,$logname,$expected_code) = @_;
+ local($code);
+ local($command) = $make_path;
- if ($code != $expected_code)
- {
- print "Error running $make_path ($code): $command\n";
- $test_passed = 0;
- # If it's a SIGINT, stop here
- if ($code & 127) {
- print STDERR "\nCaught signal ".($code & 127)."!\n";
- exit($code);
- }
- return 0;
- }
+ $expected_code = 0 unless defined($expected_code);
- if ($profile & $vos)
- {
- system "add_profile $make_path";
- }
-1;
+ # Reset to reflect this one test.
+ $test_passed = 1;
+
+ if ($filename) {
+ $command .= " -f $filename";
+ }
+
+ if ($options) {
+ $command .= " $options";
+ }
+
+ if ($valgrind) {
+ print VALGRIND "\n\nExecuting: $command\n";
+ }
+
+ $code = &run_command_with_output($logname,$command);
+
+ # Check to see if we have Purify errors. If so, keep the logfile.
+ # For this to work you need to build with the Purify flag -exit-status=yes
+
+ if ($pure_log && -f $pure_log) {
+ if ($code & 0x7000) {
+ $code &= ~0x7000;
+
+ # If we have a purify log, save it
+ $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
+ print("Renaming purify log file to $tn\n") if $debug;
+ rename($pure_log, "$tn")
+ || die "Can't rename $log to $tn: $!\n";
+ ++$purify_errors;
+ } else {
+ unlink($pure_log);
+ }
+ }
+
+ if ($code != $expected_code) {
+ print "Error running $make_path (expected $expected_code; got $code): $command\n";
+ $test_passed = 0;
+ # If it's a SIGINT, stop here
+ if ($code & 127) {
+ print STDERR "\nCaught signal ".($code & 127)."!\n";
+ exit($code);
+ }
+ return 0;
+ }
+
+ if ($profile & $vos) {
+ system "add_profile $make_path";
+ }
+
+ 1;
}
sub print_usage
diff --git a/tests/scripts/features/echoing b/tests/scripts/features/echoing
index ed1e862..2e366cd 100644
--- a/tests/scripts/features/echoing
+++ b/tests/scripts/features/echoing
@@ -54,13 +54,10 @@ $answer = "echo This makefile did not clean the dir... good\n"
# -------
&run_make_with_options($makefile,"clean",&get_logfile,0);
-$answer = "";
-&compare_output($answer,&get_logfile(1));
-
-if (-f $example)
-{
- $test_passed = 0;
+if (-f $example) {
+ $test_passed = 0;
}
+&compare_output('',&get_logfile(1));
# TEST #3
# -------
diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors
index a39064f..253f50f 100644
--- a/tests/scripts/features/errors
+++ b/tests/scripts/features/errors
@@ -52,6 +52,13 @@ $answer = "$delete_command cleanit\n"
&run_make_with_options($makefile,"",&get_logfile);
+# If make acted as planned, it should ignore the error from the first
+# command in the target and execute the second which deletes the file "foo"
+# This file, therefore, should not exist if the test PASSES.
+if (-f "foo") {
+ $test_passed = 0;
+}
+
# The output for this on VOS is too hard to replicate, so we only check it
# on unix.
if (!$vos)
@@ -59,14 +66,6 @@ if (!$vos)
&compare_output($answer,&get_logfile(1));
}
-# If make acted as planned, it should ignore the error from the first
-# command in the target and execute the second which deletes the file "foo"
-# This file, therefore, should not exist if the test PASSES.
-if (-f "foo")
-{
- $test_passed = 0;
-}
-
&touch("foo");
@@ -80,14 +79,12 @@ $answer = "$delete_command cleanit\n"
&run_make_with_options($makefile,"clean2 -i",&get_logfile);
-if (!$vos)
-{
- &compare_output($answer,&get_logfile(1));
+if (-f "foo") {
+ $test_passed = 0;
}
-if (-f "foo")
-{
- $test_passed = 0;
+if (!$vos) {
+ &compare_output($answer,&get_logfile(1));
}
1;
diff --git a/tests/scripts/features/include b/tests/scripts/features/include
index 60f4482..5f20ad8 100644
--- a/tests/scripts/features/include
+++ b/tests/scripts/features/include
@@ -2,7 +2,8 @@
$description = "Test various forms of the GNU make `include' command.";
-$details = "Test include, -include, sinclude and various regressions involving them.
+$details = "\
+Test include, -include, sinclude and various regressions involving them.
Test extra whitespace at the end of the include, multiple -includes and
sincludes (should not give an error) and make sure that errors are reported
for targets that were also -included.";
@@ -46,16 +47,36 @@ $answer = "There should be no errors for this makefile.\n";
$answer = "This is another included makefile\n";
&compare_output($answer, &get_logfile(1));
+$makefile = undef;
+
# Try to build the "error" target; this will fail since we don't know
# how to create makeit.mk, but we should also get a message (even though
# the -include suppressed it during the makefile read phase, we should
# see one during the makefile run phase).
-# The fix to this caused more problems than the error, so I removed it.
-# pds -- 22 Jan 2000
+run_make_test
+ ('
+-include foo.mk
+error: foo.mk ; @echo $@
+',
+ '',
+ "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n",
+ 512
+ );
+
+# Make sure that target-specific variables don't impact things. This could
+# happen because a file record is created when a target-specific variable is
+# set.
+
+run_make_test
+ ('
+bar.mk: foo := baz
+-include bar.mk
+hello: ; @echo hello
+',
+ '',
+ "hello\n"
+ );
-#&run_make_with_options($makefile, "error", &get_logfile, 512);
-#$answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n";
-#&compare_output($answer, &get_logfile(1));
1;
diff --git a/tests/scripts/features/order_only b/tests/scripts/features/order_only
index ac0d538..82a7253 100644
--- a/tests/scripts/features/order_only
+++ b/tests/scripts/features/order_only
@@ -144,4 +144,15 @@ $answer = "touch baz\n";
unlink(qw(foo.w foo.x baz));
+# TEST #9 -- make sure that $< is set correctly in the face of order-only
+# prerequisites in pattern rules.
+
+run_make_test('
+%r: | baz ; @echo $< $^ $|
+bar: foo
+foo:;@:
+baz:;@:
+', '', "foo foo baz\n");
+
+
1;
diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard
index 0f79acc..5e5a5ff 100644
--- a/tests/scripts/functions/wildcard
+++ b/tests/scripts/functions/wildcard
@@ -85,13 +85,12 @@ else
&run_make_with_options($makefile,"clean",&get_logfile);
-&compare_output($answer,&get_logfile(1));
-
-if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for"))
-{
+if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) {
$test_passed = 0;
}
+&compare_output($answer,&get_logfile(1));
+
1;
diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C
index 3f2b3a1..f31238f 100644
--- a/tests/scripts/options/dash-C
+++ b/tests/scripts/options/dash-C
@@ -33,6 +33,10 @@ chdir $workdir;
$wpath = &get_this_pwd;
chdir $pwd;
+if (-f $example) {
+ $test_passed = 0;
+}
+
# Create the answer to what should be produced by this Makefile
$answer = "$make_name: Entering directory `$wpath'\n"
. "$delete_command EXAMPLE_FILE\n"
@@ -40,9 +44,4 @@ $answer = "$make_name: Entering directory `$wpath'\n"
&compare_output($answer,&get_logfile(1));
-if (-f $example)
-{
- $test_passed = 0;
-}
-
1;
diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k
index fe5689e..d87a786 100644
--- a/tests/scripts/options/dash-k
+++ b/tests/scripts/options/dash-k
@@ -97,4 +97,18 @@ $make_name: Target `all' not remade because of errors.\n";
&compare_output($answer, &get_logfile(1));
+# TEST -- make sure we keep the error code if we can't create an included
+# makefile.
+
+run_make_test('all: ; @echo hi
+include ifile
+ifile: no-such-file; @false
+',
+ '-k',
+ "#MAKEFILE#:2: ifile: No such file or directory
+#MAKE#: *** No rule to make target `no-such-file', needed by `ifile'.
+#MAKE#: Failed to remake makefile `ifile'.
+hi\n",
+ 512);
+
1;
diff --git a/tests/scripts/targets/FORCE b/tests/scripts/targets/FORCE
index 90ee48d..befb326 100644
--- a/tests/scripts/targets/FORCE
+++ b/tests/scripts/targets/FORCE
@@ -1,4 +1,4 @@
-$description = "The following tests rules without Commands or Dependencies.";
+$description = "The following tests rules without Commands or Dependencies.";
$details = "If the rule ...\n";
@@ -17,7 +17,7 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE ".IGNORE :\n";
print MAKEFILE "clean: FORCE\n";
-print MAKEFILE "\t$delete_command clean\n";
+print MAKEFILE "\t$delete_command clean\n";
print MAKEFILE "FORCE:\n";
# END of Contents of MAKEFILE
@@ -26,20 +26,15 @@ close(MAKEFILE);
# Create a file named "clean". This is the same name as the target clean
-# and tricks the target into thinking that it is up to date. (Unless you
+# and tricks the target into thinking that it is up to date. (Unless you
# use the .PHONY target.
&touch("clean");
$answer = "$delete_command clean\n";
&run_make_with_options($makefile,"clean",&get_logfile);
-&compare_output($answer,&get_logfile(1));
+&compare_output($answer,&get_logfile(1));
-if (-f $example)
-{
- $test_passed = 0;
-}
-
1;
diff --git a/tests/scripts/targets/PHONY b/tests/scripts/targets/PHONY
index 14d5ae1..dd46b3f 100644
--- a/tests/scripts/targets/PHONY
+++ b/tests/scripts/targets/PHONY
@@ -27,7 +27,7 @@ print MAKEFILE ".PHONY : clean \n";
print MAKEFILE "all: \n";
print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n";
print MAKEFILE "clean: \n";
-print MAKEFILE "\t$delete_command $example clean\n";
+print MAKEFILE "\t$delete_command $example clean\n";
# END of Contents of MAKEFILE
@@ -36,20 +36,19 @@ close(MAKEFILE);
&touch($example);
# Create a file named "clean". This is the same name as the target clean
-# and tricks the target into thinking that it is up to date. (Unless you
+# and tricks the target into thinking that it is up to date. (Unless you
# use the .PHONY target.
&touch("clean");
$answer = "$delete_command $example clean\n";
&run_make_with_options($makefile,"clean",&get_logfile);
-&compare_output($answer,&get_logfile(1));
-
-if (-f $example)
-{
- $test_passed = 0;
+if (-f $example) {
+ $test_passed = 0;
}
-
+
+&compare_output($answer,&get_logfile(1));
+
1;
diff --git a/tests/scripts/targets/SILENT b/tests/scripts/targets/SILENT
index 375cad4..5f9a1db 100644
--- a/tests/scripts/targets/SILENT
+++ b/tests/scripts/targets/SILENT
@@ -22,7 +22,7 @@ open(MAKEFILE,"> $makefile");
print MAKEFILE ".SILENT : clean\n";
print MAKEFILE "clean: \n";
-print MAKEFILE "\t$delete_command EXAMPLE_FILE\n";
+print MAKEFILE "\t$delete_command EXAMPLE_FILE\n";
# END of Contents of MAKEFILE
@@ -32,13 +32,11 @@ close(MAKEFILE);
$answer = "";
&run_make_with_options($makefile,"clean",&get_logfile,0);
-
-&compare_output($answer,&get_logfile(1));
-if (-f $example)
-{
- $test_passed = 0;
+if (-f $example) {
+ $test_passed = 0;
}
-
+&compare_output($answer,&get_logfile(1));
+
1;
diff --git a/tests/scripts/targets/clean b/tests/scripts/targets/clean
index 69f4fd1..b32c976 100644
--- a/tests/scripts/targets/clean
+++ b/tests/scripts/targets/clean
@@ -33,11 +33,10 @@ $answer = "This makefile did not clean the dir... good\n";
$answer = "$delete_command $example\n";
&run_make_with_options($makefile,"clean",&get_logfile,0);
-
-&compare_output($answer,&get_logfile(1)) || &error ("abort");
if (-f $example) {
- $test_passed = 0;
+ $test_passed = 0;
}
+&compare_output($answer,&get_logfile(1)) || &error ("abort");
1;
diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special
index 58c8655..77b355c 100644
--- a/tests/scripts/variables/special
+++ b/tests/scripts/variables/special
@@ -4,12 +4,7 @@ $description = "Test special GNU make variables.";
$details = "";
-$makefile2 = &get_tmpfile;
-
-
-open(MAKEFILE, "> $makefile");
-
-print MAKEFILE <<'EOF';
+&run_make_test('
X1 := $(sort $(filter FOO BAR,$(.VARIABLES)))
@@ -23,21 +18,12 @@ all:
@echo X1 = $(X1)
@echo X2 = $(X2)
@echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES)))
-
-EOF
-
-close(MAKEFILE);
-
-# TEST #1
-# -------
-
-&run_make_with_options($makefile, "", &get_logfile);
-$answer = "X1 =\nX2 = FOO\nLAST = BAR FOO\n";
-&compare_output($answer, &get_logfile(1));
-
+',
+ '', "X1 =\nX2 = FOO\nLAST = BAR FOO\n");
+# $makefile2 = &get_tmpfile;
# open(MAKEFILE, "> $makefile2");
# print MAKEFILE <<'EOF';
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index 0ddb884..0bca669 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -28,6 +28,10 @@ $tests_run = 0;
# The number of tests in this category that have passed
$tests_passed = 0;
+
+# Yeesh. This whole test environment is such a hack!
+$test_passed = 1;
+
sub toplevel
{
# Get a clean environment
@@ -376,7 +380,7 @@ sub run_each_test
foreach $testname (sort @TESTS)
{
++$categories_run;
- $passed = 1; # reset by test on failure
+ $suite_passed = 1; # reset by test on failure
$num_of_logfiles = 0;
$num_of_tmpfiles = 0;
$description = "";
@@ -423,7 +427,7 @@ sub run_each_test
# How did it go?
if (!defined($code))
{
- $passed = 0;
+ $suite_passed = 0;
if (length ($@))
{
warn "\n*** Test died ($testname): $@\n";
@@ -434,14 +438,14 @@ sub run_each_test
}
}
elsif ($code == -1) {
- $passed = 0;
+ $suite_passed = 0;
}
elsif ($code != 1 && $code != -1) {
- $passed = 0;
+ $suite_passed = 0;
warn "\n*** Test returned $code\n";
}
- if ($passed) {
+ if ($suite_passed) {
++$categories_passed;
$status = "ok ($tests_passed passed)";
for ($i = $num_of_tmpfiles; $i; $i--)
@@ -608,10 +612,7 @@ sub compare_output
local($answer,$logfile) = @_;
local($slurp);
- if ($debug)
- {
- print "Comparing Output ........ ";
- }
+ print "Comparing Output ........ " if $debug;
$slurp = &read_file_into_string ($logfile);
@@ -622,34 +623,28 @@ sub compare_output
++$tests_run;
- if ($slurp eq $answer)
+ if ($slurp eq $answer && $test_passed)
{
- if ($debug)
- {
- print "ok\n";
- }
+ print "ok\n" if $debug;
++$tests_passed;
return 1;
}
- else
- {
- if ($debug)
- {
- print "DIFFERENT OUTPUT\n";
- }
- $passed = 0;
+
+ if ($slurp ne $answer) {
+ print "DIFFERENT OUTPUT\n" if $debug;
+
&create_file (&get_basefile, $answer);
- if ($debug)
- {
- print "\nCreating Difference File ...\n";
- }
+ print "\nCreating Difference File ...\n" if $debug;
+
# Create the difference file
local($command) = "diff -c " . &get_basefile . " " . $logfile;
&run_command_with_output(&get_difffile,$command);
- return 0;
}
+
+ $suite_passed = 0;
+ return 0;
}
sub read_file_into_string