feat(build): 新增 --app=a,b 只编指定应用;默认不重编内核
默认行为改为**不重编内核**(多数迭代只改应用/库),需要时显式加 --kernel;--app=hello,explorer 只编译列出的应用(逗号分隔),不带 --app 仍编译全部应用;新增 --libs 显式编译 Libs 下的 .so(带 --app 时默认跳过库,要一起编就加 --libs);应用/库编译改为表驱动(APP_LIST/LIB_LIST),--noapp 的拷贝逻辑抽到 CopyExisting()。
This commit is contained in:
1 parent
c4ff870941
commit
465ef4a910
1 file changed
+85
-86
@@ -9,11 +9,19 @@ clean = '--noclean' not in sys.argv
|
||||
kernel_only = '--kernel-only' in sys.argv
|
||||
noapp = '--noapp' in sys.argv
|
||||
bootloader = '--bootloader' in sys.argv
|
||||
# --onlyrun:跳过全部编译/打包步骤,只用现有 disk.img 反复启动 QEMU 复现问题。
|
||||
# 典型用法:python build.py --onlyrun(连跑多次,观察偶发写坏是否复现并留下 [FATAL])
|
||||
# --onlyrun:跳过全部编译/打包,直接用现有 disk.img 启动 QEMU
|
||||
only_run = '--onlyrun' in sys.argv
|
||||
# --onlyapp:只编译库与应用(跳过内核),用于只改应用/库时的快速迭代。
|
||||
# --onlyapp:只编译库与应用(保留兼容;现在这已是默认行为)
|
||||
only_app = '--onlyapp' in sys.argv
|
||||
# --kernel:重编内核。**默认不重编内核**(多数迭代只改应用/库),显式传才编。
|
||||
build_kernel = '--kernel' in sys.argv or kernel_only
|
||||
# --libs:编译 Libs/ 下的动态库(不带 --app 时默认也会编)
|
||||
libs = '--libs' in sys.argv
|
||||
# --app=a,b,c:只编译列出的应用(逗号分隔、可多个)。不传则编译全部应用。
|
||||
app_filter = None
|
||||
for _arg in sys.argv:
|
||||
if _arg.startswith('--app='):
|
||||
app_filter = [x.strip().lower() for x in _arg[len('--app='):].split(',') if x.strip()]
|
||||
|
||||
|
||||
def BuildKernel():
|
||||
@@ -37,90 +45,77 @@ def BuildKernel():
|
||||
shutil.copy(kernel_bin, "./disk/sys/kernel/x86_64/kernel.bin")
|
||||
|
||||
|
||||
# 应用表:(--app 的筛选名, 工程目录, 产物文件名, disk 下的目标文件名)
|
||||
APP_LIST = [
|
||||
("hello", "Apps/HelloWorld", "helloworld.elf", "hello.elf"),
|
||||
("terminal", "Apps/Terminal", "terminal.elf", "terminal.elf"),
|
||||
("gargantua", "Apps/Gargantua", "gargantua.elf", "gargantua.elf"),
|
||||
("scene3d", "Apps/Scene3D", "scene3d.elf", "scene3d.elf"),
|
||||
("explorer", "Apps/Explorer", "explorer.elf", "explorer.elf"),
|
||||
]
|
||||
# 动态库表:(工程目录, 产物文件名)
|
||||
LIB_LIST = [
|
||||
("Libs/SerialLogger", "slog.so"),
|
||||
("Libs/VPUI64", "vpui64.so"),
|
||||
]
|
||||
|
||||
|
||||
def BuildLibs():
|
||||
"""编译 Libs/ 下的动态库(应用运行期经 LOAD_SO 加载)。"""
|
||||
os.makedirs("./disk/libs", exist_ok=True)
|
||||
for proj, out in LIB_LIST:
|
||||
cmd = rf'..\..\ViperC\output\viperc.exe --project {proj}/project.vpj --clear-cache'
|
||||
if clean:
|
||||
cmd += ' --clean'
|
||||
os.system(cmd)
|
||||
src = f"{proj}/__vpcbuild__/output/{out}"
|
||||
if os.path.exists(src):
|
||||
shutil.copy(src, f"./disk/libs/{out}")
|
||||
print(f"[build] lib {out} -> disk/libs/{out}")
|
||||
|
||||
|
||||
def CopyExisting():
|
||||
"""--noapp:不编译,直接把已有产物拷进 disk/(缺文件只警告)。"""
|
||||
os.makedirs("./disk/apps", exist_ok=True)
|
||||
for _, proj, out, dst in APP_LIST:
|
||||
src = f"{proj}/__vpcbuild__/output/{out}"
|
||||
if os.path.exists(src):
|
||||
shutil.copy(src, f"./disk/apps/{dst}")
|
||||
else:
|
||||
print(f"[build] 警告: {src} 不存在,请先完整构建一次")
|
||||
for proj, out in LIB_LIST:
|
||||
src = f"{proj}/__vpcbuild__/output/{out}"
|
||||
if os.path.exists(src):
|
||||
shutil.copy(src, f"./disk/libs/{out}")
|
||||
|
||||
|
||||
def BuildApps():
|
||||
"""编译库与应用,并拷贝到 disk/"""
|
||||
# --noapp 优先级高于 --kernel-only:只编译内核,不编译所有库和应用
|
||||
"""编译库与应用,并拷贝到 disk/。
|
||||
|
||||
· 不带 --app:编库 + 全部应用
|
||||
· --app=a,b:只编列出的应用(库要一起编就再加 --libs)
|
||||
"""
|
||||
if noapp:
|
||||
print("[build] --noapp: 跳过所有库与应用编译,复用已有缓存文件")
|
||||
# 检查必要文件是否存在
|
||||
required_libs = [
|
||||
("Libs/SerialLogger/__vpcbuild__/output/slog.so", "./disk/libs/slog.so"),
|
||||
("Libs/VPUI64/__vpcbuild__/output/vpui64.so", "./disk/libs/vpui64.so"),
|
||||
]
|
||||
required_apps = [
|
||||
("Apps/HelloWorld/__vpcbuild__/output/helloworld.elf", "./disk/apps/hello.elf"),
|
||||
("Apps/Terminal/__vpcbuild__/output/terminal.elf", "./disk/apps/terminal.elf"),
|
||||
("Apps/Gargantua/__vpcbuild__/output/gargantua.elf", "./disk/apps/gargantua.elf"),
|
||||
("Apps/Scene3D/__vpcbuild__/output/scene3d.elf", "./disk/apps/scene3d.elf"),
|
||||
("Apps/Explorer/__vpcbuild__/output/explorer.elf", "./disk/apps/explorer.elf"),
|
||||
]
|
||||
os.makedirs("./disk/apps", exist_ok=True)
|
||||
os.makedirs("./disk/libs", exist_ok=True)
|
||||
for src, dst in required_libs + required_apps:
|
||||
if os.path.exists(src):
|
||||
shutil.copy(src, dst)
|
||||
else:
|
||||
print(f"[build] 警告: {src} 不存在,请先完整构建一次")
|
||||
elif kernel_only:
|
||||
# 仅 --kernel-only:只跳过应用,不跳过库(原有逻辑保留)
|
||||
print("[build] --kernel-only: 跳过其他应用和库的编译")
|
||||
if not os.path.exists("./disk/apps/hello.elf"):
|
||||
print("[build] 警告: hello.elf 不存在,请先不带 --kernel-only 完整构建一次")
|
||||
CopyExisting()
|
||||
return
|
||||
|
||||
if app_filter is None or libs:
|
||||
BuildLibs()
|
||||
else:
|
||||
# 完整编译所有库+应用
|
||||
so_cmd = r'..\..\ViperC\output\viperc.exe --project Libs/SerialLogger/project.vpj --clear-cache'
|
||||
print("[build] --app 已指定且未传 --libs:跳过库编译")
|
||||
|
||||
os.makedirs("./disk/apps", exist_ok=True)
|
||||
for name, proj, out, dst in APP_LIST:
|
||||
if app_filter is not None and name not in app_filter:
|
||||
continue
|
||||
cmd = rf'..\..\ViperC\output\viperc.exe --project {proj}/project.vpj --clear-cache'
|
||||
if clean:
|
||||
so_cmd += ' --clean'
|
||||
os.system(so_cmd)
|
||||
|
||||
vpui_cmd = r'..\..\ViperC\output\viperc.exe --project Libs/VPUI64/project.vpj --clear-cache'
|
||||
if clean:
|
||||
vpui_cmd += ' --clean'
|
||||
os.system(vpui_cmd)
|
||||
|
||||
app_cmd = r'..\..\ViperC\output\viperc.exe --project Apps/HelloWorld/project.vpj --clear-cache'
|
||||
if clean:
|
||||
app_cmd += ' --clean'
|
||||
os.system(app_cmd)
|
||||
|
||||
os.makedirs("./disk/apps", exist_ok=True)
|
||||
shutil.copy("Apps/HelloWorld/__vpcbuild__/output/helloworld.elf", "./disk/apps/hello.elf")
|
||||
|
||||
term_cmd = r'..\..\ViperC\output\viperc.exe --project Apps/Terminal/project.vpj --clear-cache'
|
||||
if clean:
|
||||
term_cmd += ' --clean'
|
||||
os.system(term_cmd)
|
||||
|
||||
shutil.copy("Apps/Terminal/__vpcbuild__/output/terminal.elf", "./disk/apps/terminal.elf")
|
||||
|
||||
garg_cmd = r'..\..\ViperC\output\viperc.exe --project Apps/Gargantua/project.vpj --clear-cache'
|
||||
if clean:
|
||||
garg_cmd += ' --clean'
|
||||
os.system(garg_cmd)
|
||||
|
||||
shutil.copy("Apps/Gargantua/__vpcbuild__/output/gargantua.elf", "./disk/apps/gargantua.elf")
|
||||
|
||||
scene3d_cmd = r'..\..\ViperC\output\viperc.exe --project Apps/Scene3D/project.vpj --clear-cache'
|
||||
if clean:
|
||||
scene3d_cmd += ' --clean'
|
||||
os.system(scene3d_cmd)
|
||||
|
||||
shutil.copy("Apps/Scene3D/__vpcbuild__/output/scene3d.elf", "./disk/apps/scene3d.elf")
|
||||
|
||||
exp_cmd = r'..\..\ViperC\output\viperc.exe --project Apps/Explorer/project.vpj --clear-cache'
|
||||
if clean:
|
||||
exp_cmd += ' --clean'
|
||||
os.system(exp_cmd)
|
||||
|
||||
shutil.copy("Apps/Explorer/__vpcbuild__/output/explorer.elf", "./disk/apps/explorer.elf")
|
||||
|
||||
os.makedirs("./disk/libs", exist_ok=True)
|
||||
so_path = os.path.abspath("Libs/SerialLogger/__vpcbuild__/output/slog.so")
|
||||
vpui_path = os.path.abspath("Libs/VPUI64/__vpcbuild__/output/vpui64.so")
|
||||
if os.path.exists(so_path):
|
||||
shutil.copy(so_path, "./disk/libs/slog.so")
|
||||
if os.path.exists(vpui_path):
|
||||
shutil.copy(vpui_path, "./disk/libs/vpui64.so")
|
||||
cmd += ' --clean'
|
||||
os.system(cmd)
|
||||
src = f"{proj}/__vpcbuild__/output/{out}"
|
||||
shutil.copy(src, f"./disk/apps/{dst}")
|
||||
print(f"[build] app {name}: {src} -> disk/apps/{dst}")
|
||||
|
||||
|
||||
def BuildBootloader():
|
||||
@@ -208,11 +203,15 @@ def RunQemu():
|
||||
if only_run:
|
||||
print("[build] --onlyrun: 跳过编译/打包,直接用现有 disk.img 启动 QEMU")
|
||||
else:
|
||||
if only_app:
|
||||
print("[build] --onlyapp: 只编译库与应用,跳过内核")
|
||||
else:
|
||||
if kernel_only:
|
||||
print("[build] --kernel-only: 只编译内核")
|
||||
BuildKernel()
|
||||
BuildApps()
|
||||
else:
|
||||
if build_kernel:
|
||||
BuildKernel()
|
||||
else:
|
||||
print("[build] 默认不重编内核(需要时加 --kernel)")
|
||||
BuildApps()
|
||||
BuildBootloader()
|
||||
BuildDisk()
|
||||
|
||||
|
||||
Reference in new issue
Block a user