Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kconfig: improve the recursive dependency report

This commit improves the messages of the recursive dependency.
Currently, sym->dir_dep.expr is not checked. Hence, any dependency
in property visibility is regarded as the dependency of the symbol.

[Test Code 1]

config A
bool "a"
depends on B

config B
bool "b"
depends on A

[Test Code 2]

config A
bool "a" if B

config B
bool "b"
depends on A

For both cases above, the same message is displayed:

symbol B depends on A
symbol A depends on B

This commit changes the message for the latter, like this:

symbol B depends on A
symbol A prompt is visible depending on B

Also, 'select' and 'imply' are distinguished.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Tested-by: Dirk Gouders <dirk@gouders.net>

+39 -19
+36 -16
scripts/kconfig/symbol.c
··· 1011 1011 struct dep_stack *prev, *next; 1012 1012 struct symbol *sym; 1013 1013 struct property *prop; 1014 - struct expr *expr; 1014 + struct expr **expr; 1015 1015 } *check_top; 1016 1016 1017 1017 static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) ··· 1076 1076 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", 1077 1077 prop->file->name, prop->lineno); 1078 1078 1079 - if (stack->expr) { 1080 - fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", 1081 - prop->file->name, prop->lineno, 1082 - sym->name ? sym->name : "<choice>", 1083 - prop_get_type_name(prop->type), 1084 - next_sym->name ? next_sym->name : "<choice>"); 1085 - } else if (stack->prop) { 1086 - fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", 1087 - prop->file->name, prop->lineno, 1088 - sym->name ? sym->name : "<choice>", 1089 - next_sym->name ? next_sym->name : "<choice>"); 1090 - } else if (sym_is_choice(sym)) { 1079 + if (sym_is_choice(sym)) { 1091 1080 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", 1092 1081 menu->file->name, menu->lineno, 1093 1082 sym->name ? sym->name : "<choice>", ··· 1086 1097 menu->file->name, menu->lineno, 1087 1098 sym->name ? sym->name : "<choice>", 1088 1099 next_sym->name ? next_sym->name : "<choice>"); 1089 - } else { 1090 - fprintf(stderr, "%s:%d:\tsymbol %s is selected or implied by %s\n", 1100 + } else if (stack->expr == &sym->dir_dep.expr) { 1101 + fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", 1091 1102 prop->file->name, prop->lineno, 1092 1103 sym->name ? sym->name : "<choice>", 1104 + next_sym->name ? next_sym->name : "<choice>"); 1105 + } else if (stack->expr == &sym->rev_dep.expr) { 1106 + fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", 1107 + prop->file->name, prop->lineno, 1108 + sym->name ? sym->name : "<choice>", 1109 + next_sym->name ? next_sym->name : "<choice>"); 1110 + } else if (stack->expr == &sym->implied.expr) { 1111 + fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", 1112 + prop->file->name, prop->lineno, 1113 + sym->name ? sym->name : "<choice>", 1114 + next_sym->name ? next_sym->name : "<choice>"); 1115 + } else if (stack->expr) { 1116 + fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", 1117 + prop->file->name, prop->lineno, 1118 + sym->name ? sym->name : "<choice>", 1119 + prop_get_type_name(prop->type), 1120 + next_sym->name ? next_sym->name : "<choice>"); 1121 + } else { 1122 + fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", 1123 + prop->file->name, prop->lineno, 1124 + sym->name ? sym->name : "<choice>", 1125 + prop_get_type_name(prop->type), 1093 1126 next_sym->name ? next_sym->name : "<choice>"); 1094 1127 } 1095 1128 } ··· 1168 1157 1169 1158 dep_stack_insert(&stack, sym); 1170 1159 1160 + stack.expr = &sym->dir_dep.expr; 1161 + sym2 = sym_check_expr_deps(sym->dir_dep.expr); 1162 + if (sym2) 1163 + goto out; 1164 + 1165 + stack.expr = &sym->rev_dep.expr; 1171 1166 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1172 1167 if (sym2) 1173 1168 goto out; 1174 1169 1170 + stack.expr = &sym->implied.expr; 1175 1171 sym2 = sym_check_expr_deps(sym->implied.expr); 1176 1172 if (sym2) 1177 1173 goto out; 1174 + 1175 + stack.expr = NULL; 1178 1176 1179 1177 for (prop = sym->prop; prop; prop = prop->next) { 1180 1178 if (prop->type == P_CHOICE || prop->type == P_SELECT || ··· 1195 1175 break; 1196 1176 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1197 1177 continue; 1198 - stack.expr = prop->expr; 1178 + stack.expr = &prop->expr; 1199 1179 sym2 = sym_check_expr_deps(prop->expr); 1200 1180 if (sym2) 1201 1181 break;
+3 -3
scripts/kconfig/tests/err_recursive_dep/expected_stderr
··· 1 1 Kconfig:11:error: recursive dependency detected! 2 - Kconfig:11: symbol B is selected or implied by B 2 + Kconfig:11: symbol B is selected by B 3 3 For a resolution refer to Documentation/kbuild/kconfig-language.txt 4 4 subsection "Kconfig recursive dependency limitations" 5 5 ··· 15 15 subsection "Kconfig recursive dependency limitations" 16 16 17 17 Kconfig:32:error: recursive dependency detected! 18 - Kconfig:32: symbol D2 is selected or implied by D1 18 + Kconfig:32: symbol D2 is selected by D1 19 19 Kconfig:27: symbol D1 depends on D2 20 20 For a resolution refer to Documentation/kbuild/kconfig-language.txt 21 21 subsection "Kconfig recursive dependency limitations" 22 22 23 23 Kconfig:37:error: recursive dependency detected! 24 24 Kconfig:37: symbol E1 depends on E2 25 - Kconfig:42: symbol E2 is selected or implied by E1 25 + Kconfig:42: symbol E2 is implied by E1 26 26 For a resolution refer to Documentation/kbuild/kconfig-language.txt 27 27 subsection "Kconfig recursive dependency limitations" 28 28