summaryrefslogtreecommitdiff
path: root/kconfiglib.py
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2017-10-01 20:01:08 +0200
committerUlf Magnusson <ulfalizer@gmail.com>2017-10-02 00:07:51 +0200
commit1774239986d36f4894e7f59efd953f408cbbf80a (patch)
tree1da243ff8e8eda5d33f4b6d0f826639a94c51e06 /kconfiglib.py
parent009ce631d0ba2978f51d15b0b250276a078707e8 (diff)
Make 'imply' consider direct dependencies
Bad oversight. Weak reverse dependencies (from imply) are not considered if the direct dependencies of a symbol are not met (the 'if'/'depends on' dependencies from the symbol and its parents, taking location into account if the symbol is defined in multiple places). Caused a wrong value for the symbol FS_FAT in the U-Boot Kconfigs, where 'imply' is more heavily used compared to the kernel. Add a new variable _direct_deps that corresponds to dir_dep from the C implementation. Before 'imply', dir_dep was only used for a 'select'-related warning in the C implementation. Add a bunch of tests to cover 'imply' semantics. Should be solid now.
Diffstat (limited to 'kconfiglib.py')
-rw-r--r--kconfiglib.py43
1 files changed, 31 insertions, 12 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index c111c68..795472f 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -1094,6 +1094,9 @@ class Config(object):
else:
# Symbol or Choice
+ if isinstance(stmt, Symbol):
+ stmt._direct_deps = _make_or(stmt._direct_deps, stmt._menu_dep)
+
# Propagate dependencies to prompts
if new_prompt is not None:
prompt, cond_expr = new_prompt
@@ -1608,14 +1611,20 @@ class Config(object):
for expr_sym in res:
expr_sym._dep.add(sym)
- # The directly dependent symbols of a symbol are:
+ # The directly dependent symbols of a symbol S are:
+ #
# - Any symbols whose prompts, default values, _rev_dep (select
- # condition), _weak_rev_dep (imply condition) or ranges depend on
- # the symbol
- # - Any symbols that belong to the same choice statement as the symbol
- # (these won't be included in _dep as that makes the dependency
- # graph unwieldy, but Symbol._get_dependent() will include them)
- # - Any symbols in a choice statement that depends on the symbol
+ # condition), _weak_rev_dep (imply condition) or ranges depend on S
+ #
+ # - Any symbol that has S as a direct dependency (has S in
+ # _direct_deps). This is needed to get invalidation right for
+ # 'imply'.
+ #
+ # - Any symbols that belong to the same choice statement as S
+ # (these won't be included in S._dep as that makes the dependency
+ # graph unwieldy, but S._get_dependent() will include them)
+ #
+ # - Any symbols in a choice statement that depends on S
# Only calculate _dep for defined symbols. Undefined symbols could
# theoretically be selected/implied, but it wouldn't change their value
@@ -1637,6 +1646,8 @@ class Config(object):
add_expr_deps(u, sym)
add_expr_deps(e, sym)
+ add_expr_deps(sym._direct_deps, sym)
+
if sym._is_choice_sym:
choice = sym._parent
for _, e in choice._prompts:
@@ -2098,11 +2109,14 @@ class Symbol(Item):
val = self._config._eval_min(def_expr, cond_val)
break
- weak_rev_dep_val = \
- self._config._eval_expr(self._weak_rev_dep)
- if weak_rev_dep_val != "n":
- self._write_to_conf = True
- val = self._config._eval_max(val, weak_rev_dep_val)
+ # Weak reverse dependencies are only considered if our
+ # direct dependencies are met
+ if self._config._eval_expr(self._direct_deps) != "n":
+ weak_rev_dep_val = \
+ self._config._eval_expr(self._weak_rev_dep)
+ if weak_rev_dep_val != "n":
+ self._write_to_conf = True
+ val = self._config._eval_max(val, weak_rev_dep_val)
# Reverse (select-related) dependencies take precedence
rev_dep_val = self._config._eval_expr(self._rev_dep)
@@ -2529,6 +2543,11 @@ class Symbol(Item):
# See comment in _parse_properties()
self._menu_dep = None
+ # The direct dependencies (inherited + 'depends on', with OR if a
+ # symbol is defined in multiple locations). This is needed for 'imply'
+ # support.
+ self._direct_deps = "n"
+
# See Symbol.get_ref/def_locations().
self._def_locations = []
self._ref_locations = []