zephyr/scripts/west_commands/domains.py
Torsten Rasmussen 8408af6d7c scripts: west commands to support --domain
This commit extends the west commands build, flash, and debug to support
--domain when having multiple domains (images) defined in a domains.yaml
build file.

The domains.yaml uses the following yaml format to specify the
build directory of each domain in the multi image build:
> default: <domain-n>
> domains:
>   <domain-1>:
>     build_dir: <build_dir-domain-1>
>   <domain-2>:
>     build_dir: <build_dir-domain-2>
>   ...

`west <build|flash|debug>` has been extended to support
`--domain <domain>`.

`west build` calls CMake to create the build system, and if `--domain`
is given, then the build tool will be invoked afterwards for the
specified domain.

`west flash` will default flash all domains, but `--domain <domain>`
argument can be used to select a specific domain to flash, for example:
> west flash --domain mcuboot

`west debug` only a single domain can be debugged at any given time.
If `--domain` is not specified, then the default domain specified in the
domains.yml file will be used.
Users can still select a different domain, for example with:
> west debug --domain mcuboot

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2022-08-03 16:05:07 +02:00

140 lines
3.4 KiB
Python

# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
'''Domain handling for west extension commands.
This provides parsing of domains yaml file and creation of objects of the
Domain class.
'''
import yaml
import pykwalify.core
from west import log
DOMAINS_SCHEMA = '''
## A pykwalify schema for basic validation of the structure of a
## domains YAML file.
##
# The domains.yaml file is a simple list of domains from a multi image build
# along with the default domain to use.
type: map
mapping:
default:
required: true
type: str
build_dir:
required: true
type: str
domains:
required: false
type: seq
sequence:
- type: map
mapping:
name:
required: true
type: str
build_dir:
required: true
type: str
'''
schema = yaml.safe_load(DOMAINS_SCHEMA)
class Domains:
def __init__(self, data):
self._domains = []
self._domain_names = []
self._domain_default = []
self._build_dir = data.get('build_dir')
domain_list = data.get('domains')
if not domain_list:
log.wrn("no domains defined; this probably won't work")
for d in domain_list:
domain = Domain(d['name'], d['build_dir'])
self._domains.append(domain)
self._domain_names.append(domain.name)
if domain.name == data['default']:
self._default_domain = domain
@staticmethod
def from_file(domains_file):
'''Load domains from domains.yaml.
Exception raised:
- ``FileNotFoundError`` if the domains file is not found.
'''
try:
with open(domains_file, 'r') as f:
domains = yaml.safe_load(f.read())
except FileNotFoundError:
log.die(f'domains.yaml file not found: {domains_file}')
try:
pykwalify.core.Core(source_data=domains, schema_data=schema)\
.validate()
except pykwalify.errors.SchemaError:
log.die(f'ERROR: Malformed yaml in file: {domains_file}')
return Domains(domains)
@staticmethod
def from_data(domains_data):
'''Load domains from domains dictionary.
'''
return Domains(domains_data)
def get_domains(self, names=None):
ret = []
if not names:
return self._domains
for n in names:
found = False
for d in self._domains:
if n == d.name:
ret.append(d)
found = True
break
# Getting here means the domain was not found.
# Todo: throw an error.
if not found:
log.die(f'domain {n} not found, '
f'valid domains are:', *self._domain_names)
return ret
def get_default_domain(self):
return self._default_domain
def get_top_build_dir(self):
return self._build_dir
class Domain:
def __init__(self, name, build_dir):
self.name = name
self.build_dir = build_dir
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
@property
def build_dir(self):
return self._build_dir
@build_dir.setter
def build_dir(self, value):
self._build_dir = value