aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2019-12-17 16:17:35 +0100
committerAndrey Konovalov <andreyknvl@gmail.com>2019-12-17 16:27:24 +0100
commita6bc9c88b9c64a9b25f560ee6c4d784ff27d0c7d (patch)
tree55210b9d6e861a2a576e6b9a2ef7278851b5b7d8
parent1af3875f3f0015538d778e5710e26bc94822f2fc (diff)
dashboard/config: update USB config extraction
Currently the config extraction script can produce an incorrect result, when one of the configs enables a particular config option, but some other one doesn't. This change fixes the issue.
-rwxr-xr-xdashboard/config/kconfiglib-merge-usb-configs.py140
-rwxr-xr-xdashboard/config/util.sh5
2 files changed, 83 insertions, 62 deletions
diff --git a/dashboard/config/kconfiglib-merge-usb-configs.py b/dashboard/config/kconfiglib-merge-usb-configs.py
index 2ac685d91..f4196e764 100755
--- a/dashboard/config/kconfiglib-merge-usb-configs.py
+++ b/dashboard/config/kconfiglib-merge-usb-configs.py
@@ -26,89 +26,101 @@ def unpack_dep_expr(expr):
return r
# Extract item dependencies recursively.
-def extract_deps(item):
+def extract_item_deps(item):
deps = set()
handled = set()
- def extract_deps_impl(item):
+ def extract_item_deps_impl(item):
if item in handled:
return
handled.add(item)
sub = unpack_dep_expr(item.direct_dep)
deps.update(sub)
for sub_item in sub:
- extract_deps_impl(sub_item)
- extract_deps_impl(item)
+ extract_item_deps_impl(sub_item)
+ extract_item_deps_impl(item)
return deps
-# Extract all dependencies for a list of nodes.
-def extract_nodes_deps(nodes):
+# Extract all dependencies for a list of items.
+def extract_items_deps(items):
deps = set()
- for node in nodes:
- deps.update(extract_deps(node.item))
+ for item in items:
+ deps.update(extract_item_deps(item))
return deps
+# Returns true if an item depends on any of the given symbols.
def item_depends_on_syms(item, syms):
- return len(syms.intersection(extract_deps(item))) > 0
+ return len(syms.intersection(extract_item_deps(item))) > 0
-if len(sys.argv) < 3:
- sys.exit('Usage: {} usb.config'.format(sys.argv[0]))
-
-# Load config given in SCRIPT_ARG.
-base_kconf = kconfiglib.Kconfig(warn=False)
-base_kconf.load_config(sys.argv[2])
-
-# Make a list of some core USB symbols.
-# Some USB drivers don't depend on core USB symbols, but rather depend on a
+# A list of some core USB symbol names.
+# Some USB drivers don't depend on any USB related symbols, but rather on a
# generic symbol for some input subsystem (e.g. HID), so include those as well.
core_usb_syms_names = ['USB_SUPPORT', 'USB', 'USB_ARCH_HAS_HCD', 'HID']
-core_usb_syms = set([base_kconf.syms[name] for name in core_usb_syms_names])
-# Extract all enabled (as =y or =m) USB nodes. A USB node is detected as a
-# node, which depends on least one USB core symbol.
-usb_nodes = set()
-for node in base_kconf.node_iter():
- if node.item.__class__ not in [kconfiglib.Symbol, kconfiglib.Choice]:
- continue
- if node.item.tri_value == 0:
- continue
- if item_depends_on_syms(node.item, core_usb_syms):
- usb_nodes.add(node)
-print('USB nodes:', len(usb_nodes))
-
-# Extract USB nodes dependencies.
-deps = extract_nodes_deps(usb_nodes)
-print('USB nodes dependencies:', len(deps))
-
-# Extract choice options to be disabled to only leave the last option enabled
-# for each choice.
-exclude = set()
-for dep in deps:
- if dep.__class__ is not kconfiglib.Choice:
+def extract_usb_items_and_deps(kconf):
+ core_usb_syms = set([kconf.syms[name] for name in core_usb_syms_names])
+
+ # Extract all enabled (as =y or =m) USB items.
+ # A USB item is an item that depends on least one core USB symbol.
+ usb_items = set()
+ for node in kconf.node_iter():
+ if node.item.__class__ not in [kconfiglib.Symbol, kconfiglib.Choice]:
+ continue
+ if node.item.tri_value == 0:
+ continue
+ if item_depends_on_syms(node.item, core_usb_syms):
+ usb_items.add(node.item)
+
+ # Extract USB items dependencies.
+ dep_items = extract_items_deps(usb_items)
+
+ # For consistency leave only the last option enabled for each choice.
+ exclude = set()
+ for item in dep_items:
+ if item.__class__ is not kconfiglib.Choice:
+ continue
+ for sym in item.syms[:-1]:
+ exclude.add(sym)
+ dep_items = filter(lambda item: item not in exclude, dep_items)
+ usb_items = filter(lambda item: item not in exclude, usb_items)
+
+ print('USB items:', len(usb_items))
+ print('USB dependencies:', len(dep_items))
+
+ return (usb_items, dep_items)
+
+if len(sys.argv) < 3:
+ sys.exit('Usage: {} <usb1.config>,<usb2.config>,...'.format(sys.argv[0]))
+
+# Load configs given in SCRIPT_ARG.
+base_kconfs = []
+for config in sys.argv[2].split(','):
+ if len(config) == 0:
continue
- for sym in dep.syms[:-1]:
- exclude.add(sym)
-print('Excluded choice options:', len(exclude))
+ kconf = kconfiglib.Kconfig(warn=False)
+ kconf.load_config(config)
+ base_kconfs.append(kconf)
+
+base_items = []
+for kconf in base_kconfs:
+ base_items.append(extract_usb_items_and_deps(kconf))
# Load current .config.
new_kconf = kconfiglib.Kconfig(warn=False)
new_kconf.load_config()
-# First, enable all extracted dependencies.
-for dep in deps:
- if dep.__class__ is kconfiglib.Symbol:
- if dep in exclude:
- continue
- new_kconf.syms[dep.name].set_value(2)
+for (usb_items, dep_items) in base_items:
+ # First, enable all extracted dependencies as =y.
+ for item in dep_items:
+ if item.__class__ is kconfiglib.Symbol:
+ new_kconf.syms[item.name].set_value(2)
-# Then, enable extracted USB nodes as =y.
-for node in list(usb_nodes):
- if node.item.__class__ is kconfiglib.Symbol:
- if node.item in exclude:
- continue
- new_kconf.syms[node.item.name].set_value(2)
+ # Then, enable extracted USB items as =y.
+ for item in usb_items:
+ if item.__class__ is kconfiglib.Symbol:
+ new_kconf.syms[item.name].set_value(2)
-# Now, disable USB symbols that are disabled in the base config, as they might
-# have been enabled when some of the dependecies got enabled.
+# Now, disable USB symbols that are disabled in all of the base configs,
+# as they might have been enabled when some of the dependecies got enabled.
to_disable = []
core_usb_syms = set([new_kconf.syms[name] for name in core_usb_syms_names])
for node in new_kconf.node_iter():
@@ -116,10 +128,16 @@ for node in new_kconf.node_iter():
continue
if not item_depends_on_syms(node.item, core_usb_syms):
continue
- sym = base_kconf.syms.get(node.item.name)
- if not sym:
- to_disable.append(node.item.name)
- if sym.tri_value == 0:
+ disable = True
+ for kconf in base_kconfs:
+ sym = kconf.syms.get(node.item.name)
+ if not sym:
+ continue
+ if sym.tri_value == 0:
+ continue
+ disable = False
+ break
+ if disable:
to_disable.append(node.item.name)
for name in to_disable:
new_kconf.syms[name].set_value(0)
diff --git a/dashboard/config/util.sh b/dashboard/config/util.sh
index 4bdd1aa8c..765052860 100755
--- a/dashboard/config/util.sh
+++ b/dashboard/config/util.sh
@@ -20,9 +20,12 @@ function util_add_usb_bits {
git clone --depth=1 https://github.com/ulfalizer/Kconfiglib.git
wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1
+
+ configs=""
for config in ${THIS_DIR}/distros/*; do
- make ${MAKE_VARS} scriptconfig SCRIPT=${MERGE_USB_SCRIPT} SCRIPT_ARG=${config}
+ configs+="${config},"
done
+ make ${MAKE_VARS} scriptconfig SCRIPT=${MERGE_USB_SCRIPT} SCRIPT_ARG=${configs}
git checkout ./scripts/kconfig/Makefile
rm -rf ./Kconfiglib