[U-Boot] [RFC PATCH v3 2/3] tools: Add a tool to get a list of defconfigs based on filters
Jean-Jacques Hiblot
jjhiblot at ti.com
Fri Oct 26 11:14:16 UTC 2018
The possible filters are "arch", "vendor", "soc", "cpu" and "arch".
The list of all the defconfigs is read from boards.cfg. If this file
doesn't exist, then tools/genboardscfg.py is called to generate it.
Signed-off-by: Jean-Jacques Hiblot <jjhiblot at ti.com>
---
Changes in v3:
- Add more comments to describe the classes and functions
- Capitalize the Class names
Changes in v2: New
tools/find_defconfigs.py | 204 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 204 insertions(+)
create mode 100755 tools/find_defconfigs.py
diff --git a/tools/find_defconfigs.py b/tools/find_defconfigs.py
new file mode 100755
index 0000000..aac5212
--- /dev/null
+++ b/tools/find_defconfigs.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Author: JJ Hiblot <jjhiblot at ti.com>
+#
+
+"""
+Output a list of defconfig-matching criteria.
+
+The possible criteria are soc, vendor, arch, cpu, board and defconfig name.
+The criteria are expressed as regexp, allowing for complex selection.
+
+How does it work?
+-----------------
+
+This tools uses the boards.cfg file produced by tools/genboardscfg.py
+It reads the file to get a list of all the defconfigs and the information
+about the soc, vendor etc. for each of them.
+Then it walks this list and outputs the defconfigs for which the info match
+the regexp passed to the program.
+
+examples:
+---------
+
+1) Get the list of defconfigs for boards built around omap5, omap4 and k3, not built by TI
+
+$ tools/find_defconfigs.py --soc 'omap[45]|k3' --vendor '(?!ti)'
+kc1_defconfig
+duovero_defconfig
+cl-som-am57x_defconfig
+cm_t54_defconfig
+
+2) Same list but iwth more details on the items that were used as filters
+
+$ tools/find_defconfigs.py --soc 'omap[45]|k3' --vendor '(?!ti)' --show-details
+kc1_defconfig | omap4 | amazon
+duovero_defconfig | omap4 | gumstix
+cl-som-am57x_defconfig | omap5 | compulab
+cm_t54_defconfig | omap5 | compulab
+
+"""
+
+import argparse
+import os
+import re
+
+
+class Board:
+
+ """A placeholder for properties read from boards.cfg"""
+
+ def __init__(self, status, arch, cpu, soc,
+ vendor, board, target, options, maintainer):
+ self.status = status
+ self.arch = arch
+ self.cpu = cpu
+ self.soc = soc
+ self.vendor = vendor
+ self.board = board
+ self.target = target
+ self.defconfig = "{}_defconfig".format(target)
+ self.options = options
+ self.maintainer = maintainer
+
+ def show(self, sep=' | ', props=None):
+ """Show the properties of a board
+
+ Args:
+ sep: a separator insertyed between the properties for readability
+ props: the list of properties we want to display
+ """
+ if not props:
+ print(
+ sep.join([self.defconfig,
+ self.vendor,
+ self.arch,
+ self.cpu,
+ self.soc,
+ self.board,
+ self.status,
+ self.maintainer]))
+ else:
+ print(sep.join([getattr(self, prop) for prop in props]))
+
+ def match(self, rules):
+ """ match a board against a set of rules
+
+ Args:
+ rules: a set of rules. a rule is an object that offers a 'match(str)'
+ method, usually a compiled regexp.
+ Returns:
+ True if the board matches all of the rules, False otherwise
+ """
+ for prop, r in rules:
+ val = getattr(self, prop)
+ if not val or val == "-":
+ return False
+ if not r.match(val):
+ return False
+ return True
+
+
+def get_all_boards():
+ """ extract a list of boards from 'boards.cfg'
+ If boards.cfg does not exit, it is generated with tools/genboardscfg.py
+ boards.cfg is parsed to create a list of Board objects
+
+ Returns:
+ A list of Board objects that have been created based on the information
+ found in boards.cfg
+ """
+
+ result = []
+ if not os.path.isfile("boards.cfg"):
+ os.system('tools/genboardscfg.py')
+
+ with open('boards.cfg', 'r') as f:
+ for l in f.readlines():
+ if not l or l[0] == "#":
+ continue
+ props = l.strip().split(None, 8)
+ if not props:
+ continue
+ if len(props) < 9:
+ props.extend(["-"] * (9 - len(props)))
+ result.append(Board(*props))
+ return result
+
+
+def get_default_options():
+ return ["board", "soc", "vendor", "arch", "cpu", "target"]
+
+
+def update_parser_with_default_options(parser):
+ """ Augment a command line parser with a list of options commonly used to
+ filter the targets (vendor, arch, cpu, soc, board, target)
+
+ Args:
+ parser: The parser to augment
+ """
+ parser.add_argument('-i', '--ignore-case', action="store_true")
+ parser.add_argument("--soc",
+ help="regexp to filter on SoC. ex: 'omap[45]' to inspect omap5 and omap5 targets")
+ parser.add_argument("--vendor", help="regexp to filter on Vendor.")
+ parser.add_argument("--arch", help="regexp to filter on Arch")
+ parser.add_argument("--cpu", help="regexp to filter on CPU")
+ parser.add_argument("--board", help="regexp to filter on Board")
+ parser.add_argument("--target",
+ help="regexp to filter on Target (defconfig filename without the '_defconfig' suffix)")
+
+
+def get_matching_boards(args, fields=get_default_options()):
+ """ Construct a list of boards matching criteria defined in args and
+ listed in fields
+
+ Args:
+ args: an object that has some members such as 'soc','cpu' etc.
+ The values of those members are strings that will be used to compile
+ a regexp object. It must have a boolean member named "ignore_case".
+ fields: a list of names of the members we are interested in.
+
+ Returns:
+ A list of Board objects matching the given criteria
+ """
+
+ # compile a list of regexp used to filter the targets
+ boards = []
+ rules = []
+ for f in fields:
+ arg = getattr(args, f)
+ if arg:
+ rules.append((f, re.compile("\\b{}\\b".format(arg),
+ re.IGNORECASE if args.ignore_case else 0)))
+
+ # get a list of boards matching the rules
+ for b in get_all_boards():
+ if b.match(rules):
+ boards.append(b)
+ return boards
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Show CONFIG options usage")
+ update_parser_with_default_options(parser)
+ parser.add_argument("--maintainer", help="regexp to filter on maintainer.")
+ parser.add_argument("--status", help="regexp to filter on status.")
+ parser.add_argument("--show-details", help="show fields used as filter",
+ action="store_true")
+ parser.add_argument("--show-all", help="show all fields",
+ action="store_true")
+ args = parser.parse_args()
+ fields = get_default_options() + ["status", "maintainer"]
+
+ for b in get_matching_boards(args, fields):
+ if args.show_details:
+ props = ["defconfig"] + [f for f in fields if getattr(args, f)]
+ b.show(props=props)
+ elif args.show_all:
+ b.show()
+ else:
+ print(b.defconfig)
+
+if __name__ == '__main__':
+ main()
--
2.7.4
More information about the U-Boot
mailing list