Drop genboardscfg.py
authorSimon Glass <sjg@chromium.org>
Tue, 12 Jul 2022 01:04:10 +0000 (19:04 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 5 Aug 2022 15:47:56 +0000 (11:47 -0400)
Now that buildman can generate this with the -R option, drop the script.

Signed-off-by: Simon Glass <sjg@chromium.org>
Suggested-by: Tom Rini <trini@konsulko.com>
scripts/pylint.base
tools/genboardscfg.py [deleted file]

index 9ebebf4..dd6360e 100644 (file)
@@ -201,7 +201,6 @@ tools_dtoc_test_fdt 6.88
 tools_dtoc_test_src_scan 9.43
 tools_efivar 6.71
 tools_endian-swap 9.29
-tools_genboardscfg 7.95
 tools_microcode-tool 7.25
 tools_moveconfig 8.34
 tools_patman___init__ 0.00
diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py
deleted file mode 100755 (executable)
index 07bf681..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0+
-#
-# Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
-#
-
-"""
-Converter from Kconfig and MAINTAINERS to a board database.
-
-Run 'tools/genboardscfg.py' to create a board database.
-
-Run 'tools/genboardscfg.py -h' for available options.
-"""
-
-import errno
-import fnmatch
-import glob
-import multiprocessing
-import optparse
-import os
-import sys
-import tempfile
-import time
-
-from buildman import kconfiglib
-
-### constant variables ###
-OUTPUT_FILE = 'boards.cfg'
-CONFIG_DIR = 'configs'
-SLEEP_TIME = 0.03
-COMMENT_BLOCK = '''#
-# List of boards
-#   Automatically generated by %s: don't edit
-#
-# Status, Arch, CPU, SoC, Vendor, Board, Target, Options, Maintainers
-
-''' % __file__
-
-### helper functions ###
-def try_remove(f):
-    """Remove a file ignoring 'No such file or directory' error."""
-    try:
-        os.remove(f)
-    except OSError as exception:
-        # Ignore 'No such file or directory' error
-        if exception.errno != errno.ENOENT:
-            raise
-
-def check_top_directory():
-    """Exit if we are not at the top of source directory."""
-    for f in ('README', 'Licenses'):
-        if not os.path.exists(f):
-            sys.exit('Please run at the top of source directory.')
-
-def output_is_new(output):
-    """Check if the output file is up to date.
-
-    Returns:
-      True if the given output file exists and is newer than any of
-      *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.
-    """
-    try:
-        ctime = os.path.getctime(output)
-    except OSError as exception:
-        if exception.errno == errno.ENOENT:
-            # return False on 'No such file or directory' error
-            return False
-        else:
-            raise
-
-    for (dirpath, dirnames, filenames) in os.walk(CONFIG_DIR):
-        for filename in fnmatch.filter(filenames, '*_defconfig'):
-            if fnmatch.fnmatch(filename, '.*'):
-                continue
-            filepath = os.path.join(dirpath, filename)
-            if ctime < os.path.getctime(filepath):
-                return False
-
-    for (dirpath, dirnames, filenames) in os.walk('.'):
-        for filename in filenames:
-            if (fnmatch.fnmatch(filename, '*~') or
-                not fnmatch.fnmatch(filename, 'Kconfig*') and
-                not filename == 'MAINTAINERS'):
-                continue
-            filepath = os.path.join(dirpath, filename)
-            if ctime < os.path.getctime(filepath):
-                return False
-
-    # Detect a board that has been removed since the current board database
-    # was generated
-    with open(output, encoding="utf-8") as f:
-        for line in f:
-            if line[0] == '#' or line == '\n':
-                continue
-            defconfig = line.split()[6] + '_defconfig'
-            if not os.path.exists(os.path.join(CONFIG_DIR, defconfig)):
-                return False
-
-    return True
-
-### classes ###
-class KconfigScanner:
-
-    """Kconfig scanner."""
-
-    ### constant variable only used in this class ###
-    _SYMBOL_TABLE = {
-        'arch' : 'SYS_ARCH',
-        'cpu' : 'SYS_CPU',
-        'soc' : 'SYS_SOC',
-        'vendor' : 'SYS_VENDOR',
-        'board' : 'SYS_BOARD',
-        'config' : 'SYS_CONFIG_NAME',
-        'options' : 'SYS_EXTRA_OPTIONS'
-    }
-
-    def __init__(self):
-        """Scan all the Kconfig files and create a Kconfig object."""
-        # Define environment variables referenced from Kconfig
-        os.environ['srctree'] = os.getcwd()
-        os.environ['UBOOTVERSION'] = 'dummy'
-        os.environ['KCONFIG_OBJDIR'] = ''
-        self._conf = kconfiglib.Kconfig(warn=False)
-
-    def __del__(self):
-        """Delete a leftover temporary file before exit.
-
-        The scan() method of this class creates a temporay file and deletes
-        it on success.  If scan() method throws an exception on the way,
-        the temporary file might be left over.  In that case, it should be
-        deleted in this destructor.
-        """
-        if hasattr(self, '_tmpfile') and self._tmpfile:
-            try_remove(self._tmpfile)
-
-    def scan(self, defconfig):
-        """Load a defconfig file to obtain board parameters.
-
-        Arguments:
-          defconfig: path to the defconfig file to be processed
-
-        Returns:
-          A dictionary of board parameters.  It has a form of:
-          {
-              'arch': <arch_name>,
-              'cpu': <cpu_name>,
-              'soc': <soc_name>,
-              'vendor': <vendor_name>,
-              'board': <board_name>,
-              'target': <target_name>,
-              'config': <config_header_name>,
-              'options': <extra_options>
-          }
-        """
-        # strip special prefixes and save it in a temporary file
-        fd, self._tmpfile = tempfile.mkstemp()
-        with os.fdopen(fd, 'w') as f:
-            for line in open(defconfig):
-                colon = line.find(':CONFIG_')
-                if colon == -1:
-                    f.write(line)
-                else:
-                    f.write(line[colon + 1:])
-
-        self._conf.load_config(self._tmpfile)
-        try_remove(self._tmpfile)
-        self._tmpfile = None
-
-        params = {}
-
-        # Get the value of CONFIG_SYS_ARCH, CONFIG_SYS_CPU, ... etc.
-        # Set '-' if the value is empty.
-        for key, symbol in list(self._SYMBOL_TABLE.items()):
-            value = self._conf.syms.get(symbol).str_value
-            if value:
-                params[key] = value
-            else:
-                params[key] = '-'
-
-        defconfig = os.path.basename(defconfig)
-        params['target'], match, rear = defconfig.partition('_defconfig')
-        assert match and not rear, '%s : invalid defconfig' % defconfig
-
-        # fix-up for aarch64
-        if params['arch'] == 'arm' and params['cpu'] == 'armv8':
-            params['arch'] = 'aarch64'
-
-        # fix-up options field. It should have the form:
-        # <config name>[:comma separated config options]
-        if params['options'] != '-':
-            params['options'] = params['config'] + ':' + \
-                                params['options'].replace(r'\"', '"')
-        elif params['config'] != params['target']:
-            params['options'] = params['config']
-
-        return params
-
-def scan_defconfigs_for_multiprocess(queue, defconfigs):
-    """Scan defconfig files and queue their board parameters
-
-    This function is intended to be passed to
-    multiprocessing.Process() constructor.
-
-    Arguments:
-      queue: An instance of multiprocessing.Queue().
-             The resulting board parameters are written into it.
-      defconfigs: A sequence of defconfig files to be scanned.
-    """
-    kconf_scanner = KconfigScanner()
-    for defconfig in defconfigs:
-        queue.put(kconf_scanner.scan(defconfig))
-
-def read_queues(queues, params_list):
-    """Read the queues and append the data to the paramers list"""
-    for q in queues:
-        while not q.empty():
-            params_list.append(q.get())
-
-def scan_defconfigs(jobs=1):
-    """Collect board parameters for all defconfig files.
-
-    This function invokes multiple processes for faster processing.
-
-    Arguments:
-      jobs: The number of jobs to run simultaneously
-    """
-    all_defconfigs = []
-    for (dirpath, dirnames, filenames) in os.walk(CONFIG_DIR):
-        for filename in fnmatch.filter(filenames, '*_defconfig'):
-            if fnmatch.fnmatch(filename, '.*'):
-                continue
-            all_defconfigs.append(os.path.join(dirpath, filename))
-
-    total_boards = len(all_defconfigs)
-    processes = []
-    queues = []
-    for i in range(jobs):
-        defconfigs = all_defconfigs[total_boards * i // jobs :
-                                    total_boards * (i + 1) // jobs]
-        q = multiprocessing.Queue(maxsize=-1)
-        p = multiprocessing.Process(target=scan_defconfigs_for_multiprocess,
-                                    args=(q, defconfigs))
-        p.start()
-        processes.append(p)
-        queues.append(q)
-
-    # The resulting data should be accumulated to this list
-    params_list = []
-
-    # Data in the queues should be retrieved preriodically.
-    # Otherwise, the queues would become full and subprocesses would get stuck.
-    while any([p.is_alive() for p in processes]):
-        read_queues(queues, params_list)
-        # sleep for a while until the queues are filled
-        time.sleep(SLEEP_TIME)
-
-    # Joining subprocesses just in case
-    # (All subprocesses should already have been finished)
-    for p in processes:
-        p.join()
-
-    # retrieve leftover data
-    read_queues(queues, params_list)
-
-    return params_list
-
-class MaintainersDatabase:
-
-    """The database of board status and maintainers."""
-
-    def __init__(self):
-        """Create an empty database."""
-        self.database = {}
-
-    def get_status(self, target):
-        """Return the status of the given board.
-
-        The board status is generally either 'Active' or 'Orphan'.
-        Display a warning message and return '-' if status information
-        is not found.
-
-        Returns:
-          'Active', 'Orphan' or '-'.
-        """
-        if not target in self.database:
-            print("WARNING: no status info for '%s'" % target, file=sys.stderr)
-            return '-'
-
-        tmp = self.database[target][0]
-        if tmp.startswith('Maintained'):
-            return 'Active'
-        elif tmp.startswith('Supported'):
-            return 'Active'
-        elif tmp.startswith('Orphan'):
-            return 'Orphan'
-        else:
-            print(("WARNING: %s: unknown status for '%s'" %
-                                  (tmp, target)), file=sys.stderr)
-            return '-'
-
-    def get_maintainers(self, target):
-        """Return the maintainers of the given board.
-
-        Returns:
-          Maintainers of the board.  If the board has two or more maintainers,
-          they are separated with colons.
-        """
-        if not target in self.database:
-            print("WARNING: no maintainers for '%s'" % target, file=sys.stderr)
-            return ''
-
-        return ':'.join(self.database[target][1])
-
-    def parse_file(self, file):
-        """Parse a MAINTAINERS file.
-
-        Parse a MAINTAINERS file and accumulates board status and
-        maintainers information.
-
-        Arguments:
-          file: MAINTAINERS file to be parsed
-        """
-        targets = []
-        maintainers = []
-        status = '-'
-        for line in open(file, encoding="utf-8"):
-            # Check also commented maintainers
-            if line[:3] == '#M:':
-                line = line[1:]
-            tag, rest = line[:2], line[2:].strip()
-            if tag == 'M:':
-                maintainers.append(rest)
-            elif tag == 'F:':
-                # expand wildcard and filter by 'configs/*_defconfig'
-                for f in glob.glob(rest):
-                    front, match, rear = f.partition('configs/')
-                    if not front and match:
-                        front, match, rear = rear.rpartition('_defconfig')
-                        if match and not rear:
-                            targets.append(front)
-            elif tag == 'S:':
-                status = rest
-            elif line == '\n':
-                for target in targets:
-                    self.database[target] = (status, maintainers)
-                targets = []
-                maintainers = []
-                status = '-'
-        if targets:
-            for target in targets:
-                self.database[target] = (status, maintainers)
-
-def insert_maintainers_info(params_list):
-    """Add Status and Maintainers information to the board parameters list.
-
-    Arguments:
-      params_list: A list of the board parameters
-    """
-    database = MaintainersDatabase()
-    for (dirpath, dirnames, filenames) in os.walk('.'):
-        if 'MAINTAINERS' in filenames:
-            database.parse_file(os.path.join(dirpath, 'MAINTAINERS'))
-
-    for i, params in enumerate(params_list):
-        target = params['target']
-        params['status'] = database.get_status(target)
-        params['maintainers'] = database.get_maintainers(target)
-        params_list[i] = params
-
-def format_and_output(params_list, output):
-    """Write board parameters into a file.
-
-    Columnate the board parameters, sort lines alphabetically,
-    and then write them to a file.
-
-    Arguments:
-      params_list: The list of board parameters
-      output: The path to the output file
-    """
-    FIELDS = ('status', 'arch', 'cpu', 'soc', 'vendor', 'board', 'target',
-              'options', 'maintainers')
-
-    # First, decide the width of each column
-    max_length = dict([ (f, 0) for f in FIELDS])
-    for params in params_list:
-        for f in FIELDS:
-            max_length[f] = max(max_length[f], len(params[f]))
-
-    output_lines = []
-    for params in params_list:
-        line = ''
-        for f in FIELDS:
-            # insert two spaces between fields like column -t would
-            line += '  ' + params[f].ljust(max_length[f])
-        output_lines.append(line.strip())
-
-    # ignore case when sorting
-    output_lines.sort(key=str.lower)
-
-    with open(output, 'w', encoding="utf-8") as f:
-        f.write(COMMENT_BLOCK + '\n'.join(output_lines) + '\n')
-
-def gen_boards_cfg(output, jobs=1, force=False, quiet=False):
-    """Generate a board database file.
-
-    Arguments:
-      output: The name of the output file
-      jobs: The number of jobs to run simultaneously
-      force: Force to generate the output even if it is new
-      quiet: True to avoid printing a message if nothing needs doing
-    """
-    check_top_directory()
-
-    if not force and output_is_new(output):
-        if not quiet:
-            print("%s is up to date. Nothing to do." % output)
-        sys.exit(0)
-
-    params_list = scan_defconfigs(jobs)
-    insert_maintainers_info(params_list)
-    format_and_output(params_list, output)
-
-def main():
-    try:
-        cpu_count = multiprocessing.cpu_count()
-    except NotImplementedError:
-        cpu_count = 1
-
-    parser = optparse.OptionParser()
-    # Add options here
-    parser.add_option('-f', '--force', action="store_true", default=False,
-                      help='regenerate the output even if it is new')
-    parser.add_option('-j', '--jobs', type='int', default=min(cpu_count, 240),
-                      help='the number of jobs to run simultaneously')
-    parser.add_option('-o', '--output', default=OUTPUT_FILE,
-                      help='output file [default=%s]' % OUTPUT_FILE)
-    parser.add_option('-q', '--quiet', action="store_true", help='run silently')
-    (options, args) = parser.parse_args()
-
-    gen_boards_cfg(options.output, jobs=options.jobs, force=options.force,
-                   quiet=options.quiet)
-
-if __name__ == '__main__':
-    main()