From: Simon Glass Date: Wed, 19 Jul 2023 23:48:21 +0000 (-0600) Subject: buildman: Detect boards with multiple CONFIG_TARGETs defined X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=bec06ed8920ccf570ee80436488dd6426733bb15;p=u-boot.git buildman: Detect boards with multiple CONFIG_TARGETs defined The TARGET_xxx options are special in that they refer to a single target. Exactly one should be enabled for each target, corresponding to a defconfig file. Detect configs which result in two TARGET_xxx options being set. For example, at present, TARGET_POLEG and TARET_POLEG_EVB are enabled for the same board. Note: This warning is not displayed by default. An option will be added to enable it. Signed-off-by: Simon Glass --- diff --git a/tools/buildman/boards.py b/tools/buildman/boards.py index 2d39326300..56fb6f4de6 100644 --- a/tools/buildman/boards.py +++ b/tools/buildman/boards.py @@ -220,16 +220,17 @@ class KconfigScanner: defconfig (str): path to the defconfig file to be processed Returns: - A dictionary of board parameters. It has a form of: - { - 'arch': , - 'cpu': , - 'soc': , - 'vendor': , - 'board': , - 'target': , - 'config': , - } + tuple: dictionary of board parameters. It has a form of: + { + 'arch': , + 'cpu': , + 'soc': , + 'vendor': , + 'board': , + 'target': , + 'config': , + } + warnings (list of str): list of warnings found """ leaf = os.path.basename(defconfig) expect_target, match, rear = leaf.partition('_defconfig') @@ -239,6 +240,7 @@ class KconfigScanner: self._tmpfile = None params = {} + warnings = [] # Get the value of CONFIG_SYS_ARCH, CONFIG_SYS_CPU, ... etc. # Set '-' if the value is empty. @@ -249,6 +251,17 @@ class KconfigScanner: else: params[key] = '-' + # Check there is exactly one TARGET_xxx set + target = None + for name, sym in self._conf.syms.items(): + if name.startswith('TARGET_') and sym.str_value == 'y': + tname = name[7:].lower() + if target: + warnings.append( + f'WARNING: {leaf}: Duplicate TARGET_xxx: {target} and {tname}') + else: + target = tname + params['target'] = expect_target # fix-up for aarch64 @@ -266,7 +279,7 @@ class KconfigScanner: else: params['arch'] = 'riscv64' - return params + return params, warnings class MaintainersDatabase: @@ -658,11 +671,19 @@ class Boards: queue.put(kconf_scanner.scan(defconfig)) @classmethod - def read_queues(cls, queues, params_list): - """Read the queues and append the data to the paramers list""" + def read_queues(cls, queues, params_list, warnings): + """Read the queues and append the data to the paramers list + + Args: + queues (list of multiprocessing.Queue): Queues to read + params_list (list of dict): List to add params too + warnings (set of str): Set to add warnings to + """ for que in queues: while not que.empty(): - params_list.append(que.get()) + params, warn = que.get() + params_list.append(params) + warnings.update(warn) def scan_defconfigs(self, config_dir, srcdir, jobs=1): """Collect board parameters for all defconfig files. @@ -675,9 +696,12 @@ class Boards: jobs (int): The number of jobs to run simultaneously Returns: - list of dict: List of board parameters, each a dict: - key: 'arch', 'cpu', 'soc', 'vendor', 'board', 'target', 'config' - value: string value of the key + tuple: + list of dict: List of board parameters, each a dict: + key: 'arch', 'cpu', 'soc', 'vendor', 'board', 'target', + 'config' + value: string value of the key + list of str: List of warnings recorded """ all_defconfigs = [] for (dirpath, _, filenames) in os.walk(config_dir): @@ -700,13 +724,14 @@ class Boards: processes.append(proc) queues.append(que) - # The resulting data should be accumulated to this list + # The resulting data should be accumulated to these lists params_list = [] + warnings = set() # 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): - self.read_queues(queues, params_list) + self.read_queues(queues, params_list, warnings) # sleep for a while until the queues are filled time.sleep(SLEEP_TIME) @@ -716,9 +741,9 @@ class Boards: proc.join() # retrieve leftover data - self.read_queues(queues, params_list) + self.read_queues(queues, params_list, warnings) - return params_list + return params_list, sorted(list(warnings)) @classmethod def insert_maintainers_info(cls, srcdir, params_list): @@ -797,9 +822,9 @@ class Boards: value: string value of the key list of str: Warnings that came up """ - params_list = self.scan_defconfigs(config_dir, srcdir, jobs) - warnings = self.insert_maintainers_info(srcdir, params_list) - return params_list, warnings + params_list, warnings = self.scan_defconfigs(config_dir, srcdir, jobs) + m_warnings = self.insert_maintainers_info(srcdir, params_list) + return params_list, warnings + m_warnings def ensure_board_list(self, output, jobs=1, force=False, quiet=False): """Generate a board database file if needed. diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index eb1fa9f0b8..154fa61c08 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -794,10 +794,11 @@ CONFIG_LOCALVERSION=y # Scan the test directory which contains a Kconfig and some *_defconfig # files - params = self._boards.scan_defconfigs(src, src) + params, warnings = self._boards.scan_defconfigs(src, src) # We should get two boards self.assertEquals(2, len(params)) + self.assertFalse(warnings) first = 0 if params[0]['target'] == 'board0' else 1 board0 = params[first] board2 = params[1 - first] @@ -882,6 +883,7 @@ Active aarch64 armv8 - armltd total_compute board2 src = self._git_dir main = os.path.join(src, 'boards', 'board0', 'MAINTAINERS') other = os.path.join(src, 'boards', 'board2', 'MAINTAINERS') + kc_file = os.path.join(src, 'Kconfig') config_dir = os.path.join(src, 'configs') params_list, warnings = self._boards.build_board_list(config_dir, src) @@ -946,3 +948,19 @@ Active aarch64 armv8 - armltd total_compute board2 self.assertEquals( ['WARNING: orphaned defconfig in boards/board0/MAINTAINERS ending at line 16'], warnings) + + # Add another TARGET to the Kconfig + tools.write_file(main, data, binary=False) + extra = (b''' +if TARGET_BOARD2 +config TARGET_OTHER +\tbool "other" +\tdefault y +endif +''') + tools.write_file(kc_file, tools.read_file(kc_file) + extra) + params_list, warnings = self._boards.build_board_list(config_dir, src) + self.assertEquals(2, len(params_list)) + self.assertEquals( + ['WARNING: board2_defconfig: Duplicate TARGET_xxx: board2 and other'], + warnings)