summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2009-10-25 00:46:52 +0000
committerPaul Smith <psmith@gnu.org>2009-10-25 00:46:52 +0000
commit4e51b6d9a4eb7eef2272551d55d8abaadd5f01e3 (patch)
treefd4867c9098333197abe49c21e27caf920c35b25
parent606cf9b169f23b8d87b20ea02b235df8fa66c2d8 (diff)
downloadgunmake-4e51b6d9a4eb7eef2272551d55d8abaadd5f01e3.tar.gz
New command line option: --eval=STRING will cause STRING to be
evaluated as a makefile statement before the first makefile is read.
-rw-r--r--ChangeLog28
-rw-r--r--NEWS21
-rw-r--r--doc/make.texi9
-rw-r--r--job.c4
-rw-r--r--main.c144
-rw-r--r--tests/scripts/options/eval19
6 files changed, 173 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index eceada6..b475f4f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2009-10-24 Paul Smith <psmith@gnu.org>
+
+ * main.c (usage): Add --eval to the usage string.
+ (switches): Add the --eval switch.
+ (main): If --eval is given, add them to the simply-expanded variable
+ -*-eval-flags-*- (necessary to allow recursion to work properly).
+ (define_makeflags): Add -*-eval-flags-*- to MAKEFLAGS.
+
+ * NEWS: Describe the new --eval command line argument.
+ * doc/make.texi (Options Summary): Document --eval.
+
+ * dep.h: eval_buffer() returns void.
+ * read.c (eval_buffer): Ditto.
+ (eval): Ditto.
+
+ * variable.h (define_variable_cname): New macro for constant
+ variable names.
+ * default.c (set_default_suffixes): Use it.
+ * main.c (main): Ditto.
+ (handle_non_switch_argument): Ditto.
+ (define_makeflags): Ditto.
+ * read.c (read_all_makefiles): Ditto.
+ * variable.c (define_automatic_variables): Ditto.
+
+ * commands.c (dep_hash_cmp): Avoid casts.
+ (dep_hash_1): Ditto.
+ (dep_hash_2): Ditto.
+
2009-10-22 Boris Kolpackov <boris@codesynthesis.com>
* read.c (read_all_makefiles): Mark the default makefile dependency
diff --git a/NEWS b/NEWS
index e6bac36..f050105 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
- 25 May 2009
+ 12 Oct 2009
See the end of this file for copyrights and conditions.
@@ -28,12 +28,17 @@ Version 3.81.90
variable.
* WARNING: Backward-incompatibility!
- The pattern-specific variables and pattern rules are now applied in the
+ The pattern-specific variables and pattern rules are now applied in the
shortest stem first order instead of the definition order (variables
and rules with the same stem length are still applied in the definition
order). This produces the usually-desired behavior where more specific
patterns are preferred. To detect this feature search for 'shortest-stem'
- in the .FEATURES special variable.
+ in the .FEATURES special variable.
+
+* New command line option: --eval=STRING causes STRING to be evaluated as
+ makefile syntax (akin to using the $(eval ...) function). The evaluation is
+ performed after all default rules and variables are defined, but before any
+ makefiles are read.
* New special variable: .RECIPEPREFIX allows you to reset the recipe
introduction character from the default (TAB) to something else. The first
@@ -47,16 +52,16 @@ Version 3.81.90
prerequisites. This is most useful for target- and pattern-specific
variables.
+* New make directive: 'undefine' allows you to undefine a variable so
+ that it appears as if it was never set. Both $(flavor) and $(origin)
+ functions will return 'undefined' for such a variable. To detect this
+ feature search for 'undefine in the .FEATURES special variable.
+
* The parser for variable assignments has been enhanced to allow multiple
modifiers ('export', 'override', 'private') on the same line as variables,
including define/endef variables, and in any order. Also, it is possible
to create variables and targets named as these modifiers.
-* New make directive: 'undefine' allows you to undefine a variable so
- that it appears as if it was never set. Both $(flavor) and $(origin)
- functions will return 'undefined' for such a variable. To detect this
- feature search for 'undefine in the .FEATURES special variable.
-
Version 3.81
diff --git a/doc/make.texi b/doc/make.texi
index 52a56ef..7a3be3b 100644
--- a/doc/make.texi
+++ b/doc/make.texi
@@ -8127,6 +8127,15 @@ Give variables taken from the environment precedence
over variables from makefiles.
@xref{Environment, ,Variables from the Environment}.
+@item --eval=@var{string}
+@cindex @code{--eval}
+@c Extra blank line here makes the table look better.
+
+Evaluate @var{string} as makefile syntax. This is a command-line
+version of the @code{eval} function (@pxref{Eval Function}). The
+evaluation is performed after the default rules and variables have
+been defined, but before any makefiles are read.
+
@item -f @var{file}
@cindex @code{-f}
@itemx --file=@var{file}
diff --git a/job.c b/job.c
index 54e17c4..a0e4d55 100644
--- a/job.c
+++ b/job.c
@@ -1,7 +1,7 @@
/* Job execution and handling for GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
-Foundation, Inc.
+1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free
+Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
diff --git a/main.c b/main.c
index 4d84b66..babf21d 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
/* Argument parsing and main program of GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
-Foundation, Inc.
+1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free
+Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -263,6 +263,9 @@ static struct stringlist *old_files = 0;
static struct stringlist *new_files = 0;
+/* List of strings to be eval'd. */
+static struct stringlist *eval_strings = 0;
+
/* If nonzero, we should just print usage and exit. */
static int print_usage_flag = 0;
@@ -313,6 +316,8 @@ static const char *const usage[] =
-e, --environment-overrides\n\
Environment variables override makefiles.\n"),
N_("\
+ --eval=STRING Evaluate STRING as a makefile statement.\n"),
+ N_("\
-f FILE, --file=FILE, --makefile=FILE\n\
Read FILE as a makefile.\n"),
N_("\
@@ -418,6 +423,7 @@ static const struct command_switch switches[] =
{ 'W', filename, &new_files, 0, 0, 0, 0, 0, "what-if" },
{ CHAR_MAX+5, flag, &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
"warn-undefined-variables" },
+ { CHAR_MAX+6, string, &eval_strings, 1, 0, 0, 0, 0, "eval" },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
@@ -1114,15 +1120,15 @@ main (int argc, char **argv, char **envp)
#endif
/* Initialize the special variables. */
- define_variable (".VARIABLES", 10, "", o_default, 0)->special = 1;
- /* define_variable (".TARGETS", 8, "", o_default, 0)->special = 1; */
- define_variable (".RECIPEPREFIX", 13, "", o_default, 0)->special = 1;
+ define_variable_cname (".VARIABLES", "", o_default, 0)->special = 1;
+ /* define_variable_cname (".TARGETS", "", o_default, 0)->special = 1; */
+ define_variable_cname (".RECIPEPREFIX", "", o_default, 0)->special = 1;
/* Set up .FEATURES */
- define_variable (".FEATURES", 9,
- "target-specific order-only second-expansion else-if"
- "shortest-stem undefine",
- o_default, 0);
+ define_variable_cname (".FEATURES",
+ "target-specific order-only second-expansion else-if"
+ "shortest-stem undefine",
+ o_default, 0);
#ifndef NO_ARCHIVES
do_variable_definition (NILF, ".FEATURES", "archives",
o_default, f_append, 0);
@@ -1204,9 +1210,8 @@ main (int argc, char **argv, char **envp)
* either the first mispelled value or an empty string
*/
if (!unix_path)
- define_variable("PATH", 4,
- windows32_path ? windows32_path : "",
- o_env, 1)->export = v_export;
+ define_variable_cname ("PATH", windows32_path ? windows32_path : "",
+ o_env, 1)->export = v_export;
#endif
#else /* For Amiga, read the ENV: device, ignoring all dirs */
{
@@ -1248,7 +1253,9 @@ main (int argc, char **argv, char **envp)
and we set the -p, -i and -e switches. Doesn't seem quite right. */
decode_env_switches (STRING_SIZE_TUPLE ("MFLAGS"));
#endif
+
decode_switches (argc, argv, 0);
+
#ifdef WINDOWS32
if (suspend_flag) {
fprintf(stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId());
@@ -1328,8 +1335,8 @@ main (int argc, char **argv, char **envp)
/* The extra indirection through $(MAKE_COMMAND) is done
for hysterical raisins. */
- (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0);
- (void) define_variable ("MAKE", 4, "$(MAKE_COMMAND)", o_default, 1);
+ define_variable_cname ("MAKE_COMMAND", argv[0], o_default, 0);
+ define_variable_cname ("MAKE", "$(MAKE_COMMAND)", o_default, 1);
if (command_variables != 0)
{
@@ -1367,8 +1374,7 @@ main (int argc, char **argv, char **envp)
/* Define an unchangeable variable with a name that no POSIX.2
makefile could validly use for its own variable. */
- (void) define_variable ("-*-command-variables-*-", 23,
- value, o_automatic, 0);
+ define_variable_cname ("-*-command-variables-*-", value, o_automatic, 0);
/* Define the variable; this will not override any user definition.
Normally a reference to this variable is written into the value of
@@ -1376,8 +1382,8 @@ main (int argc, char **argv, char **envp)
exported value of MAKEFLAGS. In POSIX-pedantic mode, we cannot
allow the user's setting of MAKEOVERRIDES to affect MAKEFLAGS, so
a reference to this hidden variable is written instead. */
- (void) define_variable ("MAKEOVERRIDES", 13,
- "${-*-command-variables-*-}", o_env, 1);
+ define_variable_cname ("MAKEOVERRIDES", "${-*-command-variables-*-}",
+ o_env, 1);
}
/* If there were -C flags, move ourselves about. */
@@ -1464,7 +1470,7 @@ main (int argc, char **argv, char **envp)
starting_directory = current_directory;
}
- (void) define_variable ("CURDIR", 6, current_directory, o_file, 0);
+ define_variable_cname ("CURDIR", current_directory, o_file, 0);
/* Read any stdin makefiles into temporary files. */
@@ -1604,7 +1610,37 @@ main (int argc, char **argv, char **envp)
default_file = enter_file (strcache_add (".DEFAULT"));
- default_goal_var = define_variable (".DEFAULT_GOAL", 13, "", o_file, 0);
+ default_goal_var = define_variable_cname (".DEFAULT_GOAL", "", o_file, 0);
+
+ /* Evaluate all strings provided with --eval.
+ Also set up the $(-*-eval-flags-*-) variable. */
+
+ if (eval_strings)
+ {
+ char *p, *value;
+ unsigned int i;
+ unsigned int len = sizeof ("--eval=") * eval_strings->idx;
+
+ for (i = 0; i < eval_strings->idx; ++i)
+ {
+ p = xstrdup (eval_strings->list[i]);
+ len += 2 * strlen (p);
+ eval_buffer (p);
+ free (p);
+ }
+
+ p = value = alloca (len);
+ for (i = 0; i < eval_strings->idx; ++i)
+ {
+ strcpy (p, "--eval=");
+ p += strlen (p);
+ p = quote_for_env (p, eval_strings->list[i]);
+ *(p++) = ' ';
+ }
+ p[-1] = '\0';
+
+ define_variable_cname ("-*-eval-flags-*-", value, o_automatic, 0);
+ }
/* Read all the makefiles. */
@@ -2402,7 +2438,7 @@ handle_non_switch_argument (char *arg, int env)
memcpy (&vp[oldlen + 1], f->name, newlen + 1);
value = vp;
}
- define_variable ("MAKECMDGOALS", 12, value, o_default, 0);
+ define_variable_cname ("MAKECMDGOALS", value, o_default, 0);
}
}
}
@@ -2504,8 +2540,16 @@ decode_switches (int argc, char **argv, int env)
optarg = xstrdup (cs->noarg_value);
else if (*optarg == '\0')
{
- error (NILF, _("the `-%c' option requires a non-empty string argument"),
- cs->c);
+ char opt[2] = "c";
+ const char *op = opt;
+
+ if (short_option (cs->c))
+ opt[0] = cs->c;
+ else
+ op = cs->long_name;
+
+ error (NILF, _("the `%s%s' option requires a non-empty string argument"),
+ short_option (cs->c) ? "-" : "--", op);
bad = 1;
}
@@ -2703,9 +2747,10 @@ quote_for_env (char *out, const char *in)
static const char *
define_makeflags (int all, int makefile)
{
- static const char ref[] = "$(MAKEOVERRIDES)";
- static const char posixref[] = "$(-*-command-variables-*-)";
- register const struct command_switch *cs;
+ const char ref[] = "$(MAKEOVERRIDES)";
+ const char posixref[] = "$(-*-command-variables-*-)";
+ const char evalref[] = "$(-*-eval-flags-*-)";
+ const struct command_switch *cs;
char *flagstring;
register char *p;
unsigned int words;
@@ -2726,7 +2771,7 @@ define_makeflags (int all, int makefile)
unsigned int flagslen = 0;
#define ADD_FLAG(ARG, LEN) \
do { \
- struct flag *new = alloca (sizeof (struct flag)); \
+ struct flag *new = alloca (sizeof (struct flag)); \
new->cs = cs; \
new->arg = (ARG); \
new->next = flags; \
@@ -2734,7 +2779,8 @@ define_makeflags (int all, int makefile)
if (new->arg == 0) \
++flagslen; /* Just a single flag letter. */ \
else \
- flagslen += 1 + 1 + 1 + 1 + 3 * (LEN); /* " -x foo" */ \
+ /* " -x foo", plus space to expand "foo". */ \
+ flagslen += 1 + 1 + 1 + 1 + (3 * (LEN)); \
if (!short_option (cs->c)) \
/* This switch has no single-letter version, so we use the long. */ \
flagslen += 2 + strlen (cs->long_name); \
@@ -2821,7 +2867,8 @@ define_makeflags (int all, int makefile)
abort ();
}
- flagslen += 4 + sizeof posixref; /* Four more for the possible " -- ". */
+ /* Four more for the possible " -- ". */
+ flagslen += 4 + sizeof (posixref) + sizeof (evalref);
#undef ADD_FLAG
@@ -2893,7 +2940,20 @@ define_makeflags (int all, int makefile)
/* Since MFLAGS is not parsed for flags, there is no reason to
override any makefile redefinition. */
- (void) define_variable ("MFLAGS", 6, flagstring, o_env, 1);
+ define_variable_cname ("MFLAGS", flagstring, o_env, 1);
+
+ /* Write a reference to -*-eval-flags-*-, which contains all the --eval
+ flag options. */
+ if (eval_strings)
+ {
+ if (p == &flagstring[1])
+ /* No flags written, so elide the leading dash already written. */
+ p = flagstring;
+ else
+ *p++ = ' ';
+ memcpy (p, evalref, sizeof (evalref) - 1);
+ p += sizeof (evalref) - 1;
+ }
if (all && command_variables != 0)
{
@@ -2920,13 +2980,13 @@ define_makeflags (int all, int makefile)
/* Copy in the string. */
if (posix_pedantic)
{
- memcpy (p, posixref, sizeof posixref - 1);
- p += sizeof posixref - 1;
+ memcpy (p, posixref, sizeof (posixref) - 1);
+ p += sizeof (posixref) - 1;
}
else
{
- memcpy (p, ref, sizeof ref - 1);
- p += sizeof ref - 1;
+ memcpy (p, ref, sizeof (ref) - 1);
+ p += sizeof (ref) - 1;
}
}
else if (p == &flagstring[1])
@@ -2945,14 +3005,14 @@ define_makeflags (int all, int makefile)
if (flagstring[0] == '-' && flagstring[1] != '-')
++flagstring;
- v = define_variable ("MAKEFLAGS", 9, flagstring,
- /* This used to use o_env, but that lost when a
- makefile defined MAKEFLAGS. Makefiles set
- MAKEFLAGS to add switches, but we still want
- to redefine its value with the full set of
- switches. Of course, an override or command
- definition will still take precedence. */
- o_file, 1);
+ v = define_variable_cname ("MAKEFLAGS", flagstring,
+ /* This used to use o_env, but that lost when a
+ makefile defined MAKEFLAGS. Makefiles set
+ MAKEFLAGS to add switches, but we still want
+ to redefine its value with the full set of
+ switches. Of course, an override or command
+ definition will still take precedence. */
+ o_file, 1);
if (! all)
/* The first time we are called, set MAKEFLAGS to always be exported.
diff --git a/tests/scripts/options/eval b/tests/scripts/options/eval
new file mode 100644
index 0000000..06a035c
--- /dev/null
+++ b/tests/scripts/options/eval
@@ -0,0 +1,19 @@
+# -*-perl-*-
+
+$description = "Test the --eval option.";
+
+$details = "Verify that --eval options take effect,
+and are passed to sub-makes.";
+
+# Verify that --eval is evaluated first
+run_make_test(q!
+BAR = bar
+all: ; @echo all
+recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!,
+ '--eval=\$\(info\ eval\) FOO=\$\(BAR\)', "eval\nall");
+
+# Make sure that --eval is handled correctly during recursion
+run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse',
+ "eval\neval\nall\nrecurse");
+
+1;