[PATCH v1 3/3] build system: don't record defaults as explicit choices. Closes 10296

Charles Mirabile via busybox <[email protected]> Sun, 5 Jul 2026 17:00:32 -0400
Newsgroups gmane.linux.busybox
Message-ID <[email protected]>
This patch is a relatively straightforward backport (minor context changes
to a few hunks due to drift, but exact same logic) of the kernel commit:
f82f3f9422d4d ("kconfig: oldconfig shall not set symbols if it does not need to")
from 2007 by Roman Zippel the original author of kconfig. Essentially,
extend `conf_askvalue` to report if the symbol was actively adjusted (more
than one valid option existed, and it didn't already have a value), or
unchanged (because it cannot change or already had a value), and then have
the callers check the return code and only call `sym_set_*_value` which
records that value an explicit user choice if it was the result of an
active adjustment.

This fixes the issue with e.g. `CONFIG_LONG_OPTS` during `allnoconfig`
because previously that option was encountered early in the loop over
all options while it was forced to yes by being selected by other configs,
e.g. `CONFIG_ADDUSER`. With the prior behavior, the fact that that option
had a value of 'Y' after `conf_askvalue` finished was recorded as if it
were representative of an actual user choice (and not merely the result
of a reverse dependency). When the config for adduser (and all the other
options that select long options) was later disabled, even though nothing
was forcing `CONFIG_LONG_OPTS` to 'Y' any more, instead of flipping off,
it was kept as 'Y' because it was recorded as being enabled by an active
choice from the user (or their policy). Leaving things in a lazy state
when no active choice was made, defers their selection until the dust of
other potential dependencies settles.

Signed-off-by: Charles Mirabile <[email protected]>
---
 scripts/kconfig/conf.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 04ae81f79..bd3885f66 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -66,7 +66,7 @@ static void check_stdin(void)
 	}
 }
 
-static void conf_askvalue(struct symbol *sym, const char *def)
+static int conf_askvalue(struct symbol *sym, const char *def)
 {
 	enum symbol_type type = sym_get_type(sym);
 	tristate val;
@@ -81,7 +81,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 		printf("%s\n", def);
 		line[0] = '\n';
 		line[1] = 0;
-		return;
+		return 0;
 	}
 
 	switch (input_mode) {
@@ -91,24 +91,24 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 	case set_random:
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
-			return;
+			return 0;
 		}
 		break;
 	case ask_new:
 	case ask_silent:
 		if (sym_has_value(sym)) {
 			printf("%s\n", def);
-			return;
+			return 0;
 		}
 		check_stdin();
 	case ask_all:
 		fflush(stdout);
 		if (!fgets(line, 128, stdin))
 			exit(1);
-		return;
+		return 1;
 	case set_default:
 		printf("%s\n", def);
-		return;
+		return 1;
 	default:
 		break;
 	}
@@ -118,7 +118,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 	case S_HEX:
 	case S_STRING:
 		printf("%s\n", def);
-		return;
+		return 1;
 	default:
 		;
 	}
@@ -169,6 +169,7 @@ static void conf_askvalue(struct symbol *sym, const char *def)
 		break;
 	}
 	printf("%s", line);
+	return 1;
 }
 
 int conf_string(struct menu *menu)
@@ -182,7 +183,8 @@ int conf_string(struct menu *menu)
 		def = sym_get_string_value(sym);
 		if (sym_get_string_value(sym))
 			printf("[%s] ", def);
-		conf_askvalue(sym, def);
+		if (!conf_askvalue(sym, def))
+			return 0;
 		switch (line[0]) {
 		case '\n':
 			break;
@@ -234,7 +236,8 @@ static int conf_sym(struct menu *menu)
 		if (sym->help)
 			printf("/?");
 		printf("] ");
-		conf_askvalue(sym, sym_get_string_value(sym));
+		if (!conf_askvalue(sym, sym_get_string_value(sym)))
+			return 0;
 		strip(line);
 
 		switch (line[0]) {
-- 
2.54.0