diff options
| author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-05-28 05:21:40 -0400 |
|---|---|---|
| committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-05-28 14:28:58 -0400 |
| commit | 104daea149c45cc84842ce77a9bd6436d19f3dd8 (patch) | |
| tree | 7f0aaa24e9fa03154a74b2bd7bcb93f24d678ea4 /scripts | |
| parent | f1089c92da791034af73478159626007cba7f092 (diff) | |
kconfig: reference environment variables directly and remove 'option env='
To get access to environment variables, Kconfig needs to define a
symbol using "option env=" syntax. It is tedious to add a symbol entry
for each environment variable given that we need to define much more
such as 'CC', 'AS', 'srctree' etc. to evaluate the compiler capability
in Kconfig.
Adding '$' for symbol references is grammatically inconsistent.
Looking at the code, the symbols prefixed with 'S' are expanded by:
- conf_expand_value()
This is used to expand 'arch/$ARCH/defconfig' and 'defconfig_list'
- sym_expand_string_value()
This is used to expand strings in 'source' and 'mainmenu'
All of them are fixed values independent of user configuration. So,
they can be changed into the direct expansion instead of symbols.
This change makes the code much cleaner. The bounce symbols 'SRCARCH',
'ARCH', 'SUBARCH', 'KERNELVERSION' are gone.
sym_init() hard-coding 'UNAME_RELEASE' is also gone. 'UNAME_RELEASE'
should be replaced with an environment variable.
ARCH_DEFCONFIG is a normal symbol, so it should be simply referenced
without '$' prefix.
The new syntax is addicted by Make. The variable reference needs
parentheses, like $(FOO), but you can omit them for single-letter
variables, like $F. Yet, in Makefiles, people tend to use the
parenthetical form for consistency / clarification.
At this moment, only the environment variable is supported, but I will
extend the concept of 'variable' later on.
The variables are expanded in the lexer so we can simplify the token
handling on the parser side.
For example, the following code works.
[Example code]
config MY_TOOLCHAIN_LIST
string
default "My tools: CC=$(CC), AS=$(AS), CPP=$(CPP)"
[Result]
$ make -s alldefconfig && tail -n 1 .config
CONFIG_MY_TOOLCHAIN_LIST="My tools: CC=gcc, AS=as, CPP=gcc -E"
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kconfig/confdata.c | 33 | ||||
| -rw-r--r-- | scripts/kconfig/kconf_id.c | 1 | ||||
| -rw-r--r-- | scripts/kconfig/lkc.h | 5 | ||||
| -rw-r--r-- | scripts/kconfig/lkc_proto.h | 6 | ||||
| -rw-r--r-- | scripts/kconfig/menu.c | 3 | ||||
| -rw-r--r-- | scripts/kconfig/preprocess.c | 238 | ||||
| -rw-r--r-- | scripts/kconfig/symbol.c | 56 | ||||
| -rw-r--r-- | scripts/kconfig/util.c | 29 | ||||
| -rw-r--r-- | scripts/kconfig/zconf.l | 67 | ||||
| -rw-r--r-- | scripts/kconfig/zconf.y | 2 |
10 files changed, 326 insertions, 114 deletions
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 569217168e96..5f87ad561b08 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
| @@ -30,7 +30,7 @@ static void conf_message(const char *fmt, ...) | |||
| 30 | static const char *conf_filename; | 30 | static const char *conf_filename; |
| 31 | static int conf_lineno, conf_warnings; | 31 | static int conf_lineno, conf_warnings; |
| 32 | 32 | ||
| 33 | const char conf_defname[] = "arch/$ARCH/defconfig"; | 33 | const char conf_defname[] = "arch/$(ARCH)/defconfig"; |
| 34 | 34 | ||
| 35 | static void conf_warning(const char *fmt, ...) | 35 | static void conf_warning(const char *fmt, ...) |
| 36 | { | 36 | { |
| @@ -81,39 +81,13 @@ const char *conf_get_autoconfig_name(void) | |||
| 81 | return name ? name : "include/config/auto.conf"; | 81 | return name ? name : "include/config/auto.conf"; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static char *conf_expand_value(const char *in) | ||
| 85 | { | ||
| 86 | struct symbol *sym; | ||
| 87 | const char *src; | ||
| 88 | static char res_value[SYMBOL_MAXLENGTH]; | ||
| 89 | char *dst, name[SYMBOL_MAXLENGTH]; | ||
| 90 | |||
| 91 | res_value[0] = 0; | ||
| 92 | dst = name; | ||
| 93 | while ((src = strchr(in, '$'))) { | ||
| 94 | strncat(res_value, in, src - in); | ||
| 95 | src++; | ||
| 96 | dst = name; | ||
| 97 | while (isalnum(*src) || *src == '_') | ||
| 98 | *dst++ = *src++; | ||
| 99 | *dst = 0; | ||
| 100 | sym = sym_lookup(name, 0); | ||
| 101 | sym_calc_value(sym); | ||
| 102 | strcat(res_value, sym_get_string_value(sym)); | ||
| 103 | in = src; | ||
| 104 | } | ||
| 105 | strcat(res_value, in); | ||
| 106 | |||
| 107 | return res_value; | ||
| 108 | } | ||
| 109 | |||
| 110 | char *conf_get_default_confname(void) | 84 | char *conf_get_default_confname(void) |
| 111 | { | 85 | { |
| 112 | struct stat buf; | 86 | struct stat buf; |
| 113 | static char fullname[PATH_MAX+1]; | 87 | static char fullname[PATH_MAX+1]; |
| 114 | char *env, *name; | 88 | char *env, *name; |
| 115 | 89 | ||
| 116 | name = conf_expand_value(conf_defname); | 90 | name = expand_string(conf_defname); |
| 117 | env = getenv(SRCTREE); | 91 | env = getenv(SRCTREE); |
| 118 | if (env) { | 92 | if (env) { |
| 119 | sprintf(fullname, "%s/%s", env, name); | 93 | sprintf(fullname, "%s/%s", env, name); |
| @@ -274,7 +248,8 @@ int conf_read_simple(const char *name, int def) | |||
| 274 | if (expr_calc_value(prop->visible.expr) == no || | 248 | if (expr_calc_value(prop->visible.expr) == no || |
| 275 | prop->expr->type != E_SYMBOL) | 249 | prop->expr->type != E_SYMBOL) |
| 276 | continue; | 250 | continue; |
| 277 | name = conf_expand_value(prop->expr->left.sym->name); | 251 | sym_calc_value(prop->expr->left.sym); |
| 252 | name = sym_get_string_value(prop->expr->left.sym); | ||
| 278 | in = zconf_fopen(name); | 253 | in = zconf_fopen(name); |
| 279 | if (in) { | 254 | if (in) { |
| 280 | conf_message("using defaults found in %s", | 255 | conf_message("using defaults found in %s", |
diff --git a/scripts/kconfig/kconf_id.c b/scripts/kconfig/kconf_id.c index 3ea9c5f9f730..b3e0ea0ac732 100644 --- a/scripts/kconfig/kconf_id.c +++ b/scripts/kconfig/kconf_id.c | |||
| @@ -32,7 +32,6 @@ static struct kconf_id kconf_id_array[] = { | |||
| 32 | { "on", T_ON, TF_PARAM }, | 32 | { "on", T_ON, TF_PARAM }, |
| 33 | { "modules", T_OPT_MODULES, TF_OPTION }, | 33 | { "modules", T_OPT_MODULES, TF_OPTION }, |
| 34 | { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, | 34 | { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, |
| 35 | { "env", T_OPT_ENV, TF_OPTION }, | ||
| 36 | { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, | 35 | { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, |
| 37 | }; | 36 | }; |
| 38 | 37 | ||
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 2628bc6a2141..ed3ff88e60ba 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
| @@ -44,7 +44,6 @@ enum conf_def_mode { | |||
| 44 | 44 | ||
| 45 | #define T_OPT_MODULES 1 | 45 | #define T_OPT_MODULES 1 |
| 46 | #define T_OPT_DEFCONFIG_LIST 2 | 46 | #define T_OPT_DEFCONFIG_LIST 2 |
| 47 | #define T_OPT_ENV 3 | ||
| 48 | #define T_OPT_ALLNOCONFIG_Y 4 | 47 | #define T_OPT_ALLNOCONFIG_Y 4 |
| 49 | 48 | ||
| 50 | struct kconf_id { | 49 | struct kconf_id { |
| @@ -103,6 +102,7 @@ void *xmalloc(size_t size); | |||
| 103 | void *xcalloc(size_t nmemb, size_t size); | 102 | void *xcalloc(size_t nmemb, size_t size); |
| 104 | void *xrealloc(void *p, size_t size); | 103 | void *xrealloc(void *p, size_t size); |
| 105 | char *xstrdup(const char *s); | 104 | char *xstrdup(const char *s); |
| 105 | char *xstrndup(const char *s, size_t n); | ||
| 106 | 106 | ||
| 107 | struct gstr { | 107 | struct gstr { |
| 108 | size_t len; | 108 | size_t len; |
| @@ -120,9 +120,6 @@ void str_printf(struct gstr *gs, const char *fmt, ...); | |||
| 120 | const char *str_get(struct gstr *gs); | 120 | const char *str_get(struct gstr *gs); |
| 121 | 121 | ||
| 122 | /* symbol.c */ | 122 | /* symbol.c */ |
| 123 | extern struct expr *sym_env_list; | ||
| 124 | |||
| 125 | void sym_init(void); | ||
| 126 | void sym_clear_all_valid(void); | 123 | void sym_clear_all_valid(void); |
| 127 | struct symbol *sym_choice_default(struct symbol *sym); | 124 | struct symbol *sym_choice_default(struct symbol *sym); |
| 128 | const char *sym_get_string_default(struct symbol *sym); | 125 | const char *sym_get_string_default(struct symbol *sym); |
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 9dc8abfb1dc3..9f465fe1ca85 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h | |||
| @@ -49,5 +49,11 @@ const char * sym_get_string_value(struct symbol *sym); | |||
| 49 | 49 | ||
| 50 | const char * prop_get_type_name(enum prop_type type); | 50 | const char * prop_get_type_name(enum prop_type type); |
| 51 | 51 | ||
| 52 | /* preprocess.c */ | ||
| 53 | void env_write_dep(FILE *f, const char *auto_conf_name); | ||
| 54 | char *expand_string(const char *in); | ||
| 55 | char *expand_dollar(const char **str); | ||
| 56 | char *expand_one_token(const char **str); | ||
| 57 | |||
| 52 | /* expr.c */ | 58 | /* expr.c */ |
| 53 | void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); | 59 | void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 068a4e4db20a..379a119dcd1e 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
| @@ -214,9 +214,6 @@ void menu_add_option(int token, char *arg) | |||
| 214 | zconf_error("trying to redefine defconfig symbol"); | 214 | zconf_error("trying to redefine defconfig symbol"); |
| 215 | sym_defconfig_list->flags |= SYMBOL_AUTO; | 215 | sym_defconfig_list->flags |= SYMBOL_AUTO; |
| 216 | break; | 216 | break; |
| 217 | case T_OPT_ENV: | ||
| 218 | prop_add_env(arg); | ||
| 219 | break; | ||
| 220 | case T_OPT_ALLNOCONFIG_Y: | 217 | case T_OPT_ALLNOCONFIG_Y: |
| 221 | current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; | 218 | current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; |
| 222 | break; | 219 | break; |
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c new file mode 100644 index 000000000000..a2eb2eb02929 --- /dev/null +++ b/scripts/kconfig/preprocess.c | |||
| @@ -0,0 +1,238 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // | ||
| 3 | // Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com> | ||
| 4 | |||
| 5 | #include <stdarg.h> | ||
| 6 | #include <stdbool.h> | ||
| 7 | #include <stdio.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <string.h> | ||
| 10 | |||
| 11 | #include "list.h" | ||
| 12 | |||
| 13 | static void __attribute__((noreturn)) pperror(const char *format, ...) | ||
| 14 | { | ||
| 15 | va_list ap; | ||
| 16 | |||
| 17 | fprintf(stderr, "%s:%d: ", current_file->name, yylineno); | ||
| 18 | va_start(ap, format); | ||
| 19 | vfprintf(stderr, format, ap); | ||
| 20 | va_end(ap); | ||
| 21 | fprintf(stderr, "\n"); | ||
| 22 | |||
| 23 | exit(1); | ||
| 24 | } | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Environment variables | ||
| 28 | */ | ||
| 29 | static LIST_HEAD(env_list); | ||
| 30 | |||
| 31 | struct env { | ||
| 32 | char *name; | ||
| 33 | char *value; | ||
| 34 | struct list_head node; | ||
| 35 | }; | ||
| 36 | |||
| 37 | static void env_add(const char *name, const char *value) | ||
