kconfig: remove 'optional' property support

The 'choice' statement is primarily used to exclusively select one
option, but the 'optional' property allows all entries to be disabled.

In the following example, both A and B can be disabled simultaneously:

    choice
            prompt "choose A, B, or nothing"
            optional

    config A
            bool "A"

    config B
            bool "B"

    endchoice

You can achieve the equivalent outcome by other means.

A common solution is to add another option to guard the choice block.
In the following example, you can set ENABLE_A_B_CHOICE=n to disable
the entire choice block:

    choice
            prompt "choose A or B"
            depends on ENABLE_A_B_CHOICE

    config A
            bool "A"

    config B
            bool "B"

    endchoice

Another approach is to insert one more entry:

    choice
            prompt "choose A, B, or disable both"

    config A
            bool "A"

    config B
            bool "B"

    config DISABLE_A_AND_B
            bool "choose this to disable both A and B"

    endchoice

Some real examples are DEBUG_INFO_NONE, INITRAMFS_COMPRESSION_NONE,
LTO_NONE, etc.

The 'optional' property is even more unnecessary for a tristate choice.

Without the 'optional' property, you can disable A and B; you can set
'm' in the choice prompt, and disable A and B individually:

    choice
            prompt "choose one built-in or make them modular"

    config A
            tristate "A"

    config B
            tristate "B"

    endchoice

In conclusion, the 'optional' property was unneeded.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <n.schier@avm.de>
This commit is contained in:
Masahiro Yamada 2024-04-23 01:41:04 +09:00
parent d9a1dab65a
commit 6a1215888e
15 changed files with 5 additions and 78 deletions

View file

@ -410,9 +410,6 @@ to be set to 'm'. This can be used if multiple drivers for a single
hardware exists and only a single driver can be compiled/loaded into
the kernel, but all drivers can be compiled as modules.
A choice accepts another option "optional", which allows to set the
choice to 'n' and no entry needs to be selected.
comment::
"comment" <prompt>

View file

@ -810,9 +810,6 @@ int conf_write_defconfig(const char *filename)
/*
* If symbol is a choice value and equals to the
* default for a choice - skip.
* But only if value is bool and equal to "y" and
* choice is not "optional".
* (If choice is "optional" then all values can be "n")
*/
if (sym_is_choice_value(sym)) {
struct symbol *cs;
@ -820,7 +817,7 @@ int conf_write_defconfig(const char *filename)
cs = prop_get_symbol(sym_get_choice_prop(sym));
ds = sym_choice_default(cs);
if (!sym_is_optional(cs) && sym == ds) {
if (sym == ds) {
if ((sym->type == S_BOOLEAN) &&
sym_get_tristate_value(sym) == yes)
continue;

View file

@ -132,7 +132,6 @@ struct symbol {
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */
#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */
#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
#define SYMBOL_CHANGED 0x0400 /* ? */
#define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */

View file

@ -87,8 +87,6 @@ static const char *dbg_sym_flags(int val)
strcat(buf, "choiceval/");
if (val & SYMBOL_VALID)
strcat(buf, "valid/");
if (val & SYMBOL_OPTIONAL)
strcat(buf, "optional/");
if (val & SYMBOL_WRITE)
strcat(buf, "write/");
if (val & SYMBOL_CHANGED)

View file

@ -120,7 +120,6 @@ n [A-Za-z0-9_-]
"menuconfig" return T_MENUCONFIG;
"modules" return T_MODULES;
"on" return T_ON;
"optional" return T_OPTIONAL;
"prompt" return T_PROMPT;
"range" return T_RANGE;
"select" return T_SELECT;

View file

@ -138,11 +138,6 @@ static inline bool sym_is_choice_value(struct symbol *sym)
return sym->flags & SYMBOL_CHOICEVAL ? true : false;
}
static inline bool sym_is_optional(struct symbol *sym)
{
return sym->flags & SYMBOL_OPTIONAL ? true : false;
}
static inline bool sym_has_value(struct symbol *sym)
{
return sym->flags & SYMBOL_DEF_USER ? true : false;

View file

@ -593,15 +593,11 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
}
/*
* For non-optional choices, add a reverse dependency (corresponding to
* a select) of '<visibility> && m'. This prevents the user from
* setting the choice mode to 'n' when the choice is visible.
*
* This would also work for non-choice symbols, but only non-optional
* choices clear SYMBOL_OPTIONAL as of writing. Choices are implemented
* as a type of symbol.
* For choices, add a reverse dependency (corresponding to a select) of
* '<visibility> && m'. This prevents the user from setting the choice
* mode to 'n' when the choice is visible.
*/
if (sym && !sym_is_optional(sym) && parent->prompt) {
if (sym && sym_is_choice(sym) && parent->prompt) {
sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
expr_alloc_and(parent->prompt->visible.expr,
expr_alloc_symbol(&symbol_mod)));

View file

@ -69,7 +69,6 @@ struct menu *current_menu, *current_entry;
%token T_MODULES
%token T_ON
%token T_OPEN_PAREN
%token T_OPTIONAL
%token T_PLUS_EQUAL
%token T_PROMPT
%token T_RANGE
@ -140,7 +139,6 @@ stmt_list_in_choice:
config_entry_start: T_CONFIG nonconst_symbol T_EOL
{
$2->flags |= SYMBOL_OPTIONAL;
menu_add_entry($2);
printd(DEBUG_PARSE, "%s:%d:config %s\n", cur_filename, cur_lineno, $2->name);
};
@ -152,7 +150,6 @@ config_stmt: config_entry_start config_option_list
menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
{
$2->flags |= SYMBOL_OPTIONAL;
menu_add_entry($2);
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", cur_filename, cur_lineno, $2->name);
};
@ -272,12 +269,6 @@ choice_option: logic_type prompt_stmt_opt T_EOL
printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);
};
choice_option: T_OPTIONAL T_EOL
{
current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", cur_filename, cur_lineno);
};
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
{
menu_add_symbol(P_DEFAULT, $2, $3);

View file

@ -17,19 +17,6 @@ config BOOL_CHOICE1
endchoice
choice
prompt "optional boolean choice"
optional
default OPT_BOOL_CHOICE1
config OPT_BOOL_CHOICE0
bool "choice 0"
config OPT_BOOL_CHOICE1
bool "choice 1"
endchoice
choice
prompt "tristate choice"
default TRI_CHOICE1
@ -41,16 +28,3 @@ config TRI_CHOICE1
tristate "choice 1"
endchoice
choice
prompt "optional tristate choice"
optional
default OPT_TRI_CHOICE1
config OPT_TRI_CHOICE0
tristate "choice 0"
config OPT_TRI_CHOICE1
tristate "choice 1"
endchoice

View file

@ -6,8 +6,6 @@ The handling of 'choice' is a bit complicated part in Kconfig.
The behavior of 'y' choice is intuitive. If choice values are tristate,
the choice can be 'm' where each value can be enabled independently.
Also, if a choice is marked as 'optional', the whole choice can be
invisible.
"""

View file

@ -1,9 +1,5 @@
CONFIG_MODULES=y
# CONFIG_BOOL_CHOICE0 is not set
CONFIG_BOOL_CHOICE1=y
# CONFIG_OPT_BOOL_CHOICE0 is not set
CONFIG_OPT_BOOL_CHOICE1=y
CONFIG_TRI_CHOICE0=m
CONFIG_TRI_CHOICE1=m
CONFIG_OPT_TRI_CHOICE0=m
CONFIG_OPT_TRI_CHOICE1=m

View file

@ -1,9 +1,5 @@
CONFIG_MODULES=y
# CONFIG_BOOL_CHOICE0 is not set
CONFIG_BOOL_CHOICE1=y
# CONFIG_OPT_BOOL_CHOICE0 is not set
CONFIG_OPT_BOOL_CHOICE1=y
# CONFIG_TRI_CHOICE0 is not set
CONFIG_TRI_CHOICE1=y
# CONFIG_OPT_TRI_CHOICE0 is not set
CONFIG_OPT_TRI_CHOICE1=y

View file

@ -3,8 +3,6 @@ boolean choice
1. choice 0 (BOOL_CHOICE0) (NEW)
> 2. choice 1 (BOOL_CHOICE1) (NEW)
choice[1-2?]:
optional boolean choice [N/y/?] (NEW)
tristate choice [M/y/?] (NEW)
choice 0 (TRI_CHOICE0) [N/m/?] (NEW)
choice 1 (TRI_CHOICE1) [N/m/?] (NEW)
optional tristate choice [N/m/y/?] (NEW)

View file

@ -1,2 +1 @@
# CONFIG_MODULES is not set
CONFIG_OPT_BOOL_CHOICE0=y

View file

@ -3,13 +3,7 @@ boolean choice
1. choice 0 (BOOL_CHOICE0) (NEW)
> 2. choice 1 (BOOL_CHOICE1) (NEW)
choice[1-2?]:
optional boolean choice [Y/n/?] (NEW)
optional boolean choice
> 1. choice 0 (OPT_BOOL_CHOICE0)
2. choice 1 (OPT_BOOL_CHOICE1) (NEW)
choice[1-2?]:
tristate choice
1. choice 0 (TRI_CHOICE0) (NEW)
> 2. choice 1 (TRI_CHOICE1) (NEW)
choice[1-2?]:
optional tristate choice [N/y/?]