# ----------------------------------------------------------------------------- # Description: Backend integration wrapper for required mxpic_router project GDS generation. # Inside functions: build_project_gds, _build_with_mxpic_router, _load_project_cells # Developer : Qin Yue @ 2026 # Organization : OptiHK Limited # ----------------------------------------------------------------------------- import os from dataclasses import dataclass, field from typing import Dict, List import yaml from router_dependency import require_router_stack @dataclass class BuildResult: """Container for GDS build output paths, status details, and engine metadata.""" output_path: str engine: str cells_built: List[str] = field(default_factory=list) warnings: List[str] = field(default_factory=list) def build_project_gds( project_dir: str, output_path: str, pdk_public_root: str, technology_manifest_path: str = None, prefer_full_gds: bool = False, ) -> BuildResult: """Build a hierarchical project GDS from saved cell YAML files with mxpic_router.""" cells = _load_project_cells(project_dir) if not cells: raise ValueError("No saved cell YAML files found for this project") return _build_with_mxpic_router( project_dir, output_path, pdk_public_root, technology_manifest_path, prefer_full_gds, ) def _build_with_mxpic_router( project_dir: str, output_path: str, pdk_root: str, technology_manifest_path: str, prefer_full_gds: bool, ) -> BuildResult: """Delegate project GDS generation to the required external mxpic_router package.""" require_router_stack() from mxpic_router import build_project_gds as build_routed_project_gds result = build_routed_project_gds( project_dir=project_dir, output_path=output_path, pdk_root=pdk_root, technology_manifest_path=technology_manifest_path, prefer_full_gds=prefer_full_gds, ) return BuildResult( output_path=result.get("output_path", output_path), engine=result.get("engine", "mxpic_router"), cells_built=result.get("cells_built", []), warnings=result.get("warnings", []), ) def _load_project_cells(project_dir: str) -> Dict[str, dict]: """Load saved cell YAML documents from a project directory.""" cells = {} for filename in sorted(os.listdir(project_dir)): if not filename.lower().endswith((".yml", ".yaml")): continue path = os.path.join(project_dir, filename) with open(path, "r", encoding="utf-8") as file: data = yaml.safe_load(file) or {} cell_name = str(data.get("name") or os.path.splitext(filename)[0]) cells[cell_name] = data return cells