我有一个外部工具可以获取一些来源(Rebar)。我希望在 Rebar运行后根据目录的内容填写一个变量。
EFLAGS += -I$(PWD)/include
EFLAGS += -pa $(PWD)/ebin
## $(PWD)/deps/* will only have contents after Rebar runs
EFLAGS += $(patsubst %,-pa %,$(wildcard $(PWD)/deps/*/ebin))
build-deps:
./rebar get-deps
./rebar compile
build-main: build-deps
erlc $(EFLAGS) $(INFILE)
如果我将它作为两个单独的调用运行,上面的内容将按预期工作:
make build-deps
make build-main
但是,如果我只生成build-main
,那么EFLAGS
目录为空时会设置deps/
,然后填充目录,然后使用EFLAGS
。
在我执行某些规则后,我是否有一个好方法只能设置EFLAGS
?
编辑:这是一个可以更轻松地演示问题的Makefile:
A=$(wildcard test*)
foo:
touch test1
bar: foo
@echo $A
clean:
-rm test*
在这里,“foo”目标代表我对rebar
的调用,所以想象一下你不知道我要传递给touch
的文件。如果你试试
make clean
make bar
make bar
您会发现make bar
的两次调用会产生不同的结果,因为在test1
开始之前存在第二个make
。我正在寻找一种方法来在运行make bar
后立即获得第二次make clean
调用的输出。
答案 0 :(得分:4)
最简单的解决方案是使用shell来计算值,而不是使用make规则。像这样:
EFLAGS += -I$(PWD)/include
EFLAGS += -pa $(PWD)/ebin
## $(PWD)/deps/* will only have contents after Rebar runs
EFLAGS += $(patsubst %,-pa %,$(wildcard $(PWD)/deps/*/ebin))
build-deps:
./rebar get-deps
./rebar compile
build-main: build-deps
for f in $(PWD)/deps/*/ebin; do paflags="$$paflags -pa $$f"; done; \
erlc $(EFLAGS) $$paflags $(INFILE)
答案 1 :(得分:2)
我相信使用包含的makefile,以下内容将起作用。 未经测试但我相信这些方面的东西会做你想要的。假设您每次尝试构建时都想运行钢筋。
EFLAGS += -I$(PWD)/include
EFLAGS += -pa $(PWD)/ebin
EFLAGS += $(PADIRS)
-include paflags.mk
build-main:
erlc $(EFLAGS) $(INFILE)
paflags.mk: force
./rebar get-deps
./rebar compile
echo 'PADIRS := $$(patsubst %,-pa %,$$(wildcard $$(PWD)/deps/*/ebin))' > '$@'
force: ;
以上编辑删除.PHONY
上的paflags.mk
声明,因为这似乎导致make无法执行此技巧所需的重启。
或者,既然您没有使用make的任何先决条件测试,那么您可以将它全部移动到构建主规则体中并执行globbing / etc。在shell中。
或者替代地,您可以使用eval
强制评估构建主规则中的patsubst我相信(我必须对其进行测试,以确保时序与GNU make如何正确运行至少,提升者在规则体中制定指令。)
以上简单测试用例的这个版本对我有用:
-include inc.mk
$(warning A:$A)
bar:
@echo $A
inc.mk:
touch test1
echo 'A=$$(wildcard test*)' > '$@'
force: ;
编辑两个示例makefile以在包含的makefile上包含强制规则,以强制make每次构建包含的文件。没有它(并且没有花哨的自动依赖关系生成/检测)make将仅第一次构建包含的文件,然后再也不会再触摸它。我相信这种力量,总是试图建立它,将避免这个问题。
话虽如此,对于这种情况,MadScientist's answer可能是更好的选择。