Перевод статьи Zephyr West Tips and TricksNoah Pendleton, Interrupt (Memfault), апрель 2026 года.

Инструмент Zephyr west — мощный менеджер воркспейсов, но, надо признать, довольно перегруженный функционалом: внутри него скрыто много возможностей!

Я подумал, что будет интересно поделиться несколькими приёмами, которые я использую с west, чтобы сделать мой рабочий процесс разработки под Zephyr немного плавнее.

Управление SDK с помощью west sdk#

West имеет встроенную команду для управления Zephyr SDK:

# установить конкретную версию SDK и целевой тулчейн
west sdk install --version 0.17.4 -t arm-zephyr-eabi

Вы можете установить только те тулчейны, которые действительно нужны, вместо загрузки полного пакета SDK. Некоторые другие полезные цели:

  • riscv64-zephyr-elf
  • xtensa-espressif_esp32_zephyr-elf

Запустите west sdk list, чтобы увидеть, что доступно, и west sdk install --help для полного набора опций.

Что замечательно: если запустить это из воркспейса west, содержащего проект zephyr, west sdk install подхватит значение zephyr/SDK_VERSION, так что вы получите соответствующую версию SDK — проще простого!

  --version [SDK_VER]  version of the Zephyr SDK to install. If not specified,
                       the install version is detected from
                       ${ZEPHYR_BASE}/SDK_VERSION file.

Это подробно рассмотрено в Practical Zephyr - West workspaces (Part 6), определённо стоит прочитать, если ещё не читали.

Ограничение глубины клона с clone-depth#

Если вы работаете с большими репозиториями или часто инициализируете новые воркспейсы, вы можете добавить clone-depth к проектам в вашем манифесте west, чтобы значительно ускорить процесс:

# west.yml
manifest:
  projects:
    - name: some-large-repo
      url: https://github.com/example/some-large-repo
      clone-depth: 1

Полная справка по манифесту: https://docs.zephyrproject.org/latest/develop/west/manifest.html#projects

Примечание: Я не уверен, учитывается ли clone-depth для проектов, которые подтягиваются транзитивно через import. Стоит проверить для вашей конкретной конфигурации воркспейса.

Ограничение того, что импортирует west update#

По умолчанию, если вы импортируете манифест проекта (например, west.yml Zephyr), west склонирует все его перечисленные зависимости рекурсивно. У Zephyr их много, и наивный west update может легко скачать гигабайты репозиториев, которые вам не нужны.

Два параметра манифеста, которые здесь очень помогают:

name-allowlist — Импортировать только названные проекты из вышестоящего манифеста:

# west.yml
manifest:
  projects:
    - name: zephyr
      url: https://github.com/zephyrproject-rtos/zephyr
      revision: v4.3.0
      import:
        name-allowlist:
          - cmsis
          - hal_nordic
          - mbedtls

Это Option 3 в документации по манифесту и, вероятно, самое полезное, что вы можете сделать для быстрой инициализации воркспейса.

path-prefix — Поместить все импортированные проекты в общий подкаталог вместо корня воркспейса. Держит всё в порядке:

import:
  path-prefix: deps
  name-allowlist:
    - cmsis
    - hal_nordic

С вышеуказанным импортированные репозитории попадают в deps/, а не разбросаны по верхнему уровню. Статья Practical Zephyr - West workspaces проходит через полный рабочий пример обоих вместе.

Кеширование загрузок west update#

Если вы часто клонируете воркспейсы west (например, при тестировании незнакомых проектов), трафик git fetch может быстро накапливаться. West поддерживает reference cache для общего хранилища объектов между воркспейсами:

west config --global update.auto-cache ~/.cache/west

С auto-cache west автоматически заполняет и использует директорию кеша, так что последующие вызовы west update в новых воркспейсах могут разрешать большинство объектов локально вместо обращения к сети.

Есть несколько других полезных опций конфигурации update.*, которые стоит посмотреть в справке: https://docs.zephyrproject.org/latest/develop/west/config.html#built-in-configuration-options

Алиасы#

West поддерживает пользовательские алиасы команд, похожие на алиасы git. Они отлично подходят для сокращения рабочих процессов, которые вы запускаете постоянно. Из документации:

west config --global alias.run "build --pristine=never --target run"
west config --global alias.menuconfig "build --pristine=never --target menuconfig"

После этого west run и west menuconfig просто работают. В документации по алиасам есть больше примеров: https://docs.zephyrproject.org/latest/develop/west/alias.html#examples

Расширения West#

Расширения West позволяют проектам (или вашему собственному локальному инструментарию) добавлять пользовательские подкоманды к west. Это полезно, когда вы хотите, чтобы проектно-специфичный инструментарий ощущался как первоклассный гражданин в вашем рабочем процессе, а не как отдельный скрипт (особенно приятно для discoverability, поскольку всё доступно из west --help).

Это полезно, когда нужные вам команды не вписываются в обычный рабочий процесс build/flash/debug/attach, предоставляемый собственными командами расширений Zephyr SDK, и алиасов недостаточно.

Быстрый пример: мы добавляем следующие файлы/фрагменты в наш репозиторий манифеста:

west.yml:

manifest:
  self:
    # register this repo's west extensions
    west-commands: scripts/west-commands.yml

scripts/west-commands.yml:

west-commands:
  - file: scripts/west_extensions.py
    commands:
      - name: project-hello
        class: ProjectHello
        help: sample Project west extension command

scripts/west_extensions.py:

from textwrap import dedent

from west.commands import WestCommand

class ProjectHello(WestCommand):
    def __init__(self):
        super().__init__(
            "project-hello",  # gets stored as self.name
            "",  # ignored self.help, will not be required by future west versions
            description=dedent(
                """
                Sample Project west extension command.
                """
            ),
        )

    def do_add_parser(self, parser_adder):
        parser = parser_adder.add_parser(self.name, description=self.description)

        levels = ["dbg", "inf", "wrn", "err"]
        parser.add_argument(
            "-l",
            "--level",
            default="inf",
            choices=levels,
            help="log level for the message (default: %(default)s)",
        )
        parser.add_argument("message", help="message to print")

        return parser  # gets stored as self.parser

    def do_run(self, args, unknown):
        log_fn = {
            "dbg": self.dbg,
            "inf": self.inf,
            "wrn": self.wrn,
            "err": self.err,
        }[args.level]

        self.inf(f"[{self.name}] log level: {args.level}")
        log_fn(f"[{self.name}] message: {args.message}")

Теперь новое расширение появляется в west --help:

extension commands from project manifest (path: blahblah):
  project-hello: sample Project west extension command

И мы можем запустить его:

❯ west project-hello --level err 'Hello!'
[project-hello] log level: err
ERROR: [project-hello] message: Hello!

Справка Zephyr подробно описывает, как это сделать: https://docs.zephyrproject.org/latest/develop/west/extensions.html#west-extensions

Сокращение того, что скачивает west update#

Для повседневной разработки вам часто не нужна полная история каждой зависимости. Вы можете значительно ускорить west update с помощью пары флагов:

west update --narrow --fetch-opt=--depth=1
  • --narrow указывает west скачивать только конкретную ревизию, указанную в манифесте, а не все refs с удалённого сервера.
  • --fetch-opt=--depth=1 передаёт --depth=1 в underlying git fetch, давая вам shallow clone только с tip-коммитом.

Вместе они могут dramatically сократить сетевой трафик и использование диска, особенно при первой инициализации большого воркспейса.

Используйте git fetch --unshallow на модуле, чтобы позже преобразовать shallow clone в полный — это полезно, если вам нужна полная история (например, для bisecting) или вы хотите внести вклад в upstream!

Разрешение манифеста в точные SHA#

Манифесты West обычно ссылаются на ветки или теги, которые могут drift со временем. Чтобы захватить полностью разрешённый снимок с точными SHA коммитов — полезно для воспроизводимых сборок или аудита — используйте:

west manifest --resolve

Вывод — валидный манифест west с каждым проектом, прибитым к конкретной ревизии:

manifest:
  group-filter:
    - -babblesim
    - -optional
    - -testing
  projects:
    - name: canopennode
      url: https://github.com/zephyrproject-rtos/canopennode
      revision: dec12fa3f0d790cafa8414a4c2930ea71ab72ffd
      path: modules/lib/canopennode
      groups:
        - optional
    - name: chre
      url: https://github.com/zephyrproject-rtos/chre
      revision: c4c2f49fdcaa2fed49eb1db027696a5734a010d2
      path: modules/lib/chre
      groups:
        - optional
    # ...

Вы можете перенаправить это в west.lock.yml (или аналогичный) и закоммитить рядом с вашим манифестом, чтобы любой, клонирующий воркспейс, получил точно такое же дерево.