Makefile存在目标与依赖仍报错:无目标及生成目标配置问题
Makefile问题解答
问题1:执行make提示"No targets"的原因
你写的Makefile里只有模式规则(./corpus/%.spacy : ./assets/%.json),但没有指定具体要构建的目标文件。Make默认会执行文件中的第一个目标,而如果没有明确列出任何具体目标,它不知道该处理哪个文件,所以会报错。
哪怕A.spacy和A.json都存在,且A.json更新时间更晚,Make也不会自动处理——因为你没告诉它要构建./corpus/A.spacy这个具体目标。
解决办法
- 直接指定目标执行:
make ./corpus/A.spacy - 或者在Makefile开头加一个默认目标,批量处理所有符合条件的文件:
这样执行# 默认目标:构建所有对应.spacy文件 all: $(patsubst ./assets/%.json, ./corpus/%.spacy, $(wildcard ./assets/*.json)) ./corpus/%.spacy : ./assets/%.json python3 ./scripts/convert.py $< $@make时,会自动扫描./assets/下所有.json文件,生成对应的./corpus/%.spacy文件。
问题2:仅存在A.json时生成A.spacy的正确配置
你之前的convert目标有两个明显问题:
- 普通目标
convert不能直接依赖带%的模式路径——Make无法识别你要的具体文件,所以报错找不到目标。 - 命令里的
$(./scripts/$*.json)语法错误,而且依赖文件的路径也不对(你的json文件在./assets/下,不是./scripts/)。
正确配置方式
方式1:生成单个指定文件
如果只想生成A.spacy,直接执行:
make ./corpus/A.spacy
你最初写的模式规则已经支持这个逻辑,只要./assets/A.json存在,就会自动调用脚本生成目标文件。
方式2:批量生成所有对应文件
如果要批量处理./assets/下所有.json文件,用wildcard和patsubst函数自动生成目标列表:
# 声明convert是伪目标,避免和同名文件混淆 .PHONY: convert # convert目标依赖所有要生成的.spacy文件 convert: $(patsubst ./assets/%.json, ./corpus/%.spacy, $(wildcard ./assets/*.json)) # 模式规则:定义json转spacy的逻辑 ./corpus/%.spacy: ./assets/%.json python3 ./scripts/convert.py $< $@
执行make convert时,会自动扫描./assets/下所有.json文件,生成对应的./corpus/%.spacy文件;如果某个.spacy已经存在且比对应.json新,就不会重复构建。
补充说明
$(wildcard ./assets/*.json):获取./assets/目录下所有.json文件的路径列表$(patsubst 原模式, 新模式, 列表):把列表中符合原模式的路径替换成新模式,比如把./assets/A.json换成./corpus/A.spacy.PHONY: convert:标记convert为伪目标,防止当前目录存在同名文件时Make产生混淆
内容的提问来源于stack exchange,提问作者mac389
相关产品推荐
相关产品推荐

