diff --git a/doc/guides/west/build-flash-debug.rst b/doc/guides/west/build-flash-debug.rst index afc67231b5..b04448e362 100644 --- a/doc/guides/west/build-flash-debug.rst +++ b/doc/guides/west/build-flash-debug.rst @@ -3,9 +3,9 @@ Building, Flashing and Debugging ################################ -West provides 5 commands for building, flashing, and interacting with Zephyr -programs running on a board: ``build``, ``flash``, ``debug``, ``debugserver`` -and ``attach``. +Zephyr provides several :ref:`west extension commands ` for +building, flashing, and interacting with Zephyr programs running on a board: +``build``, ``flash``, ``debug``, ``debugserver`` and ``attach``. These use information stored in the CMake cache [#cmakecache]_ to flash or attach a debugger to a board supported by Zephyr. The exception is @@ -61,6 +61,10 @@ no additional parameters. whether ``-b`` is required, just try leaving it out. West will print an error if the option is required and was not given. +.. tip:: + You can use the :ref:`west boards ` command to list all + supported boards. + Specify the source directory path as the first positional argument:: west build -b path/to/source/directory diff --git a/doc/guides/west/extensions.rst b/doc/guides/west/extensions.rst index f770c66497..dd35f563a3 100644 --- a/doc/guides/west/extensions.rst +++ b/doc/guides/west/extensions.rst @@ -11,12 +11,14 @@ information on west extension commands, and has a tutorial for writing your own. Some commands you can run when using west with Zephyr, like the ones used to -:ref:`build, flash, and debug `, are extensions. That's -why help for them shows up like this in ``west --help``: +:ref:`build, flash, and debug ` and the +:ref:`ones described here ` , are extensions. That's why +help for them shows up like this in ``west --help``: .. code-block:: none commands from project at "zephyr": + boards: display information about supported boards build: compile a Zephyr application sign: sign a Zephyr binary for bootloader chain-loading flash: flash and run a binary on a board diff --git a/doc/guides/west/index.rst b/doc/guides/west/index.rst index 91cf5f831b..b17931e778 100644 --- a/doc/guides/west/index.rst +++ b/doc/guides/west/index.rst @@ -38,6 +38,7 @@ context about the tool. config.rst extensions.rst build-flash-debug.rst + zephyr-cmds.rst sign.rst why.rst without-west.rst diff --git a/doc/guides/west/zephyr-cmds.rst b/doc/guides/west/zephyr-cmds.rst new file mode 100644 index 0000000000..92f0b6a364 --- /dev/null +++ b/doc/guides/west/zephyr-cmds.rst @@ -0,0 +1,39 @@ +.. _west-zephyr-ext-cmds: + +Additional Zephyr extension commands +#################################### + +Aside from the :ref:`build, flash, and debug commands `, +the zephyr tree extends the west command set with additional zephyr-specific +commands. + +.. Add a per-page contents at the top of the page. This page is nested + deeply enough that it doesn't have any subheadings in the main nav. + +.. only:: html + + .. contents:: + :local: + +.. _west-boards: + +Listing boards: ``west boards`` +******************************* + +The ``boards`` command can be used to list the boards that are supported by +Zephyr without having to resort to additional sources of information. + +It can be run by typing:: + + west boards + +This command lists all supported boards in a default format. If you prefer to +specify the display format yourself you can use the ``--format`` (or ``-f``) +flag:: + + west boards -f "{arch}:{name}" + +Additional help about the formatting options can be found by running:: + + west boards -h + diff --git a/scripts/west-commands.yml b/scripts/west-commands.yml index e86fe7f999..807489b1ee 100644 --- a/scripts/west-commands.yml +++ b/scripts/west-commands.yml @@ -1,5 +1,10 @@ # Keep the help strings in sync with the values in the .py files! west-commands: + - file: scripts/west_commands/boards.py + commands: + - name: boards + class: Boards + help: display information about supported boards - file: scripts/west_commands/build.py commands: - name: build diff --git a/scripts/west_commands/boards.py b/scripts/west_commands/boards.py new file mode 100644 index 0000000000..e324959bcd --- /dev/null +++ b/scripts/west_commands/boards.py @@ -0,0 +1,94 @@ +# Copyright (c) 2019 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import collections +import os +import re +import textwrap + +from west import log +from west.commands import WestCommand +from cmake import run_cmake + +class Boards(WestCommand): + + def __init__(self): + super().__init__( + 'boards', + # Keep this in sync with the string in west-commands.yml. + 'display information about supported boards', + 'Display information about boards', + accepts_unknown_args=False) + + def do_add_parser(self, parser_adder): + default_fmt = '{name} ({arch})' + parser = parser_adder.add_parser( + self.name, + help=self.help, + formatter_class=argparse.RawDescriptionHelpFormatter, + description=self.description, + epilog=textwrap.dedent('''\ + FORMAT STRINGS + + Boards are listed using a Python 3 format string. Arguments + to the format string are accessed by name. + + The default format string is: + + "{}" + + The following arguments are available: + + - name: board name + - arch: board architecture + '''.format(default_fmt))) + + # Remember to update scripts/west-completion.bash if you add or remove + # flags + parser.add_argument('-f', '--format', default=default_fmt, + help='''Format string to use to list each board; + see FORMAT STRINGS below.'''), + + return parser + + def do_run(self, args, unknown_args): + zb = os.environ.get('ZEPHYR_BASE') + if not zb: + log.die('Internal error: ZEPHYR_BASE not set in the environment, ' + 'and should have been by the main script') + + cmake_args = ['-DBOARD_ROOT_SPACE_SEPARATED={}'.format(zb), + '-P', '{}/cmake/boards.cmake'.format(zb)] + lines = run_cmake(cmake_args, capture_output=True) + arch_re = re.compile(r'\s*([\w-]+)\:') + board_re = re.compile(r'\s*([\w-]+)\s*') + arch = None + boards = collections.OrderedDict() + for line in lines: + match = arch_re.match(line) + if match: + arch = match.group(1) + boards[arch] = [] + continue + match = board_re.match(line) + if match: + if not arch: + log.die('Invalid board output from CMake: {}'.format(lines)) + board = match.group(1) + boards[arch].append(board) + + for arch in boards: + for board in boards[arch]: + try: + result = args.format.format( + name=board, + arch=arch) + print(result) + except KeyError as e: + # The raised KeyError seems to just put the first + # invalid argument in the args tuple, regardless of + # how many unrecognizable keys there were. + log.die('unknown key "{}" in format string "{}"'. + format(e.args[0], args.format))