Mir*_*ral 3 linux foreach makefile gnu-make
给出以下 Makefile 片段:
TOOLS=foo bar
define TOOL_install
install -c $(1) $$(prefix)/bin/$(1)
endef
.PHONY: install
install: all
$(foreach tool,$(TOOLS),$(eval $(call TOOL_install,$(tool))))
Run Code Online (Sandbox Code Playgroud)
为什么make install打印“对‘安装’无需执行任何操作。” 而不是执行 foreach 指定的命令?(foreach 之前有一个选项卡,我尝试在 TOOL_install 定义中放置一个选项卡;但没有帮助。)
根据make -p安装目标没有命令,这显然不符合预期。
在同一个 makefile 的其他地方,我成功地使用相同的技术来创建整个规则,包括命令配方;我怎样才能在现有规则内实现这项工作?
(如果我替换eval为,info那么它会打印我期望它运行的命令。)
在这个简单的情况下,我可以通过内联命令让它工作:
install: all
@$(foreach tool,$(TOOLS),install -c $(tool) $(prefix)/bin/$(tool) ; )
Run Code Online (Sandbox Code Playgroud)
但我想知道如何让第一个表单按预期工作,以防我将来需要更复杂的东西。
您不应该eval在此处使用,因为您不想创建动态构造,而是创建恒定的规则。因此,只需删除并在定义末尾eval添加一个:;TOOL_install
TOOLS := foo bar
define TOOL_install
echo $(1);
endef
.PHONY: install
install:
$(foreach tool,$(TOOLS),$(call TOOL_install,$(tool)))
Run Code Online (Sandbox Code Playgroud)
扩展后,您Makefile将如下所示:
.PHONY: install
install:
echo foo; echo bar;
Run Code Online (Sandbox Code Playgroud)
另一个答案:
我们正在使用一些临时目标install_foo和install_bar。这两个目标被添加到install依赖项中并在之后声明。此外,在每个临时目标中,我们添加有关要安装的文件的依赖项(foo或bar)。这样您就可以根据需要添加规则,而且它是“并行兼容”的。
prefix := foobar
TOOLS := foo bar
install: $(addprefix install_,$(TOOLS))
$(addprefix install_,$(TOOLS)): install_%: %
install -c $< $(prefix)/bin/$<
.PHONY: install $(addprefix install_,$(TOOLS))
Run Code Online (Sandbox Code Playgroud)
编辑:
对于卸载目标(没有依赖项),您可以使用patsubst如下函数:
prefix := foobar
TOOLS := foo bar
uninstall: $(addprefix uninstall_,$(TOOLS))
$(addprefix uninstall_,$(TOOLS)):
install -c $(patsubst uninstall_%,%,$@) $(prefix)/bin/$(patsubst uninstall_%,%,$@)
.PHONY: uninstall $(addprefix uninstall_,$(TOOLS))
Run Code Online (Sandbox Code Playgroud)
我最终采用了我最初的问题和jml的答案的混合方法(感谢您的灵感!)。
TOOLS:=foo bar
.PHONY: all
all : $(TOOLS)
.PHONY: install $(addprefix install_,$(TOOLS))
install : $(addprefix install_,$(TOOLS))
.PHONY: uninstall $(addprefix uninstall_,$(TOOLS))
uninstall : $(addprefix uninstall_,$(TOOLS))
define TOOL_template
$(1): $$($(1)_OBJS)
#commands to build it
install_$(1): $(1)
install -c $(1) $$(prefix)/bin/$(1)
uninstall_$(1):
rm $$(prefix)/bin/$(1)
endef
$(foreach tool,$(TOOLS),$(eval $(call TOOL_template,$(tool))))
Run Code Online (Sandbox Code Playgroud)
似乎可以做到这一点。
| 归档时间: |
|
| 查看次数: |
17823 次 |
| 最近记录: |