如何让SCons在源文件不变但目标文件被外部修改时触发重建?
问题原因
SCons默认的构建决策逻辑仅校验源文件的变更来判断目标是否需要重建,不会记录、比对目标文件本身的状态,因此目标文件被外部修改(比如版本控制回退、手动编辑)时,SCons会误判为目标是最新的。
解决方法
你可以通过开启目标签名校验的配置实现需求,有两种常用配置方式:
方式1:全局开启所有目标的签名校验
在SConstruct开头添加如下配置即可:
# 开启目标签名校验,判断构建时会同时比对目标当前状态和历史构建记录 Decider('MD5', target_signatures=True)
其中MD5可以替换为你需要的校验逻辑,比如'MD5-timestamp'(先比对时间戳,时间戳变更后再计算MD5,性能更高),都可以搭配target_signatures=True参数使用。
修改后的你的示例SConstruct如下:
Decider('MD5', target_signatures=True) Command('b', 'a', 'cp $SOURCE $TARGET')
再执行你给出的测试命令,第二次执行scons -Q b时就会触发重建,输出如下:
cp a b
提示:
target_signatures参数需要SCons 3.0及以上版本支持,如果你使用的是更早的版本,可以通过自定义构建决策函数实现同等逻辑。
方式2:仅为指定目标开启签名校验
如果你不想全局开启该规则,可以单独为Flex生成C++的构建目标配置:
flex_gen = Command('lex.yy.cc', 'lexer.l', 'flex -o $TARGET $SOURCE') flex_gen.Decider('MD5', target_signatures=True)
这样配置只会对Flex生成的C++文件做目标状态校验,其他构建目标仍然沿用默认逻辑。
场景适配说明
该配置完全适配你提到的Flex生成文件托管在版本控制的场景:无论生成的C++文件被版本控制回退到旧版本,还是被人为修改,SCons都会检测到目标状态和上次成功构建的记录不一致,自动触发重新构建,保证生成文件和Flex源文件版本匹配。
内容的提问来源于stack exchange,提问作者Piotr Siupa
相关产品推荐
相关产品推荐

