Make在错误目录查找源文件,如何修正此构建问题?
修正Makefile中路径匹配错误的方案
我多方查找该问题的解决方案但无果。现有一套可生成HTML的源码,使用Makefile构建,目录结构如下:
main/ main/Makefile main/src main/src/dox main/src/dox/generate.rb ...
Makefile相关内容:
sources := $(shell find src -name "*rb" ) pages := $(sources:src/%.rb=%.html) all: $(pages) %.html: src/%.rb ruby $< > $@
执行make -dr后输出错误:
(snip) Considering target file 'dox/generate.html'. File 'dox/generate.html' does not exist. Looking for an implicit rule for 'dox/generate.html'. Trying pattern rule with stem 'generate'. Trying implicit prerequisite 'dox/src/generate.rb'. Trying pattern rule with stem 'generate'. Trying implicit prerequisite 'dox/src/generate.rb'. Looking for a rule with intermediate file 'dox/src/generate.rb'. Avoiding implicit rule recursion. No implicit rule found for 'dox/generate.html'. Finished prerequisites of target file 'dox/generate.html'. Must remake target 'dox/generate.html'. make: *** No rule to make target 'dox/generate.html', needed by 'build'. Stop.
显然make在错误的目录中查找源文件,规则看似正确但无法匹配。
修正方法
问题出在GNU make对隐式模式规则的匹配逻辑上:当目标文件包含目录路径时,隐式规则的%只会匹配文件名部分而非完整路径(包括目录),导致它错误地尝试寻找dox/src/generate.rb而非正确的src/dox/generate.rb。
可以通过静态模式规则替代隐式规则,明确绑定目标与依赖的路径关系,修正代码如下:
sources := $(shell find src -name "*rb" ) pages := $(sources:src/%.rb=%.html) all: $(pages) # 使用静态模式规则,明确指定pages集合中的目标对应的依赖路径 $(pages): %.html: src/%.rb # 先创建目标文件所在的目录(如果不存在) @mkdir -p $(@D) ruby $< > $@
解释
- 静态模式规则
$(pages): %.html: src/%.rb会遍历pages中的每个目标(比如dox/generate.html),将%匹配为dox/generate,从而正确找到依赖文件src/dox/generate.rb。 - 添加
@mkdir -p $(@D)是为了确保生成HTML文件时,目标目录(比如dox/)已经存在,避免因目录缺失导致的写入失败。
内容的提问来源于stack exchange,提问作者ariel
相关产品推荐
相关产品推荐

