Incorporate some VMS fixes.

Add -B option docs.
Add .VARIABLES variable.
Add a few new tests.
Add a new translation: Swedish
This commit is contained in:
Paul Smith 2002-08-08 00:11:19 +00:00
parent bccb277dda
commit f2ceb0d68a
19 changed files with 318 additions and 77 deletions

View File

@ -1,6 +1,26 @@
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),
@ -23,6 +43,20 @@
(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

11
NEWS
View File

@ -44,10 +44,13 @@ Version 3.80
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

View File

@ -9,13 +9,6 @@
/* #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 */
@ -345,6 +338,9 @@
/* 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
@ -396,5 +392,12 @@
#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"

2
dir.c
View File

@ -546,7 +546,7 @@ find_directory (name)
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,

View File

@ -68,14 +68,21 @@ Published by the Free Software Foundation @*
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
@ -1240,9 +1247,9 @@ variable definitions.
@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)}
@ -1254,15 +1261,15 @@ variables which have empty values, as well as built-in 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
@ -6542,10 +6549,12 @@ removes the trailing (carriage-return and) newline, if it's the last
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:
@ -7093,6 +7102,15 @@ Here is a table of all the options @code{make} understands:
@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}

4
hash.h
View File

@ -173,10 +173,10 @@ extern void *hash_deleted_item;
} 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

12
main.c
View File

@ -252,6 +252,11 @@ static int print_usage_flag = 0;
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;
/* The table of command switches. */
@ -260,6 +265,9 @@ static const struct command_switch 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") },
@ -989,8 +997,8 @@ int main (int argc, char ** argv)
#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

4
make.h
View File

@ -194,6 +194,8 @@ extern unsigned int get_path_max PARAMS ((void));
# include <unixlib.h>
# include <unixio.h>
# include <perror.h>
/* Needed to use alloca on VMS. */
# include <builtins.h>
#endif
#ifndef __attribute__
@ -485,7 +487,7 @@ extern const struct floc *reading_file;
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;

View File

@ -49,7 +49,7 @@ $ lopt = "/debug"
$ 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

View File

@ -1,3 +1,7 @@
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.
@ -7,15 +11,3 @@
* .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.

View File

@ -1,5 +1,5 @@
# 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?

11
read.c
View File

@ -380,7 +380,9 @@ eval_makefile (filename, flags)
reading_file = curfile;
free(ebuf.bufstart);
fclose (ebuf.fp);
free (ebuf.bufstart);
return r;
}
@ -2564,7 +2566,12 @@ readline (ebuf)
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;
}
/* Parse the next "makefile word" from the input buffer, and return info

View File

@ -350,7 +350,6 @@ update_file_1 (file, depth)
int dep_status = 0;
register struct dep *d, *lastd;
int running = 0;
int maybe_make;
DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
@ -437,6 +436,7 @@ update_file_1 (file, depth)
while (d != 0)
{
FILE_TIMESTAMP mtime;
int maybe_make;
check_renamed (d->file);
@ -492,7 +492,7 @@ update_file_1 (file, depth)
/* 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)
@ -544,7 +544,7 @@ update_file_1 (file, depth)
file->update_status = dep_status;
notice_finished_file (file);
depth--;
--depth;
DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n"));
@ -567,7 +567,7 @@ update_file_1 (file, depth)
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;
@ -636,12 +636,18 @@ update_file_1 (file, depth)
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)
{
@ -839,7 +845,6 @@ check_dep (file, depth, this_mtime, must_make_ptr)
{
struct dep *d;
int dep_status = 0;
int maybe_make;
++depth;
start_updating (file);
@ -888,12 +893,14 @@ check_dep (file, depth, this_mtime, must_make_ptr)
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."),

View File

@ -1,3 +1,16 @@
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

View File

@ -5,12 +5,14 @@ This tests random features of the parser that need to be supported, and
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
@ -36,10 +38,21 @@ EOF
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;

View File

@ -0,0 +1,43 @@
# -*-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;

View File

@ -0,0 +1,68 @@
# -*-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;

View File

@ -177,9 +177,9 @@ define_variable_in_set (name, length, value, origin, recursive, set, flocp)
/* 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. */
@ -192,10 +192,33 @@ handle_special_var (var)
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));
@ -207,6 +230,7 @@ handle_special_var (var)
/* 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)
@ -231,6 +255,10 @@ handle_special_var (var)
}
*(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;
}
@ -262,7 +290,7 @@ lookup_variable (name, length)
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
@ -814,9 +842,10 @@ do_variable_definition (flocp, varname, value, origin, flavor, target_var)
{
/* 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. */
@ -827,14 +856,14 @@ do_variable_definition (flocp, varname, value, origin, flavor, target_var)
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);
}
}
}

View File

@ -60,6 +60,7 @@ struct variable
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