Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | # Copyright (c) 2020 Nordic Semiconductor ASA |
| 4 | # SPDX-License-Identifier: Apache-2.0 |
| 5 | |
| 6 | import argparse |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 7 | from collections import defaultdict, Counter |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 8 | from dataclasses import dataclass, field |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 9 | import itertools |
| 10 | from pathlib import Path |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 11 | import pykwalify.core |
| 12 | import sys |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 13 | from typing import List, Union |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 14 | import yaml |
| 15 | import list_hardware |
Grzegorz Swiderski | 9dabce4 | 2024-03-22 20:17:03 +0100 | [diff] [blame] | 16 | from list_hardware import unique_paths |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 17 | |
Lukasz Mrugala | b2f4321 | 2024-04-19 10:37:20 +0000 | [diff] [blame] | 18 | try: |
| 19 | from yaml import CSafeLoader as SafeLoader |
| 20 | except ImportError: |
| 21 | from yaml import SafeLoader |
| 22 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 23 | BOARD_SCHEMA_PATH = str(Path(__file__).parent / 'schemas' / 'board-schema.yml') |
| 24 | with open(BOARD_SCHEMA_PATH, 'r') as f: |
Lukasz Mrugala | b2f4321 | 2024-04-19 10:37:20 +0000 | [diff] [blame] | 25 | board_schema = yaml.load(f.read(), Loader=SafeLoader) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 26 | |
| 27 | BOARD_YML = 'board.yml' |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 28 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 29 | # |
| 30 | # This is shared code between the build system's 'boards' target |
| 31 | # and the 'west boards' extension command. If you change it, make |
| 32 | # sure to test both ways it can be used. |
| 33 | # |
| 34 | # (It's done this way to keep west optional, making it possible to run |
| 35 | # 'ninja boards' in a build directory without west installed.) |
| 36 | # |
| 37 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 38 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 39 | @dataclass |
| 40 | class Revision: |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 41 | name: str |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 42 | variants: List[str] = field(default_factory=list) |
| 43 | |
| 44 | @staticmethod |
| 45 | def from_dict(revision): |
| 46 | revisions = [] |
| 47 | for r in revision.get('revisions', []): |
| 48 | revisions.append(Revision.from_dict(r)) |
| 49 | return Revision(revision['name'], revisions) |
| 50 | |
| 51 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 52 | @dataclass |
| 53 | class Variant: |
| 54 | name: str |
| 55 | variants: List[str] = field(default_factory=list) |
| 56 | |
| 57 | @staticmethod |
| 58 | def from_dict(variant): |
| 59 | variants = [] |
| 60 | for v in variant.get('variants', []): |
| 61 | variants.append(Variant.from_dict(v)) |
| 62 | return Variant(variant['name'], variants) |
| 63 | |
| 64 | |
| 65 | @dataclass |
| 66 | class Cpucluster: |
| 67 | name: str |
| 68 | variants: List[str] = field(default_factory=list) |
| 69 | |
| 70 | |
| 71 | @dataclass |
| 72 | class Soc: |
| 73 | name: str |
| 74 | cpuclusters: List[str] = field(default_factory=list) |
| 75 | variants: List[str] = field(default_factory=list) |
| 76 | |
| 77 | @staticmethod |
| 78 | def from_soc(soc, variants): |
| 79 | if soc is None: |
| 80 | return None |
| 81 | if soc.cpuclusters: |
| 82 | cpus = [] |
| 83 | for c in soc.cpuclusters: |
| 84 | cpus.append(Cpucluster(c, |
| 85 | [Variant.from_dict(v) for v in variants if c == v['cpucluster']] |
| 86 | )) |
| 87 | return Soc(soc.name, cpuclusters=cpus) |
| 88 | return Soc(soc.name, variants=[Variant.from_dict(v) for v in variants]) |
| 89 | |
| 90 | |
| 91 | @dataclass(frozen=True) |
| 92 | class Board: |
| 93 | name: str |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 94 | # HWMv1 only supports a single Path, and requires Board dataclass to be hashable. |
| 95 | directories: Union[Path, List[Path]] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 96 | hwm: str |
Anas Nashif | 50ffc77 | 2024-10-04 07:20:29 -0400 | [diff] [blame] | 97 | full_name: str = None |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 98 | arch: str = None |
| 99 | vendor: str = None |
| 100 | revision_format: str = None |
| 101 | revision_default: str = None |
| 102 | revision_exact: bool = False |
| 103 | revisions: List[str] = field(default_factory=list, compare=False) |
| 104 | socs: List[Soc] = field(default_factory=list, compare=False) |
| 105 | variants: List[str] = field(default_factory=list, compare=False) |
| 106 | |
Grzegorz Swiderski | a1f3f88 | 2024-07-18 15:08:35 +0200 | [diff] [blame] | 107 | @property |
| 108 | def dir(self): |
| 109 | # Get the main board directory. |
| 110 | if isinstance(self.directories, Path): |
| 111 | return self.directories |
| 112 | return self.directories[0] |
| 113 | |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 114 | def from_qualifier(self, qualifiers): |
| 115 | qualifiers_list = qualifiers.split('/') |
| 116 | |
| 117 | node = Soc(None) |
| 118 | n = len(qualifiers_list) |
| 119 | if n > 0: |
| 120 | soc_qualifier = qualifiers_list.pop(0) |
| 121 | for s in self.socs: |
| 122 | if s.name == soc_qualifier: |
| 123 | node = s |
| 124 | break |
| 125 | |
| 126 | if n > 1: |
| 127 | if node.cpuclusters: |
| 128 | cpu_qualifier = qualifiers_list.pop(0) |
| 129 | for c in node.cpuclusters: |
| 130 | if c.name == cpu_qualifier: |
| 131 | node = c |
| 132 | break |
| 133 | else: |
| 134 | node = Variant(None) |
| 135 | |
| 136 | for q in qualifiers_list: |
| 137 | for v in node.variants: |
| 138 | if v.name == q: |
| 139 | node = v |
| 140 | break |
| 141 | else: |
| 142 | node = Variant(None) |
| 143 | |
| 144 | if node in (Soc(None), Variant(None)): |
| 145 | sys.exit(f'ERROR: qualifiers {qualifiers} not found when extending board {self.name}') |
| 146 | |
| 147 | return node |
| 148 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 149 | |
| 150 | def board_key(board): |
| 151 | return board.name |
| 152 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 153 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 154 | def find_arch2boards(args): |
| 155 | arch2board_set = find_arch2board_set(args) |
| 156 | return {arch: sorted(arch2board_set[arch], key=board_key) |
| 157 | for arch in arch2board_set} |
| 158 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 159 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 160 | def find_boards(args): |
| 161 | return sorted(itertools.chain(*find_arch2board_set(args).values()), |
| 162 | key=board_key) |
| 163 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 164 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 165 | def find_arch2board_set(args): |
| 166 | arches = sorted(find_arches(args)) |
| 167 | ret = defaultdict(set) |
| 168 | |
Grzegorz Swiderski | 9dabce4 | 2024-03-22 20:17:03 +0100 | [diff] [blame] | 169 | for root in unique_paths(args.board_roots): |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 170 | for arch, boards in find_arch2board_set_in(root, arches, args.board_dir).items(): |
| 171 | if args.board is not None: |
| 172 | ret[arch] |= {b for b in boards if b.name == args.board} |
| 173 | else: |
| 174 | ret[arch] |= boards |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 175 | |
| 176 | return ret |
| 177 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 178 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 179 | def find_arches(args): |
Torsten Rasmussen | c3620c8 | 2022-08-05 09:54:47 +0200 | [diff] [blame] | 180 | arch_set = set() |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 181 | |
Grzegorz Swiderski | 9dabce4 | 2024-03-22 20:17:03 +0100 | [diff] [blame] | 182 | for root in unique_paths(args.arch_roots): |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 183 | arch_set |= find_arches_in(root) |
| 184 | |
| 185 | return arch_set |
| 186 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 187 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 188 | def find_arches_in(root): |
| 189 | ret = set() |
| 190 | arch = root / 'arch' |
| 191 | common = arch / 'common' |
| 192 | |
| 193 | if not arch.is_dir(): |
| 194 | return ret |
| 195 | |
| 196 | for maybe_arch in arch.iterdir(): |
| 197 | if not maybe_arch.is_dir() or maybe_arch == common: |
| 198 | continue |
| 199 | ret.add(maybe_arch.name) |
| 200 | |
| 201 | return ret |
| 202 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 203 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 204 | def find_arch2board_set_in(root, arches, board_dir): |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 205 | ret = defaultdict(set) |
| 206 | boards = root / 'boards' |
| 207 | |
| 208 | for arch in arches: |
Torsten Rasmussen | fd772f8 | 2024-03-05 09:29:48 +0100 | [diff] [blame] | 209 | if not (boards / arch).is_dir(): |
Marcin Niestroj | 35c882d | 2021-05-08 15:36:19 +0200 | [diff] [blame] | 210 | continue |
Torsten Rasmussen | fd772f8 | 2024-03-05 09:29:48 +0100 | [diff] [blame] | 211 | for maybe_board in (boards / arch).iterdir(): |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 212 | if not maybe_board.is_dir(): |
| 213 | continue |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 214 | if board_dir and maybe_board not in board_dir: |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 215 | continue |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 216 | for maybe_defconfig in maybe_board.iterdir(): |
| 217 | file_name = maybe_defconfig.name |
Torsten Rasmussen | fd772f8 | 2024-03-05 09:29:48 +0100 | [diff] [blame] | 218 | if file_name.endswith('_defconfig') and not (maybe_board / BOARD_YML).is_file(): |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 219 | board_name = file_name[:-len('_defconfig')] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 220 | ret[arch].add(Board(board_name, maybe_board, 'v1', arch=arch)) |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 221 | |
| 222 | return ret |
| 223 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 224 | |
| 225 | def load_v2_boards(board_name, board_yml, systems): |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 226 | boards = {} |
| 227 | board_extensions = [] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 228 | if board_yml.is_file(): |
Pieter De Gendt | ca3dc01 | 2024-10-15 08:58:36 +0200 | [diff] [blame] | 229 | with board_yml.open('r', encoding='utf-8') as f: |
Lukasz Mrugala | b2f4321 | 2024-04-19 10:37:20 +0000 | [diff] [blame] | 230 | b = yaml.load(f.read(), Loader=SafeLoader) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 231 | |
| 232 | try: |
| 233 | pykwalify.core.Core(source_data=b, schema_data=board_schema).validate() |
| 234 | except pykwalify.errors.SchemaError as e: |
| 235 | sys.exit('ERROR: Malformed "build" section in file: {}\n{}' |
| 236 | .format(board_yml.as_posix(), e)) |
| 237 | |
| 238 | mutual_exclusive = {'board', 'boards'} |
| 239 | if len(mutual_exclusive - b.keys()) < 1: |
| 240 | sys.exit(f'ERROR: Malformed content in file: {board_yml.as_posix()}\n' |
| 241 | f'{mutual_exclusive} are mutual exclusive at this level.') |
| 242 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 243 | board_array = b.get('boards', [b.get('board', None)]) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 244 | for board in board_array: |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 245 | mutual_exclusive = {'name', 'extend'} |
| 246 | if len(mutual_exclusive - board.keys()) < 1: |
| 247 | sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n' |
| 248 | f'{mutual_exclusive} are mutual exclusive at this level.') |
| 249 | |
| 250 | # This is a extending an existing board, place in array to allow later processing. |
| 251 | if 'extend' in board: |
| 252 | board.update({'dir': board_yml.parent}) |
| 253 | board_extensions.append(board) |
| 254 | continue |
| 255 | |
| 256 | # Create board |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 257 | if board_name is not None: |
| 258 | if board['name'] != board_name: |
| 259 | # Not the board we're looking for, ignore. |
| 260 | continue |
| 261 | |
| 262 | board_revision = board.get('revision') |
| 263 | if board_revision is not None and board_revision.get('format') != 'custom': |
| 264 | if board_revision.get('default') is None: |
| 265 | sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n' |
| 266 | "Cannot find required key 'default'. Path: '/board/revision.'") |
| 267 | if board_revision.get('revisions') is None: |
| 268 | sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n' |
| 269 | "Cannot find required key 'revisions'. Path: '/board/revision.'") |
| 270 | |
| 271 | mutual_exclusive = {'socs', 'variants'} |
| 272 | if len(mutual_exclusive - board.keys()) < 1: |
| 273 | sys.exit(f'ERROR: Malformed "board" section in file: {board_yml.as_posix()}\n' |
| 274 | f'{mutual_exclusive} are mutual exclusive at this level.') |
| 275 | socs = [Soc.from_soc(systems.get_soc(s['name']), s.get('variants', [])) |
| 276 | for s in board.get('socs', {})] |
| 277 | |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 278 | boards[board['name']] = Board( |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 279 | name=board['name'], |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 280 | directories=[board_yml.parent], |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 281 | vendor=board.get('vendor'), |
Anas Nashif | 50ffc77 | 2024-10-04 07:20:29 -0400 | [diff] [blame] | 282 | full_name=board.get('full_name'), |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 283 | revision_format=board.get('revision', {}).get('format'), |
| 284 | revision_default=board.get('revision', {}).get('default'), |
| 285 | revision_exact=board.get('revision', {}).get('exact', False), |
| 286 | revisions=[Revision.from_dict(v) for v in |
| 287 | board.get('revision', {}).get('revisions', [])], |
| 288 | socs=socs, |
| 289 | variants=[Variant.from_dict(v) for v in board.get('variants', [])], |
| 290 | hwm='v2', |
| 291 | ) |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 292 | board_qualifiers = board_v2_qualifiers(boards[board['name']]) |
| 293 | duplicates = [q for q, n in Counter(board_qualifiers).items() if n > 1] |
| 294 | if duplicates: |
| 295 | sys.exit(f'ERROR: Duplicated board qualifiers detected {duplicates} for board: ' |
| 296 | f'{board["name"]}.\nPlease check content of: {board_yml.as_posix()}\n') |
| 297 | return boards, board_extensions |
| 298 | |
| 299 | |
| 300 | def extend_v2_boards(boards, board_extensions): |
| 301 | for e in board_extensions: |
| 302 | board = boards.get(e['extend']) |
| 303 | if board is None: |
| 304 | continue |
| 305 | board.directories.append(e['dir']) |
| 306 | |
| 307 | for v in e.get('variants', []): |
| 308 | node = board.from_qualifier(v['qualifier']) |
| 309 | if str(v['qualifier'] + '/' + v['name']) in board_v2_qualifiers(board): |
| 310 | board_yml = e['dir'] / BOARD_YML |
| 311 | sys.exit(f'ERROR: Variant: {v["name"]}, defined multiple times for board: ' |
| 312 | f'{board.name}.\nLast defined in {board_yml}') |
| 313 | node.variants.append(Variant.from_dict(v)) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 314 | |
| 315 | |
Lukasz Mrugala | 3d00574 | 2024-04-19 07:15:33 +0000 | [diff] [blame] | 316 | # Note that this does not share the args.board functionality of find_v2_boards |
| 317 | def find_v2_board_dirs(args): |
| 318 | dirs = [] |
| 319 | board_files = [] |
| 320 | for root in unique_paths(args.board_roots): |
| 321 | board_files.extend((root / 'boards').rglob(BOARD_YML)) |
| 322 | |
| 323 | dirs = [board_yml.parent for board_yml in board_files if board_yml.is_file()] |
| 324 | return dirs |
| 325 | |
| 326 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 327 | def find_v2_boards(args): |
| 328 | root_args = argparse.Namespace(**{'soc_roots': args.soc_roots}) |
| 329 | systems = list_hardware.find_v2_systems(root_args) |
| 330 | |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 331 | boards = {} |
| 332 | board_extensions = [] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 333 | board_files = [] |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 334 | if args.board_dir: |
| 335 | board_files = [d / BOARD_YML for d in args.board_dir] |
| 336 | else: |
| 337 | for root in unique_paths(args.board_roots): |
| 338 | board_files.extend((root / 'boards').rglob(BOARD_YML)) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 339 | |
| 340 | for board_yml in board_files: |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 341 | b, e = load_v2_boards(args.board, board_yml, systems) |
| 342 | conflict_boards = set(boards.keys()).intersection(b.keys()) |
| 343 | if conflict_boards: |
| 344 | sys.exit(f'ERROR: Board(s): {conflict_boards}, defined multiple times.\n' |
| 345 | f'Last defined in {board_yml}') |
| 346 | boards.update(b) |
| 347 | board_extensions.extend(e) |
| 348 | |
| 349 | extend_v2_boards(boards, board_extensions) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 350 | return boards |
| 351 | |
| 352 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 353 | def parse_args(): |
Jamie McCrae | ec70444 | 2023-01-04 16:08:36 +0000 | [diff] [blame] | 354 | parser = argparse.ArgumentParser(allow_abbrev=False) |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 355 | add_args(parser) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 356 | add_args_formatting(parser) |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 357 | return parser.parse_args() |
| 358 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 359 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 360 | def add_args(parser): |
| 361 | # Remember to update west-completion.bash if you add or remove |
| 362 | # flags |
| 363 | parser.add_argument("--arch-root", dest='arch_roots', default=[], |
| 364 | type=Path, action='append', |
Torsten Rasmussen | c3620c8 | 2022-08-05 09:54:47 +0200 | [diff] [blame] | 365 | help='add an architecture root, may be given more than once') |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 366 | parser.add_argument("--board-root", dest='board_roots', default=[], |
| 367 | type=Path, action='append', |
Torsten Rasmussen | c3620c8 | 2022-08-05 09:54:47 +0200 | [diff] [blame] | 368 | help='add a board root, may be given more than once') |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 369 | parser.add_argument("--soc-root", dest='soc_roots', default=[], |
| 370 | type=Path, action='append', |
| 371 | help='add a soc root, may be given more than once') |
| 372 | parser.add_argument("--board", dest='board', default=None, |
| 373 | help='lookup the specific board, fail if not found') |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 374 | parser.add_argument("--board-dir", default=[], type=Path, action='append', |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 375 | help='Only look for boards at the specific location') |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 376 | |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 377 | |
| 378 | def add_args_formatting(parser): |
| 379 | parser.add_argument("--cmakeformat", default=None, |
| 380 | help='''CMake Format string to use to list each board''') |
| 381 | |
| 382 | |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 383 | def variant_v2_qualifiers(variant, qualifiers = None): |
| 384 | qualifiers_list = [variant.name] if qualifiers is None else [qualifiers + '/' + variant.name] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 385 | for v in variant.variants: |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 386 | qualifiers_list.extend(variant_v2_qualifiers(v, qualifiers_list[0])) |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 387 | return qualifiers_list |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 388 | |
| 389 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 390 | def board_v2_qualifiers(board): |
| 391 | qualifiers_list = [] |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 392 | |
| 393 | for s in board.socs: |
| 394 | if s.cpuclusters: |
| 395 | for c in s.cpuclusters: |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 396 | id_str = s.name + '/' + c.name |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 397 | qualifiers_list.append(id_str) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 398 | for v in c.variants: |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 399 | qualifiers_list.extend(variant_v2_qualifiers(v, id_str)) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 400 | else: |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 401 | qualifiers_list.append(s.name) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 402 | for v in s.variants: |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 403 | qualifiers_list.extend(variant_v2_qualifiers(v, s.name)) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 404 | |
| 405 | for v in board.variants: |
Torsten Rasmussen | 88d8b23 | 2024-03-07 10:06:34 +0100 | [diff] [blame] | 406 | qualifiers_list.extend(variant_v2_qualifiers(v)) |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 407 | return qualifiers_list |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 408 | |
| 409 | |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 410 | def board_v2_qualifiers_csv(board): |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 411 | # Return in csv (comma separated value) format |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 412 | return ",".join(board_v2_qualifiers(board)) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 413 | |
| 414 | |
| 415 | def dump_v2_boards(args): |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 416 | boards = find_v2_boards(args) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 417 | |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 418 | for b in boards.values(): |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 419 | qualifiers_list = board_v2_qualifiers(b) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 420 | if args.cmakeformat is not None: |
| 421 | notfound = lambda x: x or 'NOTFOUND' |
| 422 | info = args.cmakeformat.format( |
| 423 | NAME='NAME;' + b.name, |
Torsten Rasmussen | 536d34f | 2024-05-08 13:10:48 +0200 | [diff] [blame] | 424 | DIR='DIR;' + ';'.join( |
| 425 | [str(x.as_posix()) for x in b.directories]), |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 426 | VENDOR='VENDOR;' + notfound(b.vendor), |
| 427 | HWM='HWM;' + b.hwm, |
| 428 | REVISION_DEFAULT='REVISION_DEFAULT;' + notfound(b.revision_default), |
| 429 | REVISION_FORMAT='REVISION_FORMAT;' + notfound(b.revision_format), |
| 430 | REVISION_EXACT='REVISION_EXACT;' + str(b.revision_exact), |
| 431 | REVISIONS='REVISIONS;' + ';'.join( |
| 432 | [x.name for x in b.revisions]), |
| 433 | SOCS='SOCS;' + ';'.join([s.name for s in b.socs]), |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 434 | QUALIFIERS='QUALIFIERS;' + ';'.join(qualifiers_list) |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 435 | ) |
| 436 | print(info) |
| 437 | else: |
| 438 | print(f'{b.name}') |
| 439 | |
| 440 | |
| 441 | def dump_boards(args): |
| 442 | arch2boards = find_arch2boards(args) |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 443 | for arch, boards in arch2boards.items(): |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 444 | if args.cmakeformat is None: |
| 445 | print(f'{arch}:') |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 446 | for board in boards: |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 447 | if args.cmakeformat is not None: |
| 448 | info = args.cmakeformat.format( |
| 449 | NAME='NAME;' + board.name, |
Grzegorz Swiderski | 276c1fc | 2024-07-18 15:08:35 +0200 | [diff] [blame] | 450 | DIR='DIR;' + str(board.dir.as_posix()), |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 451 | HWM='HWM;' + board.hwm, |
| 452 | VENDOR='VENDOR;NOTFOUND', |
| 453 | REVISION_DEFAULT='REVISION_DEFAULT;NOTFOUND', |
| 454 | REVISION_FORMAT='REVISION_FORMAT;NOTFOUND', |
| 455 | REVISION_EXACT='REVISION_EXACT;NOTFOUND', |
| 456 | REVISIONS='REVISIONS;NOTFOUND', |
| 457 | VARIANT_DEFAULT='VARIANT_DEFAULT;NOTFOUND', |
| 458 | SOCS='SOCS;', |
Torsten Rasmussen | 732c504 | 2024-03-19 15:26:59 +0100 | [diff] [blame] | 459 | QUALIFIERS='QUALIFIERS;' |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 460 | ) |
| 461 | print(info) |
| 462 | else: |
| 463 | print(f' {board.name}') |
| 464 | |
Martí Bolívar | 8bd6d08 | 2020-12-09 12:03:19 -0800 | [diff] [blame] | 465 | |
| 466 | if __name__ == '__main__': |
Torsten Rasmussen | 8dc3f85 | 2022-09-14 22:23:15 +0200 | [diff] [blame] | 467 | args = parse_args() |
| 468 | dump_boards(args) |
| 469 | dump_v2_boards(args) |