kbuild: Warn on selecting symbols with unmet direct dependencies
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 8 Jun 2010 16:25:57 +0000 (17:25 +0100)
committerMichal Marek <mmarek@suse.cz>
Fri, 2 Jul 2010 12:53:09 +0000 (14:53 +0200)
The "select" statement in Kconfig files allows the enabling of options
even if they have unmet direct dependencies (i.e. "depends on" expands
to "no"). Currently, the "depends on" clauses are used in calculating
the visibility but they do not affect the reverse dependencies in any
way.

The patch introduces additional tracking of the "depends on" statements
and prints a warning on selecting an option if its direct dependencies
are not met.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
scripts/kconfig/expr.h
scripts/kconfig/menu.c
scripts/kconfig/symbol.c

index 891cd9ce9ba21b915d0b0aa993fc2d0c8d2fb10c..75a31e4552f32d8889f446f345e5173413f24855 100644 (file)
@@ -83,6 +83,7 @@ struct symbol {
        tristate visible;
        int flags;
        struct property *prop;
+       struct expr_value dir_dep;
        struct expr_value rev_dep;
 };
 
@@ -163,6 +164,7 @@ struct menu {
        struct symbol *sym;
        struct property *prompt;
        struct expr *dep;
+       struct expr *dir_dep;
        unsigned int flags;
        char *help;
        struct file *file;
index eef17bacb6bca6aab1d9096a28690d701f7bea2b..11799894f3bda59425415545b9533db72f70b819 100644 (file)
@@ -105,6 +105,7 @@ static struct expr *menu_check_dep(struct expr *e)
 void menu_add_dep(struct expr *dep)
 {
        current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+       current_entry->dir_dep = current_entry->dep;
 }
 
 void menu_set_type(int type)
@@ -288,6 +289,10 @@ void menu_finalize(struct menu *parent)
                for (menu = parent->list; menu; menu = menu->next)
                        menu_finalize(menu);
        } else if (sym) {
+               /* ignore inherited dependencies for dir_dep */
+               sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
+               sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
+
                basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
                basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
                basedep = expr_eliminate_dups(expr_transform(basedep));
index 2e7a048e0cfceb32970d4d0a6fa8b211d70ef83e..174b230a52b0cb0f66000896daa1bdae2d87dc13 100644 (file)
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
        }
        if (sym_is_choice_value(sym))
                return;
+       /* defaulting to "yes" if no explicit "depends on" are given */
+       tri = yes;
+       if (sym->dir_dep.expr)
+               tri = expr_calc_value(sym->dir_dep.expr);
+       if (tri == mod)
+               tri = yes;
+       if (sym->dir_dep.tri != tri) {
+               sym->dir_dep.tri = tri;
+               sym_set_changed(sym);
+       }
        tri = no;
        if (sym->rev_dep.expr)
                tri = expr_calc_value(sym->rev_dep.expr);
@@ -321,6 +331,14 @@ void sym_calc_value(struct symbol *sym)
                                }
                        }
                calc_newval:
+                       if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
+                               fprintf(stderr, "warning: (");
+                               expr_fprint(sym->rev_dep.expr, stderr);
+                               fprintf(stderr, ") selects %s which has unmet direct dependencies (",
+                                       sym->name);
+                               expr_fprint(sym->dir_dep.expr, stderr);
+                               fprintf(stderr, ")\n");
+                       }
                        newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
                }
                if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)