diff options
author | Paul Smith <psmith@gnu.org> | 2009-10-25 00:46:52 +0000 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2009-10-25 00:46:52 +0000 |
commit | 4e51b6d9a4eb7eef2272551d55d8abaadd5f01e3 (patch) | |
tree | fd4867c9098333197abe49c21e27caf920c35b25 | |
parent | 606cf9b169f23b8d87b20ea02b235df8fa66c2d8 (diff) | |
download | gunmake-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-- | ChangeLog | 28 | ||||
-rw-r--r-- | NEWS | 21 | ||||
-rw-r--r-- | doc/make.texi | 9 | ||||
-rw-r--r-- | job.c | 4 | ||||
-rw-r--r-- | main.c | 144 | ||||
-rw-r--r-- | tests/scripts/options/eval | 19 |
6 files changed, 173 insertions, 52 deletions
@@ -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 @@ -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} @@ -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 @@ -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; |