diff --git a/App/lib/core/builtin/ViperBuild.vp b/App/lib/core/builtin/ViperBuild.vp index 919cfa2..965f2c1 100644 --- a/App/lib/core/builtin/ViperBuild.vp +++ b/App/lib/core/builtin/ViperBuild.vp @@ -66,6 +66,7 @@ _c_has_build: int = 0 _c_adv_asan: int = 0 _c_adv_traceback: int = 0 # proj.clean.* 细粒度清理(等价 --clean 的子集;build_dir = 整个 __vpcbuild__) +_c_clean_all: int = 0 _c_clean_output: int = 0 _c_clean_temp: int = 0 _c_clean_build_dir: int = 0 @@ -679,12 +680,15 @@ def _SetAdvancedField(fname: str, vnode: ast.AST*) -> int: def _SetCleanField(fname: str, vnode: ast.AST*) -> int: """Apply proj.clean. = ; 0=success.""" - global _c_clean_output, _c_clean_temp, _c_clean_build_dir, _c_clean_includes + global _c_clean_all, _c_clean_output, _c_clean_temp, _c_clean_build_dir, _c_clean_includes if fname is None or vnode is None: return 1 b: int = _EvalBool(vnode) if b < 0: VLogger.error(f"viperbuild: proj.clean.{fname} must be a boolean constant (True/False)", "viperbuild") return 1 + if string.strcmp(fname, "all") == 0: + _c_clean_all = b + return 0 if string.strcmp(fname, "output") == 0: _c_clean_output = b return 0 @@ -697,7 +701,7 @@ def _SetCleanField(fname: str, vnode: ast.AST*) -> int: if string.strcmp(fname, "includes") == 0: _c_clean_includes = b return 0 - VLogger.error(f"viperbuild: unknown field proj.clean.{fname} (supported: output / temp / build_dir / includes)", "viperbuild") + VLogger.error(f"viperbuild: unknown field proj.clean.{fname} (supported: all / output / temp / build_dir / includes)", "viperbuild") return 1 @@ -1195,7 +1199,7 @@ def _ResetAll() -> None: global _c_compiler, _c_linker, _c_static_libs, _c_dynamic_libs, _c_output global _c_triple, _c_datalayout, _c_selfmachine, _c_has_project, _c_has_build global _c_adv_asan, _c_adv_traceback - global _c_clean_output, _c_clean_temp, _c_clean_build_dir, _c_clean_includes + global _c_clean_all, _c_clean_output, _c_clean_temp, _c_clean_build_dir, _c_clean_includes global _c_run, _c_run_args global _saw_viperbuild _alias = None @@ -1222,6 +1226,7 @@ def _ResetAll() -> None: _c_has_build = 0 _c_adv_asan = 0 _c_adv_traceback = 0 + _c_clean_all = 0 _c_clean_output = 0 _c_clean_temp = 0 _c_clean_build_dir = 0 @@ -1304,6 +1309,11 @@ def AdvancedTraceback() -> int: return _c_adv_traceback +def CleanAll() -> int: + """Whether viperbuild requested a full clean (proj.clean.all: buildroot + includes); 1=yes / 0=no.""" + return _c_clean_all + + def CleanOutput() -> int: """Whether viperbuild requested cleaning the output dir (proj.clean.output); 1=yes / 0=no.""" return _c_clean_output diff --git a/App/main.vp b/App/main.vp index b9ab7e3..4ec2a58 100644 --- a/App/main.vp +++ b/App/main.vp @@ -456,10 +456,13 @@ Target: %s # build_dir 指整个构建根(缺省 {source}/__vpcbuild__,含 temp + output),优先级高于 # 单列的 temp/output。--clean 已覆盖全部目录时跳过,避免重复删除与重复日志。 if src is not None and _gb_clean == False: - c_build_dir: bool = ViperBuild.CleanBuildDir() != 0 - c_temp: bool = ViperBuild.CleanTemp() != 0 - c_output: bool = ViperBuild.CleanOutput() != 0 - c_includes: bool = ViperBuild.CleanIncludes() != 0 + # clean.all 是总开关:等价于 build_dir + includes(temp/output 已被 build_dir 覆盖), + # 个体开关写 False 不能关掉它。 + c_all: bool = ViperBuild.CleanAll() != 0 + c_build_dir: bool = c_all or ViperBuild.CleanBuildDir() != 0 + c_temp: bool = c_all or ViperBuild.CleanTemp() != 0 + c_output: bool = c_all or ViperBuild.CleanOutput() != 0 + c_includes: bool = c_all or ViperBuild.CleanIncludes() != 0 if c_build_dir: if Config.BuildDir is not None: n_cb: int = Utils.CleanDir(Config.BuildDir)