如何解决Makefile-多个配方调用一个带有变量的配方-仅第一个运行
我已经按照如下所示设置了我的makefile,以最大程度地减少代码重复
配方是一组设置变量的块,然后运行sleeper_agent配方。例如,当它们分别称为make xlsx_sleeper
时,它们的效果很好。
但是当我调用all_sleepers
时,只有第一个(xlsx_sleeper)会被编译。
我尝试将它们声明为伪造(.PHONY: all_sleepers xlsx_sleeper docx_sleeper pptx_sleeper pdf_sleeper png_sleeper
),但不会改变
并在sleeper_agent规则中添加.FORCE规则,这将导致没有此类文件或目录:
.FORCE:
sleeper_agent: .FORCE [...]
这是我的文件:
all_sleepers: xlsx_sleeper docx_sleeper pptx_sleeper png_sleeper pdf_sleeper
sleeper_agent: $(OBJ)/sleeper_agent.o $(OBJ)/identities.o
windres icons/$(ext)/resource.rc -O coff -o obj/$(ext).res
$(CC) -o $(BIN)/sleeper_$(ext).exe $^ $(OBJ)/$(ext).res $(CFLAGS) $(LIBS)
xlsx_sleeper: ext=xlsx
xlsx_sleeper: sleeper_agent
docx_sleeper: ext=docx
docx_sleeper: sleeper_agent
pptx_sleeper: ext=pptx
pptx_sleeper: sleeper_agent
png_sleeper: ext=png
png_sleeper: sleeper_agent
pdf_sleeper: ext=pdf
pdf_sleeper: sleeper_agent
解决方法
您的问题是make看不出为什么应该多次重建sleeper_agent
目标的任何原因。您可能应该坚持制造哲学:
- 尝试将真实文件作为目标(
$(BIN)/sleeper_xlsx.exe
)。 - 仅使用phony(非文件)目标:
- 为其他目标或目标组(
all_sleepers
,xlsx_sleeper
,...)赋予符号名称 - 对于不生成文件的规则(
clean
,help
...)
- 为其他目标或目标组(
- 这样声明虚假目标(
.PHONY: ...
)
使用static pattern rules,automatic variables和patsubst
make函数的示例:
SLEEPER := xlsx docx pptx png pdf
EXE := $(patsubst %,$(BIN)/sleeper_%.exe,$(SLEEPER))
SHORT := $(patsubst %,%_sleeper,$(SLEEPER))
.PHONY: all_sleepers $(SHORT) clean_sleepers
all_sleepers: $(EXE)
$(SHORT): %_sleeper: $(BIN)/sleeper_%.exe
$(EXE): $(BIN)/sleeper_%.exe: $(OBJ)/sleeper_agent.o $(OBJ)/identities.o
windres icons/$*/resource.rc -O coff -o obj/$*.res
$(CC) -o $@ $^ $(OBJ)/$*.res $(CFLAGS) $(LIBS)
clean_sleepers:
rm -f $(EXE)
然后您应该可以运行:
make all_sleepers
全部构建它们,或:
make xlsx_sleeper
仅构建其中之一。 EXE
是实际的可执行文件的列表,并且静态模式规则说明了如何构建它们。在其配方中,$*
自动变量随着与%
通配符匹配的字符串而扩展。 SHORT
是xxxx_sleeper
快捷方式的列表,另一个静态模式规则为每个快捷方式说明了其对应的实际可执行文件。 all_sleepers
和xxxx_sleeper
快捷方式(加上我作为示例添加的clean_sleepers
)被正确地声明为phony,因为没有这样的真实文件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。