Files
mcu-codegen-template/tools/pack.py
T

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()