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> 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 * variable.c (handle_special_var): New function. If the variable
reference passed in is "special" (.VARIABLES or .TARGETS), reference passed in is "special" (.VARIABLES or .TARGETS),
@ -23,6 +43,20 @@
(target_environment): Use the "exportable" flag instead of (target_environment): Use the "exportable" flag instead of
re-checking the name here... an efficiency improvement. 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> 2002-07-10 Paul D. Smith <psmith@gnu.org>
* variable.c (pop_variable_scope): Remove variable made unused by * 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 list when a makefile is just being read (before any includes) is the
name of the current makefile. name of the current makefile.
* GNU make now supports some simple introspection capability: two new * A new built-in variable is defined: $(.VARIABLES). When it is
built-in variables are defined: $(.VARIABLES) and $(.TARGETS). These expanded it returns a complete list of variable names defined by all
expand to a complete list of variables and targets, respectively, makefiles at that moment.
defined by all makefiles at the time the variables are expanded.
* 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, * The arguments to $(call ...) functions were being stored in $1, $2,
etc. as recursive variables, even though they are fully expanded etc. as recursive variables, even though they are fully expanded

View File

@ -9,13 +9,6 @@
/* #undef _ALL_SOURCE */ /* #undef _ALL_SOURCE */
#endif #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. */ /* Define to 1 if NLS is requested. */
/* #undef ENABLE_NLS */ /* #undef ENABLE_NLS */
@ -345,6 +338,9 @@
/* Define if you have the sun library (-lsun). */ /* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */ /* #undef HAVE_LIBSUN */
/* Use high resolution file timestamps if nonzero. */
#define FILE_TIMESTAMP_HI_RES 0
/* Define for case insensitve filenames */ /* Define for case insensitve filenames */
#define HAVE_CASE_INSENSITIVE_FS 1 #define HAVE_CASE_INSENSITIVE_FS 1
@ -396,5 +392,12 @@
#define PARAMS(protos) () #define PARAMS(protos) ()
#endif /* C++ or ANSI C. */ #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. */ /* Build host information. */
#define MAKE_HOST "VMS" #define MAKE_HOST "VMS"

2
dir.c
View File

@ -546,7 +546,7 @@ find_directory (name)
if (dc->dirstream == 0) if (dc->dirstream == 0)
/* Couldn't open the directory. Mark this by /* Couldn't open the directory. Mark this by
setting the `files' member to a nil pointer. */ setting the `files' member to a nil pointer. */
hash_free (&dc->dirfiles, 0); dc->dirfiles.ht_vec = 0;
else else
{ {
hash_init (&dc->dirfiles, DIRFILE_BUCKETS, hash_init (&dc->dirfiles, DIRFILE_BUCKETS,

View File

@ -68,14 +68,21 @@ Published by the Free Software Foundation @*
Boston, MA 02111-1307 USA @* Boston, MA 02111-1307 USA @*
ISBN @value{ISBN} @* 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 Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no any later version published by the Free Software Foundation; with the
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Invariant Sections being ``GNU General Public License'', the Front-Cover
Texts. A copy of the license is included in the section entitled 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''. ``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 @sp 2
Cover art by Etienne Suvasa. Cover art by Etienne Suvasa.
@end titlepage @end titlepage
@ -1240,9 +1247,9 @@ variable definitions.
@cindex makefiles, and special variables @cindex makefiles, and special variables
@cindex special variables @cindex special variables
GNU @code{make} also supports two other special variables. Note that GNU @code{make} also supports a special variable. Note that any value
any value you assign to these variables will be ignored; they will you assign to this variable will be ignored; it will always return its
always return their special value. special value.
@vindex $(.VARIABLES) @vindex $(.VARIABLES)
@vindex .VARIABLES @r{(list of 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 does not include any variables which are only defined in a
target-specific context. target-specific context.
@vindex $(.TARGETS) @c @vindex $(.TARGETS)
@vindex .TARGETS @r{(list of targets)} @c @vindex .TARGETS @r{(list of targets)}
The second special variable is @code{.TARGETS}. When expanded, the @c The second special variable is @code{.TARGETS}. When expanded, the
value consists of a list of all targets defined in all makefiles read @c 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 @c 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 @c mentioned in the makefile to be listed in this variable, even if it
would match an implicit rule and become an ``implicit target''. The @c 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 @c 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 considered a target for the purposes of this variable.
@node Remaking Makefiles, Overriding Makefiles, Special Variables, Makefiles @node Remaking Makefiles, Overriding Makefiles, Special Variables, Makefiles
@section How Makefiles Are Remade @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 thing in the result.@refill
The commands run by calls to the @code{shell} function are run when the 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 function calls are expanded (@pxref{Reading Makefiles, , How
read in. The exception is that function calls in the commands of the rules @code{make} Reads a Makefile}). Because this function involves
are expanded when the commands are run, and this applies to @code{shell} spawning a new shell, you should carefully consider the performance
function calls like all others. 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: 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} @cindex @code{-m}
These options are ignored for compatibility with other versions of @code{make}. 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} @item -C @var{dir}
@cindex @code{-C} @cindex @code{-C}
@itemx --directory=@var{dir} @itemx --directory=@var{dir}

4
hash.h
View File

@ -173,10 +173,10 @@ extern void *hash_deleted_item;
} while (0) } while (0)
#define ISTRING_COMPARE(X, Y, RESULT) do { \ #define ISTRING_COMPARE(X, Y, RESULT) do { \
_RESULT_ = stricmp ((X), (Y)); _RESULT_ = strcmpi ((X), (Y)); \
} while (0) } while (0)
#define return_ISTRING_COMPARE(X, Y) do { \ #define return_ISTRING_COMPARE(X, Y) do { \
return stricmp ((X), (Y)); return strcmpi ((X), (Y)); \
} while (0) } while (0)
#else #else

12
main.c
View File

@ -252,6 +252,11 @@ static int print_usage_flag = 0;
for each reference to an undefined variable. */ for each reference to an undefined variable. */
int warn_undefined_variables_flag; 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. */ /* The table of command switches. */
@ -260,6 +265,9 @@ static const struct command_switch switches[] =
{ 'b', ignore, 0, 0, 0, 0, 0, 0, { 'b', ignore, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
N_("Ignored for compatibility") }, 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, { 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
"directory", N_("DIRECTORY"), "directory", N_("DIRECTORY"),
N_("Change to DIRECTORY before doing anything") }, N_("Change to DIRECTORY before doing anything") },
@ -989,8 +997,8 @@ int main (int argc, char ** argv)
#endif #endif
/* Initialize the special variables. */ /* Initialize the special variables. */
define_variable (".VARIABLES", 10, "", o_default, 0); define_variable (".VARIABLES", 10, "", o_default, 0)->special = 1;
define_variable (".TARGETS", 8, "", o_default, 0); /* define_variable (".TARGETS", 8, "", o_default, 0); */
/* Read in variables from the environment. It is important that this be /* Read in variables from the environment. It is important that this be
done before $(MAKE) is figured out so its definitions will not 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 <unixlib.h>
# include <unixio.h> # include <unixio.h>
# include <perror.h> # include <perror.h>
/* Needed to use alloca on VMS. */
# include <builtins.h>
#endif #endif
#ifndef __attribute__ #ifndef __attribute__
@ -485,7 +487,7 @@ extern const struct floc *reading_file;
extern char **environ; extern char **environ;
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag; 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 env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
extern int print_version_flag, print_directory_flag; extern int print_version_flag, print_directory_flag;
extern int warn_undefined_variables_flag, posix_pedantic, not_parallel; extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;

View File

@ -49,7 +49,7 @@ $ lopt = "/debug"
$ else $ else
$ lopt = "" $ lopt = ""
$ endif $ 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 $ copy config.h-vms config.h
$ n=0 $ n=0
$ open/write optf make.opt $ 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> 2002-04-21 Paul D. Smith <psmith@gnu.org>
* LINGUAS, hr.po: Added new translation: Croatian. * LINGUAS, hr.po: Added new translation: Croatian.
@ -7,15 +11,3 @@
* .cvsignore: Moved from i18n to here. * .cvsignore: Moved from i18n to here.
* POTFILES.in, LINGUAS, Makevars: Created. * 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 # 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? # 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; reading_file = curfile;
free(ebuf.bufstart); fclose (ebuf.fp);
free (ebuf.bufstart);
return r; return r;
} }
@ -2564,7 +2566,12 @@ readline (ebuf)
if (ferror (ebuf->fp)) if (ferror (ebuf->fp))
pfatal_with_name (ebuf->floc.filenm); 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 /* 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; int dep_status = 0;
register struct dep *d, *lastd; register struct dep *d, *lastd;
int running = 0; int running = 0;
int maybe_make;
DBF (DB_VERBOSE, _("Considering target file `%s'.\n")); DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
@ -437,6 +436,7 @@ update_file_1 (file, depth)
while (d != 0) while (d != 0)
{ {
FILE_TIMESTAMP mtime; FILE_TIMESTAMP mtime;
int maybe_make;
check_renamed (d->file); check_renamed (d->file);
@ -492,7 +492,7 @@ update_file_1 (file, depth)
/* Now we know whether this target needs updating. /* Now we know whether this target needs updating.
If it does, update all the intermediate files we depend on. */ 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) for (d = file->deps; d != 0; d = d->next)
if (d->file->intermediate) if (d->file->intermediate)
@ -544,7 +544,7 @@ update_file_1 (file, depth)
file->update_status = dep_status; file->update_status = dep_status;
notice_finished_file (file); notice_finished_file (file);
depth--; --depth;
DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n")); 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). */ file's bookkeeping (updated, but not_started is bogus state). */
set_command_state (file, cs_not_started); 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 $?. */ recent than this file, so we can define $?. */
deps_changed = 0; deps_changed = 0;
@ -636,12 +636,18 @@ update_file_1 (file, depth)
DBF (DB_BASIC, DBF (DB_BASIC,
_("Target `%s' is double-colon and has no prerequisites.\n")); _("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; must_make = 0;
DBF (DB_VERBOSE, DBF (DB_VERBOSE,
_("No commands for `%s' and no prerequisites actually changed.\n")); _("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) if (!must_make)
{ {
@ -839,7 +845,6 @@ check_dep (file, depth, this_mtime, must_make_ptr)
{ {
struct dep *d; struct dep *d;
int dep_status = 0; int dep_status = 0;
int maybe_make;
++depth; ++depth;
start_updating (file); 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. */ recent than the file on whose behalf we are checking. */
else else
{ {
register struct dep *lastd; struct dep *lastd;
lastd = 0; lastd = 0;
d = file->deps; d = file->deps;
while (d != 0) while (d != 0)
{ {
int maybe_make;
if (is_updating (d->file)) if (is_updating (d->file))
{ {
error (NILF, _("Circular %s <- %s dependency dropped."), 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> 2002-07-11 Paul D. Smith <psmith@gnu.org>
* run_make_tests.pl (valid_option): Add support for Valgrind * 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 which have either broken at some point in the past or seem likely to
break."; break.";
$makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile"); open(MAKEFILE,"> $makefile");
# The contents of the Makefile ... # The contents of the Makefile ...
print MAKEFILE <<EOF; 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 = EMPTY =
.PHONY: all a1 a2 a3 a4 .PHONY: all a1 a2 a3 a4
@ -36,10 +38,21 @@ EOF
close(MAKEFILE); close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile); &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"; $answer = "$make_name: Nothing to be done for `all'.\n";
&compare_output($answer,&get_logfile(1)); &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; 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. /* If the variable passed in is "special", handle its special nature.
Currently there are two such variables, both used for introspection: 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. 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. instance of make.
Returns the variable reference passed in. */ Returns the variable reference passed in. */
@ -192,10 +192,33 @@ handle_special_var (var)
static unsigned long last_var_count = 0; 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); 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) && global_variable_set.table.ht_fill != last_var_count)
{ {
unsigned long max = EXPANSION_INCREMENT (strlen (var->value)); 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. */ /* Make sure we have at least MAX bytes in the allocated buffer. */
var->value = xrealloc (var->value, max); var->value = xrealloc (var->value, max);
/* Walk through the hash of variables, constructing a list of names. */
p = var->value; p = var->value;
len = 0; len = 0;
for (; vp < end; ++vp) for (; vp < end; ++vp)
@ -231,6 +255,10 @@ handle_special_var (var)
} }
*(p-1) = '\0'; *(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; 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); v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
if (v) if (v)
return handle_special_var (v); return v->special ? handle_special_var (v) : v;
} }
#ifdef VMS #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. */ /* 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) if (v->recursive)
/* The previous definition of the variable was recursive. /* The previous definition of the variable was recursive.
The new value is the unexpanded old and new values. */ 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 when it was set; and from the expanded new value. Allocate
memory for the expansion as we may still need the rest of the memory for the expansion as we may still need the rest of the
buffer if we're looking at a target-specific variable. */ 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); oldlen = strlen (v->value);
newlen = strlen (p); vallen = strlen (val);
p = (char *) alloca (oldlen + 1 + newlen + 1); p = (char *) alloca (oldlen + 1 + vallen + 1);
bcopy (v->value, p, oldlen); bcopy (v->value, p, oldlen);
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 per_target:1; /* Nonzero if a target-specific variable. */
unsigned int append:1; /* Nonzero if an appending target-specific unsigned int append:1; /* Nonzero if an appending target-specific
variable. */ variable. */
unsigned int special:1; /* Nonzero if this is a special variable. */
unsigned int expanding:1; /* Nonzero if currently being expanded. */ unsigned int expanding:1; /* Nonzero if currently being expanded. */
unsigned int exp_count:EXP_COUNT_BITS; unsigned int exp_count:EXP_COUNT_BITS;
/* If >1, allow this many self-referential /* If >1, allow this many self-referential