diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2022-03-16 13:33:38 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-03-17 00:08:06 +0000 |
commit | 73d2fc626440800e4e92d93b3bd88f0362fa50a2 (patch) | |
tree | 7b3b1fd77e46b045a6a4ab11d859c44bd1ab930f | |
parent | 5081c7ce7527c977b8eca37fb4a561863d91b75b (diff) | |
download | chrome-ec-73d2fc626440800e4e92d93b3bd88f0362fa50a2.tar.gz |
zephyr: zmake: Add a syntax to make simple variants of a build
Add a BUILD.py syntax to copy another project and make simple
modifications.
BUG=b:224998797
BRANCH=none
TEST=provided unit test passes
Signed-off-by: Jack Rosenthal <jrosenth@chromium.org>
Change-Id: I87f0fe6b0e02c3ac34bec6de09d38e620fc293e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3530957
Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
-rw-r--r-- | docs/zephyr/project_config.md | 20 | ||||
-rw-r--r-- | zephyr/zmake/tests/test_project.py | 26 | ||||
-rw-r--r-- | zephyr/zmake/zmake/configlib.py | 12 | ||||
-rw-r--r-- | zephyr/zmake/zmake/project.py | 46 |
4 files changed, 94 insertions, 10 deletions
diff --git a/docs/zephyr/project_config.md b/docs/zephyr/project_config.md index 9f658ef62c..664e7b0c64 100644 --- a/docs/zephyr/project_config.md +++ b/docs/zephyr/project_config.md @@ -149,7 +149,7 @@ Below is an example of how programs may wish to structure this in # found in the LICENSE file. def register_variant(project_name, chip="it8xx2", extra_dts_overlays=()): - register_binman_project( + return register_binman_project( project_name=project_name, zephyr_board=chip, dts_overlays=[ @@ -172,3 +172,21 @@ register_variant( extra_dts_overlays=[here / "hayato_gpios.dts"], ) ``` + +If a project is going to be a simple variant of another project (e.g., +project `bar` is exactly identical to project `foo` but has just a few +device-tree/Kconfig changes), you can spin a new variant using the +return value of the register functions: + +``` python +foo = register_variant(project_name="foo") +bar = foo.variant( + project_name="bar", + dts_overlays=[here / "bar_extras.dts"], +) +``` + +With this simple variant syntax, lists (like Kconfig files and DTS +overlays) are concatenated. This means it's not possible to remove +files during variant registration for this syntax, so it's only +recommended for the simple case. diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py index f7688784e7..f4808d14d5 100644 --- a/zephyr/zmake/tests/test_project.py +++ b/zephyr/zmake/tests/test_project.py @@ -192,6 +192,32 @@ def test_find_projects_name_conflict(tmp_path): zmake.project.find_projects(tmp_path) +def test_register_variant(tmp_path): + (tmp_path / "BUILD.py").write_text( + """ +some = register_raw_project( + project_name="some", + zephyr_board="foo", + dts_overlays=[here / "gpio.dts"], +) + +some_variant = some.variant(project_name="some-variant", zephyr_board="bar") +another = some_variant.variant( + project_name="another", + dts_overlays=[here / "another.dts"], +) + """ + ) + projects = zmake.project.find_projects(tmp_path) + assert projects["some"].config.zephyr_board == "foo" + assert projects["some-variant"].config.zephyr_board == "bar" + assert projects["another"].config.zephyr_board == "bar" + assert projects["another"].config.dts_overlays == [ + tmp_path / "gpio.dts", + tmp_path / "another.dts", + ] + + @pytest.mark.parametrize( ("actual_files", "config_files", "expected_files"), [ diff --git a/zephyr/zmake/zmake/configlib.py b/zephyr/zmake/zmake/configlib.py index 1e6223b2cb..a0463f1a86 100644 --- a/zephyr/zmake/zmake/configlib.py +++ b/zephyr/zmake/zmake/configlib.py @@ -11,32 +11,32 @@ def _register_project(**kwargs): kwargs.setdefault( "project_dir", here # noqa: F821 pylint: disable=undefined-variable ) - register_project(**kwargs) # noqa: F821 pylint: disable=undefined-variable + return register_project(**kwargs) # noqa: F821 pylint: disable=undefined-variable def register_host_project(**kwargs): kwargs.setdefault("zephyr_board", "native_posix") kwargs.setdefault("supported_toolchains", ["llvm", "host"]) kwargs.setdefault("output_packer", zmake.output_packers.ElfPacker) - _register_project(**kwargs) + return _register_project(**kwargs) def register_host_test(test_name, **kwargs): kwargs.setdefault("is_test", True) - register_host_project(project_name="test-{}".format(test_name), **kwargs) + return register_host_project(project_name="test-{}".format(test_name), **kwargs) def register_raw_project(**kwargs): kwargs.setdefault("supported_toolchains", ["coreboot-sdk", "zephyr"]) kwargs.setdefault("output_packer", zmake.output_packers.RawBinPacker) - _register_project(**kwargs) + return _register_project(**kwargs) def register_binman_project(**kwargs): kwargs.setdefault("output_packer", zmake.output_packers.BinmanPacker) - register_raw_project(**kwargs) + return register_raw_project(**kwargs) def register_npcx_project(**kwargs): kwargs.setdefault("output_packer", zmake.output_packers.NpcxPacker) - register_binman_project(**kwargs) + return register_binman_project(**kwargs) diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py index b2c36cbb33..b2232bb263 100644 --- a/zephyr/zmake/zmake/project.py +++ b/zephyr/zmake/zmake/project.py @@ -6,7 +6,7 @@ import dataclasses import logging import pathlib -from typing import Dict, List +from typing import Callable, Dict, List import zmake.build_config as build_config import zmake.configlib as configlib @@ -154,6 +154,41 @@ class Project: ) +@dataclasses.dataclass +class ProjectRegistrationHandler: + """Return value of register_project. + + This is intended to be used to create simple variants of a project + like so:: + + brd = register_project(project_name="brd", ...) + brd_changed = brd.variant(project_name="brd-changed", ...) + brd_changed_again = brd_changed.variant(project_name="brd-changed-again", ...) + """ + + base_config: ProjectConfig + register_func: Callable[[], "ProjectRegistrationHandler"] + + def variant(self, **kwargs) -> "ProjectRegistrationHandler": + """Register a new variant based on the base config. + + Args: + kwargs: Any project config changes. Note lists will be + concatenated. + + Returns: + Another ProjectRegistrationHandler. + """ + new_config = dataclasses.asdict(self.base_config) + for key, value in kwargs.items(): + if isinstance(value, list): + new_config[key] = [*new_config[key], *value] + else: + new_config[key] = value + + return self.register_func(**new_config) + + def load_config_file(path) -> List[Project]: """Load a BUILD.py config file and create associated projects. @@ -165,8 +200,13 @@ def load_config_file(path) -> List[Project]: """ projects: List[Project] = [] - def register_project(**kwargs): - projects.append(Project(ProjectConfig(**kwargs))) + def register_project(**kwargs) -> ProjectRegistrationHandler: + config = ProjectConfig(**kwargs) + projects.append(Project(config)) + return ProjectRegistrationHandler( + base_config=config, + register_func=register_project, + ) # The Python environment passed to the config file. config_globals = { |