blob: 92478f92a7c08287d4a7d6d96fa28c4a48d97a6d [file] [log] [blame]
#!/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
#
# 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 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 = set()
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, may be given more than once')
parser.add_argument("--board-root", dest='board_roots', default=[],
type=Path, action='append',
help='add a board root, 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()))