添加普冉 PY32F040 OTA 双工程代码生成模板
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Verify zip package contents for the two project packages (shared-layer layout).
|
||||
|
||||
Checks:
|
||||
1. zip top-level layout: <Proj>/ + Drivers/ + Shared/ (must be siblings)
|
||||
2. uvprojx ..\\..\\Drivers / ..\\..\\Shared references resolve inside the zip
|
||||
(simulates the receiver unzipping the archive anywhere and opening Keil)
|
||||
3. no junk build artifacts (.o/.d/.crf/...)
|
||||
"""
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
EXCLUDE_EXT = ('.o', '.d', '.crf', '.axf', '.lst', '.dep', '.htm', '.map', '.bak', '.uvguix')
|
||||
|
||||
ok = True
|
||||
for z, proj in [('bootloader_package.zip', 'Bootloader'),
|
||||
('app_package.zip', 'App')]:
|
||||
names = zipfile.ZipFile(z).namelist()
|
||||
print('===== %s (%d files) =====' % (z, len(names)))
|
||||
|
||||
# 1) 顶层布局
|
||||
tops = sorted(set(n.split('/')[0] for n in names))
|
||||
print('top dirs:', tops)
|
||||
expect = {proj, 'Drivers', 'Shared'}
|
||||
if not expect.issubset(tops):
|
||||
print(' [FAIL] 缺少共享层目录: %s' % (expect - set(tops)))
|
||||
ok = False
|
||||
|
||||
# 2) uvprojx 的 ..\\..\\ 引用在 zip 内可解析
|
||||
uv = [n for n in names if n.endswith('.uvprojx')]
|
||||
if not uv:
|
||||
print(' [FAIL] 无 uvprojx')
|
||||
ok = False
|
||||
continue
|
||||
data = zipfile.ZipFile(z).read(uv[0]).decode('utf-8', errors='ignore')
|
||||
tree = ET.fromstring(data)
|
||||
base = os.path.dirname(uv[0]) # 工程内 MDK-ARM 目录在 zip 中的路径
|
||||
missing_f = []
|
||||
for fp in tree.iter('FilePath'):
|
||||
v = (fp.text or '').strip()
|
||||
if not v:
|
||||
continue
|
||||
# zip 条目用 '/', uvprojx 用 '\' —— 统一为 posix 形式比较
|
||||
full = posixpath.normpath(posixpath.join(base, v.replace('\\', '/')))
|
||||
if full not in names:
|
||||
missing_f.append(v)
|
||||
missing_i = []
|
||||
for ip in tree.iter('IncludePath'):
|
||||
for seg in (ip.text or '').split(';'):
|
||||
seg = seg.strip()
|
||||
if not seg:
|
||||
continue
|
||||
# IncludePath 是目录:zip 无目录条目,用「目录下有文件条目」判断存在
|
||||
d = posixpath.normpath(posixpath.join(base, seg.replace('\\', '/')))
|
||||
if not any(n.startswith(d + '/') for n in names):
|
||||
missing_i.append(seg)
|
||||
print('uvprojx: %s' % uv[0])
|
||||
print(' FilePath 缺失: %d, IncludePath 缺失: %d' % (len(missing_f), len(missing_i)))
|
||||
for m in (missing_f + missing_i)[:8]:
|
||||
print(' MISSING: %s' % m)
|
||||
ok = False
|
||||
|
||||
# 3) 中间产物
|
||||
bad = [n for n in names if n.lower().endswith(EXCLUDE_EXT)]
|
||||
print('junk files:', len(bad))
|
||||
if bad:
|
||||
ok = False
|
||||
|
||||
print('has startup:', any(n.lower().endswith('startup_py32f040xx.s') for n in names))
|
||||
print('has RTE:', any('/RTE/' in n for n in names))
|
||||
|
||||
print('\n%s' % ('=== 全部通过 ✓ 接收方解压即编译 ===' if ok else '=== 存在问题 ✗ ==='))
|
||||
sys.exit(0 if ok else 1)
|
||||
Reference in New Issue
Block a user