feat: strengthen BSP and PSP validation and handoff
This commit is contained in:
1 parent
bcea35a91e
commit
1641fac631
39 files changed
+2695
-90
No files matched your search
@@ -49,6 +49,64 @@ def detects_dual_os(config_dir: Path) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def resolve_board_layout(project: Path, chip: str | None = None) -> dict[str, object]:
|
||||
"""Keep the existing CV184X layout; recognize CV181X split configuration."""
|
||||
config_dirs = config_directories(project)
|
||||
if chip and chip.upper().startswith("CV181"):
|
||||
kernel = project / "configs" / "kernel"
|
||||
uboot = project / "configs" / "uboot"
|
||||
if {path.name for path in config_dirs} != {"kernel", "uboot"}:
|
||||
return {
|
||||
"board_build_type": None,
|
||||
"system_form": None,
|
||||
"config_directory": None,
|
||||
"layout": "unknown",
|
||||
"error": "CV181X 项目需要 configs/kernel 和 configs/uboot 两个配置目录",
|
||||
}
|
||||
candidates = sorted(
|
||||
path for path in uboot.glob("*_defconfig")
|
||||
if path.is_file() and not path.is_symlink() and not path.name.startswith("cvitek_")
|
||||
)
|
||||
if len(candidates) == 1:
|
||||
build_type = candidates[0].name.removesuffix("_defconfig")
|
||||
sdk_config = uboot / f"cvitek_{build_type}_defconfig"
|
||||
kernel_config = kernel / f"cvitek_{build_type}_defconfig"
|
||||
if (sdk_config.is_file() and not sdk_config.is_symlink()
|
||||
and kernel_config.is_file() and not kernel_config.is_symlink()):
|
||||
return {
|
||||
"board_build_type": build_type,
|
||||
"system_form": "dual-os" if detects_dual_os(uboot) else "single-os",
|
||||
"config_directory": str(uboot),
|
||||
"layout": "split-kernel-uboot",
|
||||
"error": None,
|
||||
}
|
||||
return {
|
||||
"board_build_type": None,
|
||||
"system_form": None,
|
||||
"config_directory": None,
|
||||
"layout": "split-kernel-uboot",
|
||||
"error": "CV181X kernel/uboot 结构未能唯一定位完整的板级 defconfig 组",
|
||||
}
|
||||
|
||||
if len(config_dirs) == 1 and config_dirs[0].name not in {"kernel", "uboot"}:
|
||||
config_dir = config_dirs[0]
|
||||
return {
|
||||
"board_build_type": config_dir.name,
|
||||
"system_form": "dual-os" if detects_dual_os(config_dir) else "single-os",
|
||||
"config_directory": str(config_dir),
|
||||
"layout": "board-directory",
|
||||
"error": None,
|
||||
}
|
||||
|
||||
return {
|
||||
"board_build_type": None,
|
||||
"system_form": None,
|
||||
"config_directory": None,
|
||||
"layout": "unknown",
|
||||
"error": f"无法识别配置布局:configs/ 下有 {[path.name for path in config_dirs]}",
|
||||
}
|
||||
|
||||
|
||||
def project_preflight(reference_name: str, target_name: str, root: Path) -> dict[str, object]:
|
||||
errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
@@ -64,13 +122,19 @@ def project_preflight(reference_name: str, target_name: str, root: Path) -> dict
|
||||
errors.append(f"缺少 buildEnvConfig.sh: {build_env}")
|
||||
else:
|
||||
assignments = parse_assignments(build_env)
|
||||
config_dirs = config_directories(reference)
|
||||
if len(config_dirs) != 1:
|
||||
errors.append(f"参考项目必须唯一定位一个配置目录,实际为 {len(config_dirs)} 个")
|
||||
config_dir = config_dirs[0] if len(config_dirs) == 1 else None
|
||||
sync_script = reference / "configs" / "EPSYNCSDKConfig.sh"
|
||||
if not sync_script.is_file():
|
||||
warnings.append(f"未找到项目同步脚本: {sync_script}")
|
||||
layout = resolve_board_layout(reference, assignments.get("EP_CHIP"))
|
||||
if layout["error"]:
|
||||
errors.append(str(layout["error"]))
|
||||
if layout["layout"] == "split-kernel-uboot":
|
||||
sync_scripts = [reference / "configs" / part / script for part, script in (
|
||||
("kernel", "ep_kernel.sh"), ("uboot", "ep_uboot.sh"))]
|
||||
sync_script = None
|
||||
else:
|
||||
sync_script = reference / "configs" / "EPSYNCSDKConfig.sh"
|
||||
sync_scripts = [sync_script]
|
||||
for path in sync_scripts:
|
||||
if not path.is_file() or path.is_symlink():
|
||||
warnings.append(f"未找到普通项目同步脚本: {path}")
|
||||
|
||||
imgs = reference / "imgs"
|
||||
imgs_target = os.readlink(imgs) if imgs.is_symlink() else None
|
||||
@@ -94,13 +158,15 @@ def project_preflight(reference_name: str, target_name: str, root: Path) -> dict
|
||||
"architecture": assignments.get("EP_ARCH"),
|
||||
"flash": assignments.get("EP_FLASH_TYPE"),
|
||||
"nand_flash_id": assignments.get("NAND_FLASH_ID"),
|
||||
"board_build_type": config_dir.name if config_dir else None,
|
||||
"system_form": "dual-os" if config_dir and detects_dual_os(config_dir) else "single-os",
|
||||
"board_build_type": layout["board_build_type"],
|
||||
"system_form": layout["system_form"],
|
||||
"config_layout": layout["layout"],
|
||||
},
|
||||
"bounded_paths": {
|
||||
"build_env": str(build_env),
|
||||
"config_directory": str(config_dir) if config_dir else None,
|
||||
"sync_script": str(sync_script),
|
||||
"config_directory": layout["config_directory"],
|
||||
"sync_script": str(sync_script) if sync_script else None,
|
||||
"sync_scripts": [str(path) for path in sync_scripts],
|
||||
"reference_imgs_target": imgs_target,
|
||||
"target_imgs_target": project_guard.expected_imgs_target(target_name),
|
||||
},
|
||||
@@ -115,6 +181,14 @@ def build_preflight(project_name: str, version: str, root: Path, output_root: Pa
|
||||
if not VERSION_RE.fullmatch(version):
|
||||
errors.append("构建版本必须为 YYYYMMDD_N,且 N 为正整数")
|
||||
|
||||
build_env = project / "buildEnvConfig.sh"
|
||||
assignments = parse_assignments(build_env) if build_env.is_file() and not build_env.is_symlink() else {}
|
||||
if not assignments.get("EP_CHIP"):
|
||||
errors.append(f"构建前无法确认 EP_CHIP: {build_env}")
|
||||
layout = resolve_board_layout(project, assignments.get("EP_CHIP"))
|
||||
if layout["error"]:
|
||||
errors.append(str(layout["error"]))
|
||||
|
||||
completion_script = root / "tools" / "script_completion.sh"
|
||||
if not completion_script.is_file():
|
||||
errors.append(f"统一构建入口不存在: {completion_script}")
|
||||
@@ -137,6 +211,9 @@ def build_preflight(project_name: str, version: str, root: Path, output_root: Pa
|
||||
f"EMX2_BuildSDKTool {project_name} {version} all"
|
||||
)
|
||||
warnings.append("统一构建可能同步配置到项目外 SDK,并按工具实现执行 git fetch origin")
|
||||
requires_patch_precheck = assignments.get("EP_CHIP", "").upper().startswith("CV184")
|
||||
if requires_patch_precheck:
|
||||
warnings.append("CV184X 构建补丁检查失败可能触发 --applypatch --force;本预检未验证补丁环境,不能单凭 passed=true 自动构建")
|
||||
return {
|
||||
"schema_version": 1,
|
||||
"kind": "build-preflight",
|
||||
@@ -145,6 +222,9 @@ def build_preflight(project_name: str, version: str, root: Path, output_root: Pa
|
||||
"warnings": warnings,
|
||||
"project": project_name,
|
||||
"project_path": str(project),
|
||||
"config_layout": layout["layout"],
|
||||
"board_build_type": layout["board_build_type"],
|
||||
"requires_patch_precheck": requires_patch_precheck,
|
||||
"build_version": version,
|
||||
"working_directory": str(root),
|
||||
"completion_script": str(completion_script),
|
||||
|
||||
Reference in new issue
Block a user