You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 $< > $@

解释

  1. 静态模式规则$(pages): %.html: src/%.rb会遍历pages中的每个目标(比如dox/generate.html),将%匹配为dox/generate,从而正确找到依赖文件src/dox/generate.rb。
  2. 添加@mkdir -p $(@D)是为了确保生成HTML文件时,目标目录(比如dox/)已经存在,避免因目录缺失导致的写入失败。

内容的提问来源于stack exchange,提问作者ariel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:46:29