diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2021-02-17 19:33:16 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-23 00:51:52 +0000 |
commit | e193be9c9b02c97cb303605eb473d7a3a4ba7a65 (patch) | |
tree | de7195694b595ee8ce9679d5d65ea39d74debc9b /zephyr | |
parent | cc83ab7cf383f268452ddf8ea1ad406dbb28c885 (diff) | |
download | chrome-ec-e193be9c9b02c97cb303605eb473d7a3a4ba7a65.tar.gz |
zephyr: zmake: prune modules to only those required by the project
Implement a new configuration option: "modules", which allows projects
to require only specific modules.
This is needed for chameleon so they can only require the modules they
need (instead of all modules supported by zmake). From pfagerburg@:
When zmake pulled in one of the EC modules, that module wanted a
bunch of EC symbols to be defined in Chameleon's Kconfig, e.g.,
CROS_EC_RO and CROS_EC_RW.
BUG=b:180545676
BRANCH=none
TEST=provided unit test
Signed-off-by: Jack Rosenthal <jrosenth@chromium.org>
Change-Id: I17bf2ac9a8f75f2879e5a67b991fd60d77071c32
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2702509
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'zephyr')
-rw-r--r-- | zephyr/zmake/tests/test_project.py | 44 | ||||
-rw-r--r-- | zephyr/zmake/zmake/project.py | 42 | ||||
-rw-r--r-- | zephyr/zmake/zmake/zmake.py | 3 |
3 files changed, 89 insertions, 0 deletions
diff --git a/zephyr/zmake/tests/test_project.py b/zephyr/zmake/tests/test_project.py index 03c9d3a917..5d6fd0b5ed 100644 --- a/zephyr/zmake/tests/test_project.py +++ b/zephyr/zmake/tests/test_project.py @@ -5,9 +5,11 @@ import hypothesis import hypothesis.strategies as st import pathlib +import pytest import string import tempfile +import zmake.modules import zmake.project @@ -80,3 +82,45 @@ def test_find_dts_overlays(modules): assert actual_dts_files == set(map(str, expected_dts_files)) setup_modules_and_dispatch(modules, testcase) + + +module_lists = st.lists(st.one_of(*map(st.just, zmake.modules.known_modules)), + unique=True) + + +@hypothesis.given(module_lists) +@hypothesis.settings(deadline=None) +def test_prune_modules(modules): + """Test the Project.prune_modules method in the usual case (all + modules available).""" + module_paths = { + name: pathlib.Path('/fake/module/path', name) + for name in zmake.modules.known_modules + } + + with TemporaryProject( + {'board': 'native_posix', + 'toolchain': 'coreboot-sdk', + 'output-type': 'elf', + 'supported-zephyr-versions': ['v2.5'], + 'modules': modules}) as project: + assert set(project.prune_modules(module_paths)) == set(modules) + + +def test_prune_modules_unavailable(): + """The Project.prune_modules method should raise a KeyError when + not all modules are available.""" + + # Missing 'cmsis' + module_paths = { + 'hal_stm32': pathlib.Path('/mod/halstm'), + } + + with TemporaryProject( + {'board': 'native_posix', + 'toolchain': 'coreboot-sdk', + 'output-type': 'elf', + 'supported-zephyr-versions': ['v2.5'], + 'modules': ['hal_stm32', 'cmsis']}) as project: + with pytest.raises(KeyError): + project.prune_modules(module_paths) diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py index d6ff55a3fa..f8079ce423 100644 --- a/zephyr/zmake/zmake/project.py +++ b/zephyr/zmake/zmake/project.py @@ -14,6 +14,7 @@ with warnings.catch_warnings(): import jsonschema import zmake.build_config as build_config +import zmake.modules as modules import zmake.output_packers as packers import zmake.util as util @@ -52,6 +53,13 @@ class ProjectConfig: 'board': { 'type': 'string', }, + 'modules': { + 'type': 'array', + 'items': { + 'type': 'string', + 'enum': list(modules.known_modules), + }, + }, 'output-type': { 'type': 'string', 'enum': list(packers.packer_registry), @@ -86,6 +94,10 @@ class ProjectConfig: return self.config_dict['board'] @property + def modules(self): + return self.config_dict.get('modules', list(modules.known_modules)) + + @property def output_packer(self): return packers.packer_registry[self.config_dict['output-type']] @@ -151,3 +163,33 @@ class Project: cmake_defs={'DTC_OVERLAY_FILE': ';'.join(map(str, overlays))}) else: return build_config.BuildConfig() + + def prune_modules(self, module_paths): + """Reduce a modules dict to the ones required by this project. + + If this project does not define a modules list in the + configuration, it is assumed that all known modules to Zmake + are required. This is typically inconsequential as Zephyr + module design conventions require a Kconfig option to actually + enable most modules. + + Args: + module_paths: A dictionary mapping module names to their + paths. This dictionary is not modified. + + Returns: + A new module_paths dictionary with only the modules + required by this project. + + Raises: + A KeyError, if a required module is unavailable. + """ + result = {} + for module in self.config.modules: + try: + result[module] = module_paths[module] + except KeyError as e: + raise KeyError( + 'The {!r} module is required by the {} project, but is not ' + 'available.'.format(module, self.project_dir)) from e + return result diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py index 0cd24ee799..4dbc2fed61 100644 --- a/zephyr/zmake/zmake/zmake.py +++ b/zephyr/zmake/zmake/zmake.py @@ -132,6 +132,9 @@ class Zmake: self.module_paths['ec'] / 'zephyr' / 'include' / 'drivers'), }) + # Prune the module paths to just those required by the project. + module_paths = project.prune_modules(self.module_paths) + module_config = zmake.modules.setup_module_symlinks( build_dir / 'modules', module_paths) |