123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #!/usr/bin/env python3
- # Copyright (c) 2020 Nordic Semiconductor ASA
- # SPDX-License-Identifier: Apache-2.0
- import argparse
- from collections import defaultdict
- import itertools
- from pathlib import Path
- from typing import NamedTuple
- ZEPHYR_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: Path
- def board_key(board):
- return board.name
- def 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 ret
- def find_arches(args):
- arch_set = find_arches_in(ZEPHYR_BASE)
- for root in args.arch_roots:
- arch_set |= find_arches_in(root)
- return arch_set
- def 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 ret
- def 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 ret
- def 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()))
|