78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
# -*- 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)
|