zephyr/scripts/list_boards.py

117 lines
3.3 KiB
Python
Executable File

#!/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()))