diff mbox series

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

Message ID 20231108022651.645950-5-mmaurer@google.com (mailing list archive)
State New, archived
Headers show
Series Support MODVERSIONS by disabling Rust modules | expand

Commit Message

Matthew Maurer Nov. 8, 2023, 2:26 a.m. UTC
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(-)

Comments

Randy Dunlap Nov. 8, 2023, 3:01 a.m. UTC | #1
On 11/7/23 18:26, Matthew Maurer wrote:
> 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(-)
> 

Hi,

This appears to be a change to the Kconfig language, so please update
Documentation/kbuild/kconfig-language.rst with some prose explaining it.

Thanks.
Boris Kolpackov Nov. 9, 2023, 7:43 a.m. UTC | #2
Matthew Maurer <mmaurer@google.com> writes:

> 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.
>
> [...]
>
> +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);
> +}
> +

Hm, this feels like a quick and dirty hack to me: will we be hardcoding
a symbol for each language?

I know there is little sympathy for other projects that use Kconfig,
and whatever Linux needs, goes, but still, this feels like a step too
far.
diff mbox series

Patch

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";
 		}