Add -B option docs.
Add .VARIABLES variable.
Add a few new tests.
Add a new translation: Swedish
+2002-08-02 Paul D. Smith <psmith@gnu.org>
+
+ * NEWS: Remove the mention of .TARGETS; we aren't going to publish
+ this one because it's too hard to get right. We'll look at it for
+ a future release.
+
2002-08-01 Paul D. Smith <psmith@gnu.org>
- Add new introspection variables .VARIABLES and .TARGETS.
+ * main.c (switches): Add a new option, -B (--always-make). If
+ specified, make will rebuild all targets that it encounters even
+ if they don't appear to be out of date.
+ (always_make_flag): New flag.
+ * make.h: Extern always_make_flag.
+ * remake.c (update_file_1): Check always_make_flag; if it's set we
+ will always rebuild any target we can, even if none of its
+ prerequisites are newer.
+ * NEWS: Mention it.
+
+ * doc/make.texi (Shell Function): Make it clear that make
+ variables marked as "export" are not passed to instances of the
+ shell function.
+
+ Add new introspection variable .VARIABLES and .TARGETS.
* variable.c (handle_special_var): New function. If the variable
reference passed in is "special" (.VARIABLES or .TARGETS),
(target_environment): Use the "exportable" flag instead of
re-checking the name here... an efficiency improvement.
+2002-07-31 Paul D. Smith <psmith@gnu.org>
+
+ * config.h-vms.template: Updates to build on VMS. Thanks to
+ Brian_Benning@aksteel.com for helping verify the build.
+ * makefile.com: Build the new hash.c file.
+ * hash.h: Use strcpmi(), not stricmp(), in the
+ HAVE_CASE_INSENSITIVE_FS case.
+
+2002-07-30 Paul D. Smith <psmith@gnu.org>
+
+ * hash.h (ISTRING_COMPARE, return_ISTRING_COMPARE): Add missing
+ backslashes to the HAVE_CASE_INSENSITIVE_FS case.
+ Reported by <Brian_Benning@aksteel.com>.
+
2002-07-10 Paul D. Smith <psmith@gnu.org>
* variable.c (pop_variable_scope): Remove variable made unused by
list when a makefile is just being read (before any includes) is the
name of the current makefile.
-* GNU make now supports some simple introspection capability: two new
- built-in variables are defined: $(.VARIABLES) and $(.TARGETS). These
- expand to a complete list of variables and targets, respectively,
- defined by all makefiles at the time the variables are expanded.
+* A new built-in variable is defined: $(.VARIABLES). When it is
+ expanded it returns a complete list of variable names defined by all
+ makefiles at that moment.
+
+* A new command-line option is defined, -B or --always-make. If
+ specified GNU make will consider all targets out-of-date even if they
+ would otherwise not be.
* The arguments to $(call ...) functions were being stored in $1, $2,
etc. as recursive variables, even though they are fully expanded
/* #undef _ALL_SOURCE */
#endif
-/* Define if using alloca.c. */
-/* #undef C_ALLOCA */
-/* maybe this should be placed into make.h */
-#if defined(__VAX) && defined(__DECC)
-#define alloca(n) __ALLOCA(n)
-#endif
-
/* Define to 1 if NLS is requested. */
/* #undef ENABLE_NLS */
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
+/* Use high resolution file timestamps if nonzero. */
+#define FILE_TIMESTAMP_HI_RES 0
+
/* Define for case insensitve filenames */
#define HAVE_CASE_INSENSITIVE_FS 1
#define PARAMS(protos) ()
#endif /* C++ or ANSI C. */
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+/* maybe this should be placed into make.h */
+#if defined(__VAX) && defined(__DECC)
+#define alloca(n) __ALLOCA(n)
+#endif
+
/* Build host information. */
#define MAKE_HOST "VMS"
if (dc->dirstream == 0)
/* Couldn't open the directory. Mark this by
setting the `files' member to a nil pointer. */
- hash_free (&dc->dirfiles, 0);
+ dc->dirfiles.ht_vec = 0;
else
{
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
Boston, MA 02111-1307 USA @*
ISBN @value{ISBN} @*
-Maintenance and updates since Version 3.76 by Paul D. Smith.
-
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the section entitled
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+Texts being ``A GNU Manual'', and with the Back-Cover Texts being as in
+(a) below. A copy of the license is included in the section entitled
``GNU Free Documentation License''.
+
+(a) The FSF's Back-Cover Text is:
+
+@quotation
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end quotation
@sp 2
Cover art by Etienne Suvasa.
@end titlepage
@cindex makefiles, and special variables
@cindex special variables
-GNU @code{make} also supports two other special variables. Note that
-any value you assign to these variables will be ignored; they will
-always return their special value.
+GNU @code{make} also supports a special variable. Note that any value
+you assign to this variable will be ignored; it will always return its
+special value.
@vindex $(.VARIABLES)
@vindex .VARIABLES @r{(list of variables)}
does not include any variables which are only defined in a
target-specific context.
-@vindex $(.TARGETS)
-@vindex .TARGETS @r{(list of targets)}
-The second special variable is @code{.TARGETS}. When expanded, the
-value consists of a list of all targets defined in all makefiles read
-up until that point. Note it's not enough for a file to be simply
-mentioned in the makefile to be listed in this variable, even if it
-would match an implicit rule and become an ``implicit target''. The
-file must appear as a target, on the left-hand side of a ``:'', to be
-considered a target for the purposes of this variable.
+@c @vindex $(.TARGETS)
+@c @vindex .TARGETS @r{(list of targets)}
+@c The second special variable is @code{.TARGETS}. When expanded, the
+@c value consists of a list of all targets defined in all makefiles read
+@c up until that point. Note it's not enough for a file to be simply
+@c mentioned in the makefile to be listed in this variable, even if it
+@c would match an implicit rule and become an ``implicit target''. The
+@c file must appear as a target, on the left-hand side of a ``:'', to be
+@c considered a target for the purposes of this variable.
@node Remaking Makefiles, Overriding Makefiles, Special Variables, Makefiles
@section How Makefiles Are Remade
thing in the result.@refill
The commands run by calls to the @code{shell} function are run when the
-function calls are expanded. In most cases, this is when the makefile is
-read in. The exception is that function calls in the commands of the rules
-are expanded when the commands are run, and this applies to @code{shell}
-function calls like all others.
+function calls are expanded (@pxref{Reading Makefiles, , How
+@code{make} Reads a Makefile}). Because this function involves
+spawning a new shell, you should carefully consider the performance
+implications of using the @code{shell} function within recursively
+expanded variables vs. simply expanded variables (@pxref{Flavors, ,The
+Two Flavors of Variables}).
Here are some examples of the use of the @code{shell} function:
@cindex @code{-m}
These options are ignored for compatibility with other versions of @code{make}.
+@item -B
+@cindex @code{-B}
+@itemx --always-make
+@cindex @code{--always-make}
+Consider all targets out-of-date. GNU @code{make} proceeds to
+consider targets and their prerequisites using the normal algorithms;
+however, all these targets are remade, regardless of the status of
+their prerequisites.
+
@item -C @var{dir}
@cindex @code{-C}
@itemx --directory=@var{dir}
} while (0)
#define ISTRING_COMPARE(X, Y, RESULT) do { \
- _RESULT_ = stricmp ((X), (Y));
+ _RESULT_ = strcmpi ((X), (Y)); \
} while (0)
#define return_ISTRING_COMPARE(X, Y) do { \
- return stricmp ((X), (Y));
+ return strcmpi ((X), (Y)); \
} while (0)
#else
for each reference to an undefined variable. */
int warn_undefined_variables_flag;
+
+/* If nonzero, always build all targets, regardless of whether
+ they appear out of date or not. */
+
+int always_make_flag = 0;
\f
/* The table of command switches. */
{ 'b', ignore, 0, 0, 0, 0, 0, 0,
0, 0,
N_("Ignored for compatibility") },
+ { 'B', flag, (char *) &always_make_flag, 1, 1, 0, 0, 0,
+ "always-make", 0,
+ N_("Unconditionally make all targets") },
{ 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
"directory", N_("DIRECTORY"),
N_("Change to DIRECTORY before doing anything") },
#endif
/* Initialize the special variables. */
- define_variable (".VARIABLES", 10, "", o_default, 0);
- define_variable (".TARGETS", 8, "", o_default, 0);
+ define_variable (".VARIABLES", 10, "", o_default, 0)->special = 1;
+ /* define_variable (".TARGETS", 8, "", o_default, 0); */
/* Read in variables from the environment. It is important that this be
done before $(MAKE) is figured out so its definitions will not be
# include <unixlib.h>
# include <unixio.h>
# include <perror.h>
+/* Needed to use alloca on VMS. */
+# include <builtins.h>
#endif
#ifndef __attribute__
extern char **environ;
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
-extern int print_data_base_flag, question_flag, touch_flag;
+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;
$ else
$ lopt = ""
$ endif
-$ filelist = "alloca ar arscan commands default dir expand file function implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt1 getopt"
+$ filelist = "alloca ar arscan commands default dir expand file function hash implicit job main misc read remake remote-stub rule signame variable version vmsfunctions vmsify vpath [.glob]glob [.glob]fnmatch getopt1 getopt"
$ copy config.h-vms config.h
$ n=0
$ open/write optf make.opt
+2002-08-02 Paul D. Smith <psmith@gnu.org>
+
+ * LINGUAS: Add a new translation for Swedish (sv).
+
2002-04-21 Paul D. Smith <psmith@gnu.org>
* LINGUAS, hr.po: Added new translation: Croatian.
* .cvsignore: Moved from i18n to here.
* POTFILES.in, LINGUAS, Makevars: Created.
-
-2002-04-21 gettextize <bug-gnu-gettext@gnu.org>
-
- * Makefile.in.in: New file, from gettext-0.11.1.
- * Rules-quot: New file, from gettext-0.11.1.
- * boldquot.sed: New file, from gettext-0.11.1.
- * en@boldquot.header: New file, from gettext-0.11.1.
- * en@quot.header: New file, from gettext-0.11.1.
- * insert-header.sin: New file, from gettext-0.11.1.
- * quot.sed: New file, from gettext-0.11.1.
- * remove-potcdate.sin: New file, from gettext-0.11.1.
-
# Set of available languages: 14 languages
-da de es fr gl he hr ja ko nl pl pt_BR ru tr
+da de es fr gl he hr ja ko nl pl pt_BR sv ru tr
# Can't seem to get en@quot and en@boldquot to build properly?
reading_file = curfile;
- free(ebuf.bufstart);
+ fclose (ebuf.fp);
+
+ free (ebuf.bufstart);
return r;
}
if (ferror (ebuf->fp))
pfatal_with_name (ebuf->floc.filenm);
- return nlines ? nlines : -1;
+ /* If we found some lines, return how many.
+ If we didn't, but we did find _something_, that indicates we read the last
+ line of a file with no final newline; return 1.
+ If we read nothing, we're at EOF; return -1. */
+
+ return nlines ? nlines : p == ebuf->bufstart ? -1 : 1;
}
\f
/* Parse the next "makefile word" from the input buffer, and return info
int dep_status = 0;
register struct dep *d, *lastd;
int running = 0;
- int maybe_make;
DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
while (d != 0)
{
FILE_TIMESTAMP mtime;
+ int maybe_make;
check_renamed (d->file);
/* Now we know whether this target needs updating.
If it does, update all the intermediate files we depend on. */
- if (must_make)
+ if (must_make || always_make_flag)
{
for (d = file->deps; d != 0; d = d->next)
if (d->file->intermediate)
file->update_status = dep_status;
notice_finished_file (file);
- depth--;
+ --depth;
DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n"));
file's bookkeeping (updated, but not_started is bogus state). */
set_command_state (file, cs_not_started);
- /* Now record which dependencies are more
+ /* Now record which prerequisites are more
recent than this file, so we can define $?. */
deps_changed = 0;
DBF (DB_BASIC,
_("Target `%s' is double-colon and has no prerequisites.\n"));
}
- else if (!noexist && file->is_target && !deps_changed && file->cmds == 0)
+ else if (!noexist && file->is_target && !deps_changed && file->cmds == 0
+ && !always_make_flag)
{
must_make = 0;
DBF (DB_VERBOSE,
_("No commands for `%s' and no prerequisites actually changed.\n"));
}
+ else if (!must_make && file->cmds != 0 && always_make_flag)
+ {
+ must_make = 1;
+ DBF (DB_VERBOSE, _("Making `%s' due to always-make flag.\n"));
+ }
if (!must_make)
{
{
struct dep *d;
int dep_status = 0;
- int maybe_make;
++depth;
start_updating (file);
recent than the file on whose behalf we are checking. */
else
{
- register struct dep *lastd;
+ struct dep *lastd;
lastd = 0;
d = file->deps;
while (d != 0)
{
+ int maybe_make;
+
if (is_updating (d->file))
{
error (NILF, _("Circular %s <- %s dependency dropped."),
+2002-08-07 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/misc/general3: Add a test for makefiles that don't end
+ in newlines.
+
+ * scripts/variables/special: Create tests for the special
+ variables (.VARIABLES and .TARGETS). Comment out .TARGETS test
+ for now as it's not yet supported.
+
+2002-08-01 Paul D. Smith <psmith@gnu.org>
+
+ * scripts/options/dash-B: Add a test for the new -B option.
+
2002-07-11 Paul D. Smith <psmith@gnu.org>
* run_make_tests.pl (valid_option): Add support for Valgrind
which have either broken at some point in the past or seem likely to
break.";
+$makefile2 = &get_tmpfile;
+
open(MAKEFILE,"> $makefile");
# The contents of the Makefile ...
print MAKEFILE <<EOF;
-\# We want to allow both empty commands _and_ commands that resolve to empty.
+# We want to allow both empty commands _and_ commands that resolve to empty.
EMPTY =
.PHONY: all a1 a2 a3 a4
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile);
-
-# Create the answer to what should be produced by this Makefile
$answer = "$make_name: Nothing to be done for `all'.\n";
+&compare_output($answer,&get_logfile(1));
+
+
+# TEST 2
+# Make sure files without trailing newlines are handled properly.
+
+open(MAKEFILE, "> $makefile2");
+print MAKEFILE "all:;\@echo FOO = \$(FOO)\nFOO = foo";
+close(MAKEFILE);
+
+&run_make_with_options($makefile2,"",&get_logfile);
+$answer = "FOO = foo\n";
&compare_output($answer,&get_logfile(1));
+
1;
--- /dev/null
+# -*-perl-*-
+
+$description = "Test make -B (always remake) option.\n";
+
+$details = "\
+Construct a simple makefile that builds a target.
+Invoke make once, so it builds everything. Invoke it again and verify
+that nothing is built. Then invoke it with -B and verify that everything
+is built again.";
+
+open(MAKEFILE,"> $makefile");
+
+print MAKEFILE <<'EOF';
+.SUFFIXES:
+
+.PHONY: all
+all: foo
+
+foo: bar.x
+ @echo cp $< $@
+ @touch $@
+EOF
+
+close(MAKEFILE);
+
+
+&touch('bar.x');
+
+&run_make_with_options($makefile, '', &get_logfile);
+$answer = "cp bar.x foo\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile, '', &get_logfile);
+$answer = "$make_name: Nothing to be done for `all'.\n";
+&compare_output($answer, &get_logfile(1));
+
+&run_make_with_options($makefile, '-B', &get_logfile);
+$answer = "cp bar.x foo\n";
+&compare_output($answer, &get_logfile(1));
+
+unlink('bar.x', 'foo') unless $keep;
+
+1;
--- /dev/null
+# -*-perl-*-
+
+$description = "Test special GNU make variables.";
+
+$details = "";
+
+$makefile2 = &get_tmpfile;
+
+
+open(MAKEFILE, "> $makefile");
+
+print MAKEFILE <<'EOF';
+
+X1 := $(sort $(filter FOO BAR,$(.VARIABLES)))
+
+FOO := foo
+
+X2 := $(sort $(filter FOO BAR,$(.VARIABLES)))
+
+BAR := bar
+
+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));
+
+
+
+
+# open(MAKEFILE, "> $makefile2");
+
+# print MAKEFILE <<'EOF';
+
+# X1 := $(sort $(.TARGETS))
+
+# all: foo
+# @echo X1 = $(X1)
+# @echo X2 = $(X2)
+# @echo LAST = $(sort $(.TARGETS))
+
+# X2 := $(sort $(.TARGETS))
+
+# foo:
+
+# EOF
+
+# close(MAKEFILE);
+
+# # TEST #2
+# # -------
+
+# &run_make_with_options($makefile2, "", &get_logfile);
+# $answer = "X1 =\nX2 = all\nLAST = all foo\n";
+# &compare_output($answer, &get_logfile(1));
+
+
+1;
\f
/* If the variable passed in is "special", handle its special nature.
Currently there are two such variables, both used for introspection:
- .MAKE_VARS expands to a list of all the variables defined in this instance
+ .VARIABLES expands to a list of all the variables defined in this instance
of make.
- .MAKE_TARGETS expands to a list of all the targets defined in this
+ .TARGETS expands to a list of all the targets defined in this
instance of make.
Returns the variable reference passed in. */
static unsigned long last_var_count = 0;
- if (streq (var->name, ".MAKE_TARGETS"))
+ /* This one actually turns out to be very hard, due to the way the parser
+ records targets. The way it works is that target information is collected
+ internally until make knows the target is completely specified. It unitl
+ it sees that some new construct (a new target or variable) is defined that
+ it knows the previous one is done. In short, this means that if you do
+ this:
+
+ all:
+
+ TARGS := $(.TARGETS)
+
+ then $(TARGS) won't contain "all", because it's not until after the
+ variable is created that the previous target is completed.
+
+ Changing this would be a major pain. I think a less complex way to do it
+ would be to pre-define the target files as soon as the first line is
+ parsed, then come back and do the rest of the definition as now. That
+ would allow $(.TARGETS) to be correct without a major change to the way
+ the parser works.
+
+ if (streq (var->name, ".TARGETS"))
var->value = build_target_list (var->value);
- else if (streq (var->name, ".MAKE_VARS")
+ else
+ */
+
+ if (streq (var->name, ".VARIABLES")
&& global_variable_set.table.ht_fill != last_var_count)
{
unsigned long max = EXPANSION_INCREMENT (strlen (var->value));
/* Make sure we have at least MAX bytes in the allocated buffer. */
var->value = xrealloc (var->value, max);
+ /* Walk through the hash of variables, constructing a list of names. */
p = var->value;
len = 0;
for (; vp < end; ++vp)
}
*(p-1) = '\0';
+ /* Remember how many variables are in our current count. Since we never
+ remove variables from the list, this is a reliable way to know whether
+ the list is up to date or needs to be recomputed. */
+
last_var_count = global_variable_set.table.ht_fill;
}
v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
if (v)
- return handle_special_var (v);
+ return v->special ? handle_special_var (v) : v;
}
#ifdef VMS
{
/* Paste the old and new values together in VALUE. */
- unsigned int oldlen, newlen;
+ unsigned int oldlen, vallen;
+ char *val;
- p = value;
+ val = value;
if (v->recursive)
/* The previous definition of the variable was recursive.
The new value is the unexpanded old and new values. */
when it was set; and from the expanded new value. Allocate
memory for the expansion as we may still need the rest of the
buffer if we're looking at a target-specific variable. */
- p = alloc_value = allocated_variable_expand (p);
+ val = alloc_value = allocated_variable_expand (val);
oldlen = strlen (v->value);
- newlen = strlen (p);
- p = (char *) alloca (oldlen + 1 + newlen + 1);
+ vallen = strlen (val);
+ p = (char *) alloca (oldlen + 1 + vallen + 1);
bcopy (v->value, p, oldlen);
p[oldlen] = ' ';
- bcopy (value, &p[oldlen + 1], newlen + 1);
+ bcopy (val, &p[oldlen + 1], vallen + 1);
}
}
}
unsigned int per_target:1; /* Nonzero if a target-specific variable. */
unsigned int append:1; /* Nonzero if an appending target-specific
variable. */
+ unsigned int special:1; /* Nonzero if this is a special variable. */
unsigned int expanding:1; /* Nonzero if currently being expanded. */
unsigned int exp_count:EXP_COUNT_BITS;
/* If >1, allow this many self-referential