Commit 5e8c5299 authored by Masahiro Yamada's avatar Masahiro Yamada

kconfig: report recursive dependency involving 'imply'

Currently, Kconfig does not complain about the recursive dependency
where 'imply' keywords are involved.

[Test Code]

  config A
          bool "a"

  config B
          bool "b"
          imply A
          depends on A

In the code above, Kconfig cannot calculate the symbol values correctly
due to the circular dependency.  For example, allyesconfig followed by
syncconfig results in an odd behavior because CONFIG_B becomes visible
in syncconfig.

  $ make allyesconfig
  scripts/kconfig/conf  --allyesconfig Kconfig
  #
  # configuration written to .config
  #
  $ cat .config
  #
  # Automatically generated file; DO NOT EDIT.
  # Main menu
  #
  CONFIG_A=y
  $ make syncconfig
  scripts/kconfig/conf  --syncconfig Kconfig
  *
  * Restart config...
  *
  *
  * Main menu
  *
  a (A) [Y/n/?] y
    b (B) [N/y/?] (NEW)

To detect this correctly, sym_check_expr_deps() should recurse to
not only sym->rev_dep.expr but also sym->implied.expr .

At this moment, sym_check_print_recursive() cannot distinguish
'select' and 'imply' since it does not know the precise context
where the recursive dependency has been hit.  This will be solved
by the next commit.

In fact, even the document and the unit-test are confused.  Using
'imply' does not solve recursive dependency since 'imply' addresses
the unmet direct dependency, which 'select' could cause.
Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: default avatarDirk Gouders <dirk@gouders.net>
parent f1575595
...@@ -545,7 +545,7 @@ make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig ...@@ -545,7 +545,7 @@ make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
Practical solutions to kconfig recursive issue Practical solutions to kconfig recursive issue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Developers who run into the recursive Kconfig issue have three options Developers who run into the recursive Kconfig issue have two options
at their disposal. We document them below and also provide a list of at their disposal. We document them below and also provide a list of
historical issues resolved through these different solutions. historical issues resolved through these different solutions.
...@@ -553,7 +553,6 @@ historical issues resolved through these different solutions. ...@@ -553,7 +553,6 @@ historical issues resolved through these different solutions.
b) Match dependency semantics: b) Match dependency semantics:
b1) Swap all "select FOO" to "depends on FOO" or, b1) Swap all "select FOO" to "depends on FOO" or,
b2) Swap all "depends on FOO" to "select FOO" b2) Swap all "depends on FOO" to "select FOO"
c) Consider the use of "imply" instead of "select"
The resolution to a) can be tested with the sample Kconfig file The resolution to a) can be tested with the sample Kconfig file
Documentation/kbuild/Kconfig.recursion-issue-01 through the removal Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
......
...@@ -1098,7 +1098,7 @@ static void sym_check_print_recursive(struct symbol *last_sym) ...@@ -1098,7 +1098,7 @@ static void sym_check_print_recursive(struct symbol *last_sym)
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else { } else {
fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", fprintf(stderr, "%s:%d:\tsymbol %s is selected or implied by %s\n",
prop->file->name, prop->lineno, prop->file->name, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
...@@ -1161,8 +1161,13 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym) ...@@ -1161,8 +1161,13 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
if (sym2) if (sym2)
goto out; goto out;
sym2 = sym_check_expr_deps(sym->implied.expr);
if (sym2)
goto out;
for (prop = sym->prop; prop; prop = prop->next) { for (prop = sym->prop; prop; prop = prop->next) {
if (prop->type == P_CHOICE || prop->type == P_SELECT) if (prop->type == P_CHOICE || prop->type == P_SELECT ||
prop->type == P_IMPLY)
continue; continue;
stack.prop = prop; stack.prop = prop;
sym2 = sym_check_expr_deps(prop->visible.expr); sym2 = sym_check_expr_deps(prop->visible.expr);
......
# SPDX-License-Identifier: GPL-2.0
# depends on itself # depends on itself
config A config A
...@@ -31,7 +33,6 @@ config D2 ...@@ -31,7 +33,6 @@ config D2
bool bool
# depends on and imply # depends on and imply
# This is not recursive dependency
config E1 config E1
bool "E1" bool "E1"
......
Kconfig:9:error: recursive dependency detected! Kconfig:11:error: recursive dependency detected!
Kconfig:9: symbol B is selected by B Kconfig:11: symbol B is selected or implied by B
For a resolution refer to Documentation/kbuild/kconfig-language.txt For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:3:error: recursive dependency detected! Kconfig:5:error: recursive dependency detected!
Kconfig:3: symbol A depends on A Kconfig:5: symbol A depends on A
For a resolution refer to Documentation/kbuild/kconfig-language.txt For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:15:error: recursive dependency detected! Kconfig:17:error: recursive dependency detected!
Kconfig:15: symbol C1 depends on C2 Kconfig:17: symbol C1 depends on C2
Kconfig:19: symbol C2 depends on C1 Kconfig:21: symbol C2 depends on C1
For a resolution refer to Documentation/kbuild/kconfig-language.txt For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:30:error: recursive dependency detected! Kconfig:32:error: recursive dependency detected!
Kconfig:30: symbol D2 is selected by D1 Kconfig:32: symbol D2 is selected or implied by D1
Kconfig:25: symbol D1 depends on D2 Kconfig:27: symbol D1 depends on D2
For a resolution refer to Documentation/kbuild/kconfig-language.txt For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:59:error: recursive dependency detected! Kconfig:37:error: recursive dependency detected!
Kconfig:59: symbol G depends on G Kconfig:37: symbol E1 depends on E2
Kconfig:42: symbol E2 is selected or implied by E1
For a resolution refer to Documentation/kbuild/kconfig-language.txt For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:50:error: recursive dependency detected! Kconfig:60:error: recursive dependency detected!
Kconfig:50: symbol F2 depends on F1 Kconfig:60: symbol G depends on G
Kconfig:48: symbol F1 default value contains F2 For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
Kconfig:51:error: recursive dependency detected!
Kconfig:51: symbol F2 depends on F1
Kconfig:49: symbol F1 default value contains F2
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment