81 lines
3.4 KiB
Python
81 lines
3.4 KiB
Python
import pathlib
|
|
|
|
import modulus.config
|
|
|
|
build_root = pathlib.Path("build")
|
|
common_dir = build_root / "build_common"
|
|
tools_dir = build_root / "build_tools"
|
|
|
|
class build_target:
|
|
def __init__(self, name, profile, build_dir, build_type, can_run, cmake_definitions):
|
|
self.name = name
|
|
self.profile = profile
|
|
self.build_dir = build_dir
|
|
self.build_type = build_type
|
|
self.can_run = can_run
|
|
self.cmake_definitions = cmake_definitions
|
|
|
|
def find_repo_root(start):
|
|
current = start.resolve()
|
|
for candidate in (current, *current.parents):
|
|
if (candidate / "modulus.json").is_file():
|
|
return candidate
|
|
raise SystemExit("could not find modulus.json from current directory")
|
|
|
|
def validate_build_directory(repo_root, source_dir, build_dir):
|
|
resolved = pathlib.Path(build_dir).resolve()
|
|
if resolved in {pathlib.Path(repo_root).resolve(), pathlib.Path(source_dir).resolve()}:
|
|
raise modulus.config.config_error(f"build directory must differ from the project and source roots: {build_dir}")
|
|
|
|
class build_context:
|
|
def __init__(self, repo_root, config):
|
|
self.repo_root = repo_root
|
|
self.config = config
|
|
self.package = config["package"]
|
|
self.artifact = self.package["artifact"]
|
|
self.tooling = config["tooling"]
|
|
self.run_settings = self.tooling["run"]
|
|
self.lsp_settings = self.tooling.get("lsp", {"enabled": False, "compile_databases": []})
|
|
self.build_root = repo_root / build_root
|
|
self.common_dir = repo_root / common_dir
|
|
self.tools_rel = tools_dir if (repo_root / tools_dir).exists() else pathlib.Path("tools")
|
|
self.tools_dir = repo_root / self.tools_rel
|
|
self.conan_cache_dir = self.common_dir / "conan_cache"
|
|
self.default_target_name = str(self.tooling["default_target"])
|
|
self.targets = self._targets()
|
|
self.default_target = self.targets[self.default_target_name]
|
|
docker = self.tooling["docker"]
|
|
self.docker_image = str(docker["image"])
|
|
self.dockerfile = repo_root / docker["dockerfile"] if docker.get("dockerfile") else self.tools_dir / "docker" / "Dockerfile"
|
|
self.docker_inputs = [self.tools_dir / "docker" / "format_requirements.txt", *(repo_root / path for path in docker.get("inputs", []))]
|
|
self.docker_workdir = str(repo_root)
|
|
self.docker_marker = pathlib.Path(str(docker["marker"]))
|
|
self.upload_env = str(self.tooling["upload_env"])
|
|
self.package_upload_env = str(self.artifact["upload_env"])
|
|
def _targets(self):
|
|
result = {}
|
|
targets = self.tooling["targets"]
|
|
for name, target in targets.items():
|
|
validate_build_directory(self.repo_root, self.repo_root, self.repo_root / str(target["build_dir"]))
|
|
result[name] = build_target(
|
|
name=name,
|
|
profile=self.repo_root / str(target["profile"]),
|
|
build_dir=self.repo_root / str(target["build_dir"]),
|
|
build_type=str(target.get("build_type", "Release")),
|
|
can_run=bool(target.get("can_run", True)),
|
|
cmake_definitions=dict(target.get("cmake_definitions", {})),
|
|
)
|
|
return result
|
|
def target(self, name):
|
|
try:
|
|
return self.targets[name]
|
|
except KeyError:
|
|
valid = ", ".join(sorted(self.targets))
|
|
raise SystemExit(f"unknown target '{name}'. Valid targets: {valid}") from None
|
|
def selected_targets(self, names, all_targets):
|
|
if all_targets:
|
|
return list(self.targets.values())
|
|
if not names:
|
|
return [self.default_target]
|
|
return [self.target(name) for name in names]
|