从规则中设置变量 [英] Set a variable from within a rule

查看:90
本文介绍了从规则中设置变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个外部工具,该工具可以获取某些资源( Rebar ).钢筋运行后,我想根据目录 的内容填写一个变量.

I have an external tool that fetches some sources (Rebar). I want to fill in a variable according to the contents of a directory after Rebar runs.

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)

如果我将其作为两个单独的调用运行,则以上内容将按预期工作:

The above will work as intended if I run it as two separate invocations:

make build-deps
make build-main

但是,如果我只是创建build-main,则EFLAGS会在deps/目录为空时设置,然后填充目录,然后使用EFLAGS.

However, if I just make build-main, then EFLAGS gets set while the deps/ directory is empty, then the directory is populated, and then I use EFLAGS.

我有一种很好的方法来在运行一些规则后才设置EFLAGS吗?

Is there a good way for me to only set EFLAGS after I've run some rules?

编辑:以下是一个Makefile,可以更轻松地演示问题:

EDIT: Here's a Makefile that may demonstrate the problem more easily:

A=$(wildcard test*)

foo:
    touch test1

bar: foo
    @echo $A

clean:
    -rm test*

在这里,"foo"目标正代表我对rebar的调用,因此,请想象一下,您不知道我要传递给touch的文件.如果您尝试

Here, the "foo" target is standing in for my call to rebar, so just imagine that you don't know which files I'm going to pass to touch. If you try

make clean
make bar
make bar

您会发现make bar的两个调用产生不同的结果,因为在第二个调用中,test1make开始之前存在.我正在寻找一种在运行make clean之后立即获取第二个make bar调用的输出的方法.

you will find that the two invocations of make bar produce different results, because in the second one test1 exists before make begins. I'm looking for a way to get the output of the second make bar invocation immediately after running make clean.

推荐答案

我相信使用包含的makefile进行以下操作是可行的. 未经测试,但我相信遵循这些原则的东西会做您想要的.假设您希望在每次尝试构建时都运行钢筋.

I believe something like the following, using an included makefile, will work. Untested but I believe something along these lines will do what you want. Assuming you want to run rebar every time you try to build.

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: ;

以上进行了编辑,删除了paflags.mk上的.PHONY声明,因为这似乎会使make不执行使此技巧起作用所需的重新启动.

Above edited to remove the .PHONY declaration on paflags.mk as that seemed to cause make to not perform the restart necessary for this trick to work.

或者,由于您没有为此使用make的前提测试,因此可以将其全部移至build-main规则主体中并进行globing/etc.在外壳中.

Alternatively, since you aren't using any of make's prerequisite testing for this you could just move it all into the build-main rule body and do the globbing/etc. in the shell.

或者,您可以使用eval来强制评估我相信的构建主规则中的patsubst(我必须进行测试,以确保时序能够正确计算,至少GNU如何提升)在规则主体中创建指令.

Alternatively alternatively, you could use eval to forcibly evaluate the patsubst in the build-main rule I believe (I'd have to test that to be sure the timing works out correctly with how, GNU make at least, hoists make directives in rule bodies).

上面关于简单测试用例的想法的这个版本对我有用:

This version of the idea above for the simple test case works for me:

-include inc.mk

$(warning A:$A)

bar:
        @echo $A

inc.mk:
        touch test1
        echo 'A=$$(wildcard test*)' > '$@'

force: ;

编辑了两个样本makefile,以在包含的makefile上包含强制规则,以强制make每次构建包含的文件.否则,make只会在第一次构建包含的文件,然后再也不会触摸它.我相信,这支部队将始终避免建立这种部队,而为此付出代价,始终可以避免这种问题.

Edited both sample makefiles to include a force rule on the included makefile to force make to build the included file every time. Without that (and without fancy automatic dependency generation/detection) make will only build the included file the first time and then never touch it again. I believe the force, at a cost of always trying to build it, will avoid that problem.

话虽如此,对于这种情况, MadScientist的答案可能是更好的选择.

That being said, for this case, MadScientist's answer is probably the better choice.

这篇关于从规则中设置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆