Makefile问题:CSS/JS更新时仅首个HTML文件触发构建
解决Makefile中仅首个HTML文件触发构建的问题
问题原因
你的Makefile规则$(HTML_Files) : $(CSS_Files) $(JS_Files)虽然定义了所有HTML文件依赖CSS/JS,但Make默认基于**文件修改时间(mtime)**做依赖检查:
- 若后续HTML文件的mtime晚于CSS/JS的mtime,Make会判定它们"up to date"
- 多目标规则的写法在部分场景下会导致依赖检查逻辑不符合预期,比如
hashinclude工具未修改文件内容时,不会更新HTML的mtime,但逻辑上需要重新处理
解决方案
推荐使用标记文件的方式,确保任意CSS/JS更新时,所有HTML文件都会触发构建。修改后的Makefile如下:
CSS_Files = $(wildcard wwwroot/assets/css/*.css) JS_Files = $(wildcard wwwroot/assets/js/*.js) HTML_Files = $(wildcard wwwroot/t*.htm wwwroot/pw*.html) # 标记文件:用于追踪CSS/JS的更新状态 ASSETS_TIMESTAMP = wwwroot/.assets_timestamp all : $(HTML_Files) # 任意CSS/JS更新时,更新标记文件的修改时间 $(ASSETS_TIMESTAMP): $(CSS_Files) $(JS_Files) @echo Updating assets timestamp @touch $@ # 所有HTML文件依赖标记文件,确保CSS/JS更新时触发构建 $(HTML_Files) : $(ASSETS_TIMESTAMP) @echo Build '$(@F)' -@attrib -r $@ @hashinclude $@ -inplace -hvonly # 可选:清理标记文件 clean: @del $(ASSETS_TIMESTAMP)
逻辑说明
ASSETS_TIMESTAMP作为中间依赖,只要CSS/JS文件更新,就会通过touch命令刷新其mtime- 所有HTML文件依赖该标记文件,当标记文件的mtime晚于HTML文件时,Make会强制触发构建命令
- 移除了原规则中无效的
$(%F)变量(该变量仅在模式规则中生效,此处为空值)
备选方案(强制全量构建)
如果需要每次运行Make都构建所有HTML文件(不依赖文件时间),可以使用FORCE目标:
CSS_Files = $(wildcard wwwroot/assets/css/*.css) JS_Files = $(wildcard wwwroot/assets/js/*.js) HTML_Files = $(wildcard wwwroot/t*.htm wwwroot/pw*.html) all : $(HTML_Files) FORCE: $(HTML_Files) : $(CSS_Files) $(JS_Files) FORCE @echo Build '$(@F)' -@attrib -r $@ @hashinclude $@ -inplace -hvonly
内容的提问来源于stack exchange,提问作者William Walseth
相关产品推荐
相关产品推荐

