* Put the host info in the --version output.
* Don't croak if the user forces -jN on submakes.
+1999-09-01 Paul D. Smith <psmith@gnu.org>
+
+ * configure.in (MAKE_HOST): Define it to be the canonical build
+ host info, now that we need AC_CANONICAL_HOST anyway (for large
+ file support).
+ * version.c (make_host): Define a variable to MAKE_HOST so we're
+ sure to get it from the local config.h.
+ * main.c (print_version): Use it in the version information.
+ * config.ami.template: Add MAKE_HOST.
+ * configh.dos.template: Ditto.
+ * config.h.W32.template: Ditto.
+ * config.h-vms.template: Ditto.
+
+ * main.c (main): Close the jobserver file descriptors if we need
+ to re-exec ourselves.
+ Also print more reasonable error if users force -jN for submakes.
+ This may be common for a while until people use the jobserver
+ feature. If it happens, we ignore the existing jobserver stuff
+ and use whatever they specified on the commandline.
+ (define_makeflags): Fixed a long-standing bug: if a long name
+ only option comes immediately after a single letter option with no
+ argument, then the option string is constructed incorrectly. For
+ example, with -w and --jobserver-fds you get "-w-jobserver-fds..."
+ instead of "-w --jobserver-fds..."; add in an extra " -".
+
+ * make.texinfo (Phony Targets): Add another example of using
+ .PHONY with subdirectories/recursive make.
+
1999-08-30 Paul D. Smith <psmith@gnu.org>
* README.W32.template: Renamed from README.W32 so it's
/* Define for Case Insensitve behavior */
#define HAVE_CASE_INSENSITIVE_FS
+
+/* Build host information. */
+#define MAKE_HOST "Amiga"
#define PARAMS(protos) ()
#endif /* C++ or ANSI C. */
+/* Build host information. */
+#define MAKE_HOST "VMS"
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
+/* Build host information. */
+#define MAKE_HOST "Windows32"
+
/*
* Refer to README.W32 for info on the following settings
*/
/* Define if you have the vprintf library function. */\r
#undef HAVE_VPRINTF\r
#define HAVE_VPRINTF 1\r
+\r
+/* Build host information. */\r
+#define MAKE_HOST "DOS (DJGPP)"\r
esac
+AC_DEFINE_UNQUOTED(MAKE_HOST,"$host",[Build host information.])
+
+
MAINT_MAKEFILE=/dev/null
if test -r "$srcdir/maintMakefile"; then
MAINT_MAKEFILE="$srcdir/maintMakefile"
if (jobserver_fds->idx > 1)
fatal (NILF, _("internal error: multiple --jobserver-fds options"));
- /* The combination of a pipe + !job_slots means we're using the
- jobserver. If !job_slots and we don't have a pipe, we can start
- infinite jobs. */
-
- if (job_slots != 0)
- fatal (NILF, _("internal error: --jobserver-fds unexpected"));
-
/* Now parse the fds string and make sure it has the proper format. */
cp = jobserver_fds->list[0];
fatal (NILF,
_("internal error: invalid --jobserver-fds string `%s'"), cp);
+ /* The combination of a pipe + !job_slots means we're using the
+ jobserver. If !job_slots and we don't have a pipe, we can start
+ infinite jobs. If we see both a pipe and job_slots >0 that means the
+ user set -j explicitly. This is broken; in this case obey the user
+ (ignore the jobserver pipe for this make) but print a message. */
+
+ if (job_slots > 0)
+ error (NILF, _("warning: -jN set for submakes: ignoring jobserver."));
+
/* Create a duplicate pipe, that will be closed in the SIGCHLD
handler. If this fails with EBADF, the parent has closed the pipe
on us because it didn't think we were a submake. If so, print a
warning then default to -j1. */
- if ((job_rfd = dup (job_fds[0])) < 0)
+ else if ((job_rfd = dup (job_fds[0])) < 0)
{
if (errno != EBADF)
pfatal_with_name (_("dup jobserver"));
error (NILF,
_("warning: jobserver unavailable (using -j1). Add `+' to parent make rule."));
job_slots = 1;
+ }
+
+ if (job_slots > 0)
+ {
+ close (job_fds[0]);
+ close (job_fds[1]);
job_fds[0] = job_fds[1] = -1;
free (jobserver_fds->list);
free (jobserver_fds);
/* If we have >1 slot but no jobserver-fds, then we're a top-level make.
Set up the pipe and install the fds option for our children. */
- else if (job_slots > 1)
+ if (job_slots > 1)
{
char c = '+';
fflush (stdout);
fflush (stderr);
+ /* Close the jobserver pipes if we opened any. */
+ if (job_fds[0] >= 0)
+ {
+ close (job_fds[0]);
+ close (job_fds[1]);
+ }
+ if (job_rfd >= 0)
+ close (job_rfd);
+
#ifndef _AMIGA
exec_command (nargv, environ);
#else
while (flags != 0)
{
/* Add the flag letter or name to the string. */
- if (!short_option (flags->cs->c))
+ if (short_option (flags->cs->c))
+ *p++ = flags->cs->c;
+ else
{
+ if (*p != '-')
+ {
+ *p++ = ' ';
+ *p++ = '-';
+ }
*p++ = '-';
strcpy (p, flags->cs->long_name);
p += strlen (p);
}
- else
- *p++ = flags->cs->c;
if (flags->arg != 0)
{
/* A flag that takes an optional argument which in this case is
static void
print_version ()
{
+ extern char *make_host;
static int printed_version = 0;
char *precede = print_data_base_flag ? "# " : "";
/* Do it only once. */
return;
- printf ("%sGNU Make version %s", precede, version_string);
+ printf ("%sGNU Make %s (%s)", precede, version_string, make_host);
if (remote_description != 0 && *remote_description != '\0')
printf ("-%s", remote_description);
@end group
@end example
+Another example of the usefulness of phony targets is in conjunction
+with recursive invocations of @code{make}. In this case the makefile
+will often contain a variable which lists a number of subdirectories to
+be built. One way to handle this is with one rule whose command is a
+shell loop over the subdirectories, like this:
+
+@example
+@group
+SUBDIRS = foo bar baz
+
+subdirs:
+ for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir; \
+ done
+@end group
+@end example
+
+There are a few of problems with this method, however. First, any error
+detected in a submake is not noted by this rule, so it will continue to
+build the rest of the directories even when one fails. This can be
+overcome by adding shell commands to note the error and exit, but then
+it will do so even if @code{make} is invoked with the @code{-k} option,
+which is unfortunate. Second, and perhaps more importantly, you cannot
+take advantage of the parallel build capabilities of make using this
+method, since there is only one rule.
+
+By declaring the subdirectories as phony targets (you must do this as
+the subdirectory obviously always exists; otherwise it won't be built)
+you can remove these problems:
+
+@example
+@group
+SUBDIRS = foo bar baz
+
+.PHONY: subdirs $(SUBDIRS)
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+ $(MAKE) -C $@
+
+foo: baz
+@end group
+@end example
+
+Here we've also declared that the @file{foo} subdirectory cannot be
+built until after the @file{baz} subdirectory is complete; this kind of
+relationship declaration is particularly important when attempting
+parallel builds.
+
A phony target should not be a prerequisite of a real target file; if it
is, its commands are run every time @code{make} goes to update that
file. As long as a phony target is never a prerequisite of a real
(which it would do because make.h was found in $srcdir). */
#include <config.h>
+#ifndef MAKE_HOST
+# define MAKE_HOST "unknown"
+#endif
+
char *version_string = VERSION;
+char *make_host = MAKE_HOST;
\f
/*
Local variables: