summaryrefslogtreecommitdiff
path: root/zephyr/zmake/zmake/project.py
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/zmake/zmake/project.py')
-rw-r--r--zephyr/zmake/zmake/project.py180
1 files changed, 68 insertions, 112 deletions
diff --git a/zephyr/zmake/zmake/project.py b/zephyr/zmake/zmake/project.py
index 7ffe4ebc19..62a3b7dd00 100644
--- a/zephyr/zmake/zmake/project.py
+++ b/zephyr/zmake/zmake/project.py
@@ -3,24 +3,14 @@
# found in the LICENSE file.
"""Module for project config wrapper object."""
+import dataclasses
import logging
import pathlib
-import warnings
-
-import yaml
import zmake.build_config as build_config
+import zmake.configlib as configlib
import zmake.modules as modules
-import zmake.output_packers as packers
import zmake.toolchains as toolchains
-import zmake.util as util
-
-# The version of jsonschema in the chroot has a bunch of
-# DeprecationWarnings that fire when we import it. Suppress these
-# during the import to keep the noise down.
-with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- import jsonschema
def module_dts_overlay_name(modpath, board_name):
@@ -36,121 +26,87 @@ def module_dts_overlay_name(modpath, board_name):
return modpath / "zephyr" / "dts" / "board-overlays" / "{}.dts".format(board_name)
-def find_projects(root_dir):
- """Finds all zmake projects in root_dir.
+def load_config_file(path):
+ """Load a BUILD.py config file and create associated projects.
Args:
- root_dir: the root dir as a pathlib.Path object
+ path: A pathlib.Path to the BUILD.py file.
- Yields:
- Project: The next project found.
+ Returns:
+ A list of Project objects specified by the file.
"""
- logging.info("Finding zmake targets under '%s'.", root_dir)
- for path in pathlib.Path(root_dir).rglob("zmake.yaml"):
- yield Project(path.parent)
+ projects = []
+ def register_project(name, **kwargs):
+ projects.append(Project(ProjectConfig(name=name, **kwargs)))
-class ProjectConfig:
- """An object wrapping zmake.yaml."""
-
- validator = jsonschema.Draft7Validator
- schema = {
- "type": "object",
- "required": [
- "board",
- "output-type",
- "supported-toolchains",
- "supported-zephyr-versions",
- ],
- "properties": {
- "supported-zephyr-versions": {
- "type": "array",
- "items": {
- "type": "string",
- "enum": ["v2.6", "v2.7", "v2.8"],
- },
- "minItems": 1,
- "uniqueItems": True,
- },
- "board": {
- "type": "string",
- },
- "modules": {
- "type": "array",
- "items": {
- "type": "string",
- "enum": list(modules.known_modules),
- },
- },
- "output-type": {
- "type": "string",
- "enum": list(packers.packer_registry),
- },
- "supported-toolchains": {
- "type": "array",
- "items": {
- "type": "string",
- "enum": list(toolchains.support_classes),
- },
- },
- "is-test": {
- "type": "boolean",
- },
- "dts-overlays": {
- "type": "array",
- "items": {
- "type": "string",
- },
- },
- },
+ # The Python environment passed to the config file.
+ config_globals = {
+ "register_project": register_project,
+ "here": path.parent.resolve(),
}
- def __init__(self, config_dict):
- self.validator.check_schema(self.schema)
- jsonschema.validate(config_dict, self.schema, cls=self.validator)
- self.config_dict = config_dict
+ # First, load the global helper functions.
+ code = compile(
+ pathlib.Path(configlib.__file__).read_bytes(),
+ configlib.__file__,
+ "exec",
+ )
+ exec(code, config_globals)
- @property
- def supported_zephyr_versions(self):
- return [
- util.parse_zephyr_version(x)
- for x in self.config_dict["supported-zephyr-versions"]
- ]
+ # Next, load the BUILD.py
+ logging.info("Loading config file %s", path)
+ code = compile(path.read_bytes(), str(path), "exec")
+ exec(code, config_globals)
+ logging.info("Config file %s defines %s projects", path, len(projects))
+ return projects
- @property
- def board(self):
- return self.config_dict["board"]
- @property
- def modules(self):
- return self.config_dict.get("modules", list(modules.known_modules))
+def find_projects(root_dir):
+ """Finds all zmake projects in root_dir.
- @property
- def output_packer(self):
- return packers.packer_registry[self.config_dict["output-type"]]
+ Args:
+ root_dir: the root dir as a pathlib.Path object
- @property
- def supported_toolchains(self):
- return self.config_dict["supported-toolchains"]
+ Returns:
+ A dictionary mapping project names to Project objects.
+ """
+ logging.info("Finding zmake targets under '%s'.", root_dir)
+ found_projects = {}
+ for path in pathlib.Path(root_dir).rglob("BUILD.py"):
+ for project in load_config_file(path):
+ if project.config.name in found_projects:
+ raise KeyError(
+ "Duplicate project defined: {} (in {})".format(
+ project.config.name, path
+ )
+ )
+ found_projects[project.config.name] = project
+ return found_projects
- @property
- def is_test(self):
- return self.config_dict.get("is-test", False)
- @property
- def dts_overlays(self):
- return self.config_dict.get("dts-overlays", [])
+@dataclasses.dataclass
+class ProjectConfig:
+ name: str
+ zephyr_board: str
+ supported_toolchains: "list[str]"
+ output_packer: type
+ supported_zephyr_versions: "list[str]" = dataclasses.field(
+ default_factory=lambda: ["v2.7"],
+ )
+ modules: "list[str]" = dataclasses.field(
+ default_factory=lambda: modules.known_modules,
+ )
+ is_test: bool = dataclasses.field(default=False)
+ dts_overlays: "list[str]" = dataclasses.field(default_factory=list)
+ project_dir: pathlib.Path = dataclasses.field(default_factory=pathlib.Path)
class Project:
"""An object encapsulating a project directory."""
- def __init__(self, project_dir, config_dict=None):
- self.project_dir = project_dir.resolve()
- if not config_dict:
- with open(self.project_dir / "zmake.yaml") as f:
- config_dict = yaml.safe_load(f)
- self.config = ProjectConfig(config_dict)
+ def __init__(self, config):
+ self.config = config
self.packer = self.config.output_packer(self)
def iter_builds(self):
@@ -159,8 +115,8 @@ class Project:
Yields:
2-tuples of a build configuration name and a BuildConfig.
"""
- conf = build_config.BuildConfig(cmake_defs={"BOARD": self.config.board})
- prj_conf = self.project_dir / "prj.conf"
+ conf = build_config.BuildConfig(cmake_defs={"BOARD": self.config.zephyr_board})
+ prj_conf = self.config.project_dir / "prj.conf"
if prj_conf.is_file():
conf |= build_config.BuildConfig(kconfig_files=[prj_conf])
for build_name, packer_config in self.packer.configs():
@@ -178,11 +134,11 @@ class Project:
"""
overlays = []
for module_path in modules.values():
- dts_path = module_dts_overlay_name(module_path, self.config.board)
+ dts_path = module_dts_overlay_name(module_path, self.config.zephyr_board)
if dts_path.is_file():
overlays.append(dts_path.resolve())
- overlays.extend(self.project_dir / f for f in self.config.dts_overlays)
+ overlays.extend(self.config.dts_overlays)
if overlays:
return build_config.BuildConfig(
@@ -218,7 +174,7 @@ class Project:
except KeyError as e:
raise KeyError(
"The {!r} module is required by the {} project, but is not "
- "available.".format(module, self.project_dir)
+ "available.".format(module, self.config.project_dir)
) from e
return result