diff options
-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) |