在规则中设置变量

时间:2014-06-03 16:01:23

标签: makefile

我有一个外部工具可以获取一些来源(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调用的输出。

2 个答案:

答案 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可能是更好的选择。