| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import os
- import shutil
- import logging
- import subprocess
- from pathlib import Path
- from typing import List
- logger = logging.getLogger(__name__)
- class BuildSOCError(Exception):
- """SOC 编译异常"""
- pass
- def prepare_soc(mcu_sdk_dir: str, soc_dir: str, soc_project: str):
- """
- 将 MCU 编译产物拷贝到 SOC 的 hbbin/mcubin/deploy/ (或 deploy_dv/)。
- 对应原 Shell 的 prepare_for_compile_soc()。
- """
- # MCU 输出目录
- mcu_output = os.path.join(mcu_sdk_dir, 'output', 'dbg')
- if not os.path.isdir(mcu_output):
- raise BuildSOCError(f"MCU output directory not found: {mcu_output}")
- # 确定目标目录:deploy 或 deploy_dv
- if 'DV' in soc_project.upper():
- deploy_dir = os.path.join(soc_dir, 'hbbin', 'mcubin', 'deploy_dv')
- else:
- deploy_dir = os.path.join(soc_dir, 'hbbin', 'mcubin', 'deploy')
- os.makedirs(deploy_dir, exist_ok=True)
- # 复制 J6_MCU.zip
- src_zip = os.path.join(mcu_output, 'J6_MCU.zip')
- if os.path.isfile(src_zip):
- shutil.copy2(src_zip, deploy_dir)
- logger.info("Copied %s to %s", src_zip, deploy_dir)
- else:
- raise BuildSOCError(f"Missing MCU archive: {src_zip}")
- # 复制 .map 和 .elf 文件
- for item in os.listdir(mcu_output):
- if item.endswith('.map') or item.endswith('.elf'):
- src = os.path.join(mcu_output, item)
- if os.path.isfile(src):
- shutil.copy2(src, deploy_dir)
- logger.info("Copied %s to %s", src, deploy_dir)
- def compile_soc(soc_dir: str, soc_project: str,
- secure_enable: bool = False,
- factory_emmc_img_enable: bool = False,
- profile_mode: str = 'Debug'):
- """
- 执行 SOC 编译和部署。
- 对应原 Shell 的 compile_soc()。
- """
- # 切换到 SOC 根目录
- original_cwd = os.getcwd()
- os.chdir(soc_dir)
- try:
- # 检查 QNX 工具链
- if not os.path.isdir('/opt/qnx800'):
- raise BuildSOCError("QNX toolchain not found: /opt/qnx800")
- # 建立软链接(如果不存在)
- target_link = os.path.join('build_tools', 'Compiler', 'qnx800')
- if not os.path.islink(target_link) and not os.path.exists(target_link):
- os.makedirs(os.path.dirname(target_link), exist_ok=True)
- os.symlink('/opt/qnx800', target_link)
- logger.info("Created symlink: %s -> /opt/qnx800", target_link)
- # 1. 编译镜像
- build_cmd = ['./build-tools/build.sh', '-c', 'invo-all-image']
- logger.info("SOC compile: %s", ' '.join(build_cmd))
- subprocess.run(build_cmd, check=True)
- # 2. 部署镜像(生成所有需要的镜像文件)
- deploy_cmd = ['./build-tools/build.sh'] + _build_deploy_args(soc_project,
- secure_enable,
- factory_emmc_img_enable,
- profile_mode) + ['-b', 'invo-all-image']
- logger.info("SOC deploy: %s", ' '.join(deploy_cmd))
- subprocess.run(deploy_cmd, check=True)
- except subprocess.CalledProcessError as e:
- raise BuildSOCError(f"SOC build failed: {e}") from e
- finally:
- os.chdir(original_cwd)
- def _build_deploy_args(soc_project: str, secure_enable: bool,
- factory_emmc_img_enable: bool, profile_mode: str) -> List[str]:
- """
- 构造部署命令的额外参数。
- 对应原 Shell 的 extra_para 逻辑。
- """
- args = []
- # DV 项目添加 -d
- if 'DV' in soc_project.upper():
- args.append('-d')
- # 安全编译
- if secure_enable:
- args.append('-s')
- # 工厂 eMMC 镜像
- if factory_emmc_img_enable:
- args.append('-f')
- # Release 模式
- if profile_mode == 'Release':
- args.append('-r')
- return args
|