# ----------------------------------------------------------------------------- # 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 tempfile from dataclasses import dataclass, field from typing import List from layout_files import load_layout_cell_files, write_layout_cells_to_directory 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, warnings = _load_project_cells(project_dir) if not cells: raise ValueError("No saved cell YAML files found for this project") with tempfile.TemporaryDirectory(prefix="mxpic_gds_project_") as staged_project_dir: write_layout_cells_to_directory(cells, staged_project_dir) result = _build_with_mxpic_router( staged_project_dir, output_path, pdk_public_root, technology_manifest_path, prefer_full_gds, ) return BuildResult( output_path=result.output_path, engine=result.engine, cells_built=result.cells_built, warnings=warnings + result.warnings, ) 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): """Load saved cell YAML documents from a project directory.""" return load_layout_cell_files(project_dir)