86 lines
3.1 KiB
Python
86 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Pack a project (Bootloader/ or App/) together with the shared layers
|
|
(top-level Drivers/ + Shared/) into a sendable zip.
|
|
|
|
Structure change (2026-08-18): Drivers/ and Shared/ now live at the repo
|
|
top level and are shared by both projects. The zip reproduces the same
|
|
layout, so the receiver unzips anywhere and the ..\\..\\Drivers /
|
|
..\\..\\Shared references in the .uvprojx resolve correctly.
|
|
|
|
Usage:
|
|
python pack.py bl -> Output/bootloader_package.zip
|
|
python pack.py app -> Output/app_package.zip
|
|
|
|
Intermediate build artifacts (.o/.d/.crf/.axf/... and MDK Objects/Output/Listings)
|
|
are excluded to keep the package small and clean.
|
|
"""
|
|
import os
|
|
import sys
|
|
import zipfile
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
# intermediate build artifacts to exclude from the zip
|
|
EXCLUDE_EXT = {'.o', '.d', '.crf', '.axf', '.lst', '.dep', '.htm', '.map', '.bak', '.uvguix'}
|
|
# MDK build-output dirs (case-insensitive) - never descend into them
|
|
EXCLUDE_DIRS = {'objects', 'output', 'listings'}
|
|
|
|
|
|
def add_dir(zf, src_dir, arc_base):
|
|
"""Add src_dir tree into zip under arc_base, skipping build artifacts."""
|
|
n = 0
|
|
for base, dirs, files in os.walk(src_dir):
|
|
rel = os.path.relpath(base, src_dir)
|
|
parts = [p.lower() for p in rel.split(os.sep) if p not in ('', '.')]
|
|
if any(p in EXCLUDE_DIRS for p in parts):
|
|
dirs[:] = [] # do not descend into MDK build-output dirs
|
|
continue
|
|
for f in files:
|
|
if os.path.splitext(f)[1].lower() in EXCLUDE_EXT:
|
|
continue
|
|
src = os.path.join(base, f)
|
|
dst = os.path.join(arc_base, rel, f) if rel != '.' else os.path.join(arc_base, f)
|
|
zf.write(src, dst)
|
|
n += 1
|
|
return n
|
|
|
|
|
|
def pack(proj, zip_path):
|
|
"""zip 内布局与仓库一致: <Proj>/ + Drivers/ + Shared/(共享层来自顶层)"""
|
|
n = 0
|
|
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
|
|
n += add_dir(zf, os.path.join(ROOT, proj), proj)
|
|
n += add_dir(zf, os.path.join(ROOT, 'Drivers'), 'Drivers')
|
|
n += add_dir(zf, os.path.join(ROOT, 'Shared'), 'Shared')
|
|
return n
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print('usage: python pack.py bl|app')
|
|
sys.exit(1)
|
|
mode = sys.argv[1].lower()
|
|
if mode == 'bl':
|
|
proj, zipname, uv = 'Bootloader', 'bootloader_package.zip', 'Bootloader.uvprojx'
|
|
elif mode == 'app':
|
|
proj, zipname, uv = 'App', 'app_package.zip', 'project.uvprojx'
|
|
else:
|
|
print('unknown mode: %s (use bl or app)' % mode)
|
|
sys.exit(1)
|
|
|
|
out_dir = os.path.join(ROOT, 'Output')
|
|
os.makedirs(out_dir, exist_ok=True)
|
|
zip_path = os.path.join(out_dir, zipname)
|
|
# 注:不预先删除旧 zip('w' 模式会直接截断覆盖,避免依赖删除旧文件的权限/回收站)
|
|
|
|
n = pack(proj, zip_path)
|
|
print('[OK] %d files -> %s' % (n, zip_path))
|
|
print(' zip layout: %s/ + Drivers/ + Shared/ (same as repo, unzip anywhere)' % proj)
|
|
print(' receiver: unzip, open %s\\MDK-ARM\\%s in Keil and build.' % (proj, uv))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|