+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
.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
static void
set_file_variables (struct file *file)
{
+ struct dep *d;
char *at, *percent, *star, *less;
#ifndef NO_ARCHIVES
}
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.
char *caret_value;
char *qp;
char *bp;
- struct dep *d;
unsigned int len;
/* Compute first the value for $+, which is supposed to contain
[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
#ifdef VMS
#ifdef __ALPHA
"ARCH", "ALPHA",
-#else
+#endif
+#ifdef __ia64
+ "ARCH", "IA64",
+#endif
+#ifdef __VAX
"ARCH", "VAX",
#endif
"AR", "library/obj",
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 *));
@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
@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
* 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.
@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
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
@end group
@group
+.PHONY: install
install: all
$(INSTALL) tar $(bindir)/$(binprefix)tar
-test ! -f rmt || $(INSTALL) rmt /etc/rmt
@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' \
@end group
@group
+.PHONY: dist
dist: $(SRCS) $(AUX)
echo tar-`sed \
-e '/version_string/!d' \
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)
{
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."));
/* 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
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";
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;
}
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,
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;
}
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",
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
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;
}
}
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;
+
\f
/* The usage output. We write it this way to make life easier for the
translators, especially those trying to translate to right-to-left
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);
char **nargv = argv;
int nargc = argc;
int orig_db_level = db_level;
+ int status;
if (! ISDB (DB_MAKEFILES))
db_level = DB_NONE;
/* 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
mtime = file_mtime_no_search (d->file);
any_remade |= (mtime != NONEXISTENT_MTIME
&& mtime != makefile_mtimes[i]);
+ makefile_status = MAKE_FAILURE;
}
}
else
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. */
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;
# 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
#
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
clean:
$$ purge [...]
-$(RM) make.exe;,*.obj;
- -$(RM) *.opt;
-$(RM) [.glob]*.obj;
# Automatically generated dependencies.
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. */
+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.
+\f
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
\f
/* 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. */
unsigned int ocommands_started;
int x;
check_renamed (file);
- if (makefiles)
+ if (rebuilding_makefiles)
{
if (file->cmd_target)
{
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
matter how much more we run, since we already know
the answer to return. */
stop = (!keep_going_flag && !question_flag
- && !makefiles);
+ && !rebuilding_makefiles);
}
else
{
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;
}
/* 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. */
considered = !considered;
}
- if (makefiles)
+ if (rebuilding_makefiles)
{
touch_flag = t;
question_flag = q;
/* 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;
}
\f
+/* 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
{
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;
}
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;
}
}
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
# -------
&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
# -------
&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)
&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");
&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;
$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.";
$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;
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;
&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;
$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"
&compare_output($answer,&get_logfile(1));
-if (-f $example)
-{
- $test_passed = 0;
-}
-
1;
&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;
-$description = "The following tests rules without Commands or Dependencies.";
+$description = "The following tests rules without Commands or Dependencies.";
$details = "If the rule ...\n";
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
# 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;
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
&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;
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
$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;
$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;
$details = "";
-$makefile2 = &get_tmpfile;
-
-
-open(MAKEFILE, "> $makefile");
-
-print MAKEFILE <<'EOF';
+&run_make_test('
X1 := $(sort $(filter FOO BAR,$(.VARIABLES)))
@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';
# 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
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 = "";
# How did it go?
if (!defined($code))
{
- $passed = 0;
+ $suite_passed = 0;
if (length ($@))
{
warn "\n*** Test died ($testname): $@\n";
}
}
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--)
local($answer,$logfile) = @_;
local($slurp);
- if ($debug)
- {
- print "Comparing Output ........ ";
- }
+ print "Comparing Output ........ " if $debug;
$slurp = &read_file_into_string ($logfile);
++$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