| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 | #!/usr/bin/env python3# Copyright (c) 2020 Nordic Semiconductor ASA# SPDX-License-Identifier: Apache-2.0import argparsefrom collections import defaultdictimport itertoolsfrom pathlib import Pathfrom typing import NamedTupleZEPHYR_BASE = Path(__file__).resolve().parents[1]## This is shared code between the build system's 'boards' target# and the 'west boards' extension command. If you change it, make# sure to test both ways it can be used.## (It's done this way to keep west optional, making it possible to run# 'ninja boards' in a build directory without west installed.)#class Board(NamedTuple):    name: str    arch: str    dir: Pathdef board_key(board):    return board.namedef find_arch2boards(args):    arch2board_set = find_arch2board_set(args)    return {arch: sorted(arch2board_set[arch], key=board_key)            for arch in arch2board_set}def find_boards(args):    return sorted(itertools.chain(*find_arch2board_set(args).values()),                  key=board_key)def find_arch2board_set(args):    arches = sorted(find_arches(args))    ret = defaultdict(set)    for root in itertools.chain([ZEPHYR_BASE], args.board_roots):        for arch, boards in find_arch2board_set_in(root, arches).items():            ret[arch] |= boards    return retdef find_arches(args):    arch_set = find_arches_in(ZEPHYR_BASE)    for root in args.arch_roots:        arch_set |= find_arches_in(root)    return arch_setdef find_arches_in(root):    ret = set()    arch = root / 'arch'    common = arch / 'common'    if not arch.is_dir():        return ret    for maybe_arch in arch.iterdir():        if not maybe_arch.is_dir() or maybe_arch == common:            continue        ret.add(maybe_arch.name)    return retdef find_arch2board_set_in(root, arches):    ret = defaultdict(set)    boards = root / 'boards'    for arch in arches:        if not (boards / arch).is_dir():            continue        for maybe_board in (boards / arch).iterdir():            if not maybe_board.is_dir():                continue            for maybe_defconfig in maybe_board.iterdir():                file_name = maybe_defconfig.name                if file_name.endswith('_defconfig'):                    board_name = file_name[:-len('_defconfig')]                    ret[arch].add(Board(board_name, arch, maybe_board))    return retdef parse_args():    parser = argparse.ArgumentParser()    add_args(parser)    return parser.parse_args()def add_args(parser):    # Remember to update west-completion.bash if you add or remove    # flags    parser.add_argument("--arch-root", dest='arch_roots', default=[],                        type=Path, action='append',                        help='''add an architecture root (ZEPHYR_BASE is                        always present), may be given more than once''')    parser.add_argument("--board-root", dest='board_roots', default=[],                        type=Path, action='append',                        help='''add a board root (ZEPHYR_BASE is always                        present), may be given more than once''')def dump_boards(arch2boards):    for arch, boards in arch2boards.items():        print(f'{arch}:')        for board in boards:            print(f'  {board.name}')if __name__ == '__main__':    dump_boards(find_arch2boards(parse_args()))
 |