[PATCH 2/3] kconfig: Add special rust_modules config option

Matthew Maurer
2023-11-08T02:27:43Z

Adds support for the rust_modules kconfig type, which works similarly to
modules, but for restricting or allowing the use of modules which
directly depend on Rust.

Signed-off-by: Matthew Maurer <mmaurer@google.com>
---
scripts/kconfig/confdata.c | 3 +++
scripts/kconfig/expr.h | 1 +
scripts/kconfig/lexer.l | 1 +
scripts/kconfig/lkc.h | 1 +
scripts/kconfig/menu.c | 7 +++++--
scripts/kconfig/parser.y | 12 ++++++++++++
scripts/kconfig/symbol.c | 31 +++++++++++++++++++++++++++++--
7 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 4a6811d77d18..f5e2dcb56e1c 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -549,10 +549,12 @@ int conf_read(const char *name)

if (conf_read_simple(name, S_DEF_USER)) {
sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);
return 1;
}

sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);

for_all_symbols(i, sym) {
sym_calc_value(sym);
@@ -1090,6 +1092,7 @@ static int conf_touch_deps(void)

conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);

for_all_symbols(i, sym) {
sym_calc_value(sym);
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index edfe3046d050..6b576fbc330e 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -283,6 +283,7 @@ struct file *lookup_file(const char *name);

extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym;
+extern struct symbol *modules_rust_sym;
extern int cdebug;
struct expr *expr_alloc_symbol(struct symbol *sym);
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index cc386e443683..d6c7fd11f07e 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -114,6 +114,7 @@ n [A-Za-z0-9_-]
"optional" return T_OPTIONAL;
"prompt" return T_PROMPT;
"range" return T_RANGE;
+"rust_modules" return T_MODULES_RUST;
"select" return T_SELECT;
"source" return T_SOURCE;
"string" return T_STRING;
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 471a59acecec..ea97ff25909e 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -108,6 +108,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */
void sym_clear_all_valid(void);
struct symbol *sym_choice_default(struct symbol *sym);
+bool sym_depends_rust(struct symbol *sym);
struct property *sym_get_range_prop(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index d5898cd6aeb8..10a115f3a450 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -96,8 +96,11 @@ static struct expr *rewrite_m(struct expr *e)
break;
case E_SYMBOL:
/* change 'm' into 'm' && MODULES */
- if (e->left.sym == &symbol_mod)
- return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+ if (e->left.sym == &symbol_mod) {
+ if (sym_depends_rust(e->left.sym))
+ e = expr_alloc_and(e, expr_alloc_symbol(modules_rust_sym));
+ e = expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+ }
break;
default:
break;
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 2af7ce4e1531..37d9e390f545 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -68,6 +68,7 @@ struct menu *current_menu, *current_entry;
%token T_MENU
%token T_MENUCONFIG
%token T_MODULES
+%token T_MODULES_RUST
%token T_ON
%token T_OPEN_PAREN
%token T_OPTIONAL
@@ -224,6 +225,15 @@ config_option: T_MODULES T_EOL
modules_sym = current_entry->sym;
};

+config_option: T_MODULES_RUST T_EOL
+{
+ if (modules_rust_sym)
+ zconf_error("symbol '%s' redefines option 'rust_modules' already defined by symbol '%s'",
+ current_entry->sym->name, modules_rust_sym->name);
+ modules_rust_sym = current_entry->sym;
+};
+
+
/* choice entry */

choice: T_CHOICE word_opt T_EOL
@@ -495,6 +505,8 @@ void conf_parse(const char *name)
exit(1);
if (!modules_sym)
modules_sym = sym_find( "n" );
+ if (!modules_rust_sym)
+ modules_rust_sym = sym_find( "n" );

if (!menu_has_prompt(&rootmenu)) {
current_entry = &rootmenu;
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 0572330bf8a7..d48fbde936d1 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -38,6 +38,18 @@ static struct symbol symbol_empty = {
struct symbol *modules_sym;
static tristate modules_val;

+struct symbol *modules_rust_sym;
+static tristate modules_rust_val;
+
+bool sym_depends_rust(struct symbol *sym)
+{
+ static struct symbol *rust_sym;
+
+ if (!rust_sym)
+ rust_sym = sym_find("RUST");
+ return expr_depends_symbol(sym->dir_dep.expr, rust_sym, true);
+}
+
enum symbol_type sym_get_type(struct symbol *sym)
{
enum symbol_type type = sym->type;
@@ -47,6 +59,8 @@ enum symbol_type sym_get_type(struct symbol *sym)
type = S_BOOLEAN;
else if (modules_val == no)
type = S_BOOLEAN;
+ else if ((modules_rust_val == no) && sym_depends_rust(sym))
+ type = S_BOOLEAN;
}
return type;
}
@@ -443,6 +457,10 @@ void sym_calc_value(struct symbol *sym)
sym_set_all_changed();
modules_val = modules_sym->curr.tri;
}
+ if (modules_rust_sym == sym) {
+ sym_set_all_changed();
+ modules_rust_val = modules_rust_sym->curr.tri;
+ }
}

if (sym_is_choice(sym)) {
@@ -474,6 +492,7 @@ void sym_clear_all_valid(void)
sym->flags &= ~SYMBOL_VALID;
conf_set_changed(true);
sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);
}

bool sym_tristate_within_range(struct symbol *sym, tristate val)
@@ -704,6 +723,7 @@ const char *sym_get_string_default(struct symbol *sym)

sym_calc_visibility(sym);
sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);
val = symbol_no.curr.tri;
str = symbol_empty.curr.val;

@@ -734,9 +754,12 @@ const char *sym_get_string_default(struct symbol *sym)
val = EXPR_OR(val, sym->rev_dep.tri);

/* transpose mod to yes if modules are not enabled */
- if (val == mod)
- if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
+ if ((val == mod) && !sym_is_choice_value(sym)) {
+ if (modules_sym->curr.tri == no)
+ val = yes;
+ if ((modules_rust_sym->curr.tri == no) && sym_depends_rust(sym))
val = yes;
+ }

/* transpose mod to yes if type is bool */
if (sym->type == S_BOOLEAN && val == mod)
@@ -778,7 +801,11 @@ const char *sym_get_string_value(struct symbol *sym)
return "n";
case mod:
sym_calc_value(modules_sym);
+ sym_calc_value(modules_rust_sym);
+ if (sym_depends_rust(sym))
+ return (modules_rust_sym->curr.tri == no) ? "n" : "m";
return (modules_sym->curr.tri == no) ? "n" : "m";
+
case yes:
return "y";
}
--
2.42.0.869.gea05f2083d-goog