Skip to content

Commit

Permalink
config: Add support for requires config option
Browse files Browse the repository at this point in the history
Support for a config option `requires` in `mbed_app.json` is added
which enables application to choose required mbed libraries. if
`requires` is mentioned in `mbed_app.json` then only those mbed
libraries and other libraries those mbed libraries depend on will be
selected. Other mbed libraries are ignored.
  • Loading branch information
urutva authored and rwalton-arm committed Dec 21, 2020
1 parent 14a25c9 commit 14a65ef
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
1 change: 1 addition & 0 deletions news/20201214165520.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for requires config option in mbed_app.json
29 changes: 25 additions & 4 deletions src/mbed_tools/build/_internal/config/assemble_build_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
from mbed_tools.build._internal.config.config import Config
from mbed_tools.build._internal.config.cumulative_data import CumulativeData
from mbed_tools.build._internal.config.source import Source
from mbed_tools.build._internal.find_files import LabelFilter, filter_files, find_files
from mbed_tools.lib.json_helpers import decode_json_file
from mbed_tools.build._internal.find_files import LabelFilter, RequiresFilter, filter_files, find_files


def assemble_config(target_attributes: dict, mbed_program_directory: Path, mbed_app_file: Optional[Path]) -> Config:
Expand All @@ -27,13 +28,23 @@ def _assemble_config_from_sources_and_lib_files(
target_attributes: dict, mbed_lib_files: Iterable[Path], mbed_app_file: Optional[Path] = None
) -> Config:
previous_cumulative_data = None
requires = list()
target_source = Source.from_target(target_attributes)
current_cumulative_data = CumulativeData.from_sources([target_source])
if mbed_app_file:
app_data = decode_json_file(mbed_app_file)
requires = app_data["requires"] if "requires" in app_data else []

while previous_cumulative_data != current_cumulative_data:
current_labels = current_cumulative_data.labels | current_cumulative_data.extra_labels
filtered_files = _filter_files(
mbed_lib_files, current_labels, current_cumulative_data.features, current_cumulative_data.components
mbed_lib_files,
current_labels,
current_cumulative_data.features,
current_cumulative_data.components,
requires,
)

mbed_lib_sources = [Source.from_mbed_lib(file, current_labels) for file in filtered_files]
all_sources = [target_source] + mbed_lib_sources
if mbed_app_file:
Expand All @@ -48,14 +59,24 @@ def _assemble_config_from_sources_and_lib_files(


def _filter_files(
files: Iterable[Path], labels: Iterable[str], features: Iterable[str], components: Iterable[str]
files: Iterable[Path],
labels: Iterable[str],
features: Iterable[str],
components: Iterable[str],
requires: Iterable[str],
) -> Iterable[Path]:
filters = (
LabelFilter("TARGET", labels),
LabelFilter("FEATURE", features),
LabelFilter("COMPONENT", components),
)
return filter_files(files, filters)
filtered_files = filter_files(files, filters)

if not requires:
return filtered_files
else:
requires_filter = RequiresFilter(requires)
return requires_filter(filtered_files)


def _update_target_attributes(target_attributes: dict, cumulative_data: CumulativeData) -> None:
Expand Down
54 changes: 53 additions & 1 deletion src/mbed_tools/build/_internal/find_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"""Find files in MbedOS program directory."""
from pathlib import Path
import fnmatch
from typing import Callable, Iterable, Optional, List, Tuple
from typing import Callable, Iterable, Optional, List, Tuple, Any, Set

from mbed_tools.lib.json_helpers import decode_json_file


def find_files(filename: str, directory: Path) -> List[Path]:
Expand Down Expand Up @@ -66,6 +68,56 @@ def filter_files(files: Iterable[Path], filters: Iterable[Callable]) -> Iterable
return [file for file in files if all(f(file) for f in filters)]


class RequiresFilter:
"""Filter out mbed libraries not needed by application.
The 'requires' config option in mbed_app.json can specify list of mbed
libraries (mbed_lib.json) that application requires. Apply 'requires'
filter to remove mbed_lib.json files not required by application.
"""

def __init__(self, requires: Iterable[str]):
"""Initialise the filter attributes.
Args:
requires: List of required mbed libraries.
"""
self._requires = requires

def __call__(self, files: Iterable[Path]) -> Iterable[Path]:
"""Apply requires filter and remove mbed_lib.json files not required by application."""
requires_filtered_files: Set[Path] = set()
return self.apply_requires_filter(requires_filtered_files, files, self._requires)

@staticmethod
def apply_requires_filter(
requires_filtered_files: set, files: Iterable[Path], requires: Iterable[str]
) -> Iterable[Path]:
"""Remove mbed_lib.json files not required by application."""
for required_mbed_lib in requires:
for mbed_lib_path in files:
lib_contents = decode_json_file(mbed_lib_path)

if required_mbed_lib == RequiresFilter.get_mbed_lib_name(lib_contents):
requires_filtered_files.add(mbed_lib_path)

RequiresFilter.apply_requires_filter(
requires_filtered_files, files, RequiresFilter.get_mbed_lib_requires(lib_contents)
)

return requires_filtered_files

@staticmethod
def get_mbed_lib_requires(lib_contents: Any) -> Any:
"""Get list of mbed libraries required by appplication."""
return lib_contents["requires"] if "requires" in lib_contents else []

@staticmethod
def get_mbed_lib_name(lib_contents: Any) -> Any:
"""Get mbed library name."""
return lib_contents["name"]


class LabelFilter:
"""Filter out given paths using path labelling rules.
Expand Down
20 changes: 20 additions & 0 deletions tests/build/test_generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,23 @@ def test_settings_from_multiple_libs_included(matching_target_and_filter, progra

assert "MBED_CONF_PLATFORM_STDIO_BAUD_RATE=9600" in config_text
assert "MBED_LFS_READ_SIZE=64" in config_text


def test_requires_config_option(program):
create_mbed_app_json(program.root, requires=["bare-metal"])
create_mbed_lib_json(program.mbed_os.root / "bare-metal" / "mbed_lib.json", "bare-metal", requires=["platform"])
create_mbed_lib_json(
program.mbed_os.root / "platform" / "mbed_lib.json", "platform", config={"stdio-baud-rate": {"value": 9600}},
)
create_mbed_lib_json(
program.mbed_os.root / "storage" / "mbed_lib.json",
"filesystem",
config={"read_size": {"macro_name": "MBED_LFS_READ_SIZE", "value": 64}},
)

generate_config("K64F", "GCC_ARM", program)

config_text = program.files.cmake_config_file.read_text()

assert "MBED_CONF_PLATFORM_STDIO_BAUD_RATE=9600" in config_text
assert "MBED_LFS_READ_SIZE=64" not in config_text

0 comments on commit 14a65ef

Please sign in to comment.