从同一 Makefile 中的配方更改 make 变量并调用另一个规则?
Posted
技术标签:
【中文标题】从同一 Makefile 中的配方更改 make 变量并调用另一个规则?【英文标题】:Change a make variable, and call another rule, from a recipe in same Makefile? 【发布时间】:2014-12-10 13:08:42 【问题描述】:我已经看过How to manually call another target from a make target?,但我的问题有点不同;考虑这个例子(注意,***.com 将选项卡更改为显示中的空格;但如果您尝试编辑,选项卡会保留在源代码中):
TEXENGINE=pdflatex
pdflatex:
echo the engine is $(TEXENGINE)
lualatex:
TEXENGINE=lualatex
echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there!
在这里,如果我运行默认目标 (pdflatex
),我会得到预期的输出:
$ make pdflatex
echo the engine is pdflatex
the engine is pdflatex
但是,对于目标lualatex
,我想:
make
变量TEXENGINE
改为lualatex
,然后
调用与pdflatex
相同的代码(使用它)。
我怎么能这样做?
显然,在我的 lualatex
规则中,我什至无法更改 TEXENGINE
变量,因为我在尝试时得到了这个:
$ make lualatex
TEXENGINE=lualatex
echo Here I want to call the pdflatex rule, to check pdflatex there!
Here I want to call the pdflatex rule, to check pdflatex there!
...所以我真的很想知道 Makefiles 中是否有可能发生这样的事情。
【问题讨论】:
首先,如果您使用它来检查任意内容,我不会称该目标为pdflatex
。我建议checkEngine
之类的东西,然后改成.PHONY
。
谢谢,@OliverCharlesworth - 不过,我认为这很好,因为在这个用例中pdflatex
是默认值,所以我只得到make
或make pdflatex
的相同结果(然后用例是通过将引擎指定为make
的目标来更改引擎,如make lualatex
)。干杯!
好吧,这取决于你 ;)(我觉得这是相当混乱和不好的做法......)你能不能只做 make TEXENGINE=whatever
,并构建一组通用的目标/规则,使用用户指定的TEXENGINE
变量?
再次感谢@OliverCharlesworth - 我同意这是不好的做法,尤其是对于代码构建;但是在这种情况下,这种makefile的增长方式将非常有限,所以我敢于忽略不良做法以换取命令行便利:)
否则,我会忘记make
上的所有变量命令行-在下面写下我的答案时才想起。干杯!
【参考方案1】:
使用target-specific variable
目标特定变量还有一个特殊功能:当您定义目标特定变量时,该变量值也对该目标的所有先决条件及其所有先决条件等有效(除非这些先决条件覆盖具有自己的目标特定变量值的变量)。
TEXENGINE=pdflatex
pdflatex:
echo the engine is $(TEXENGINE)
lualatex: TEXENGINE=lualatex
lualatex: pdflatex
echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there!
输出是:
$ make pdflatex
echo the engine is pdflatex
the engine is pdflatex
$ make lualatex
echo the engine is lualatex
the engine is lualatex
echo Here I want to call the pdflatex rule, to check lualatex there!
Here I want to call the pdflatex rule, to check lualatex there!
【讨论】:
感谢@JonathanWakely - 一开始我很困惑,因为先决条件会在lualatex
之前调用pdflatex
;但后来我测试并实现将lualatex:
目标一分为二避免了这个陷阱——而且该解决方案在没有递归make
调用的情况下也可以工作,这很棒。也感谢关于“目标特定变量”的说明。干杯!
更具体地说,如果您在 lualatex
中不需要做任何事情,而这不仅仅是 pdflatex
所做的,那么您不需要 lualatex
目标上的配方正文一点也不。只需两行lualatex:
就足够了。
你能定义多个变量吗?【参考方案2】:
好吧,我设法找到了一种解决方法,但我不太了解它 - 因此将不胜感激。对我来说,这些链接有帮助:
Set a variable from within a rule make : rule call rule Passing additional variables from command line to make所以这里是修改后的例子——显然,为了事后从规则中调用规则(不是作为先决条件,而是作为post必要条件),我只能递归调用make
,同时在其命令行上指定了新的变量值:
TEXENGINE=pdflatex
pdflatex:
echo the engine is $(TEXENGINE)
lualatex:
echo Here I want to call the pdflatex rule, to check $(TEXENGINE) there!
$(MAKE) TEXENGINE=lualatex pdflatex
输出比我想要的要详细一些,但它确实有效:
$ make lualatex
echo Here I want to call the pdflatex rule, to check pdflatex there!
Here I want to call the pdflatex rule, to check pdflatex there!
make TEXENGINE=lualatex pdflatex
make[1]: Entering directory `/tmp'
echo the engine is lualatex
the engine is lualatex
make[1]: Leaving directory `/tmp'
...这是我想要的纯命令行交互方式,但我知道这不是最好的解决方案(请参阅下面的@JonathanWakely 评论)
【讨论】:
您的规则在这里执行的是运行make
的另一个实例并显式覆盖TEXENGINE
变量。命令行上定义的变量优先于环境或 makefile 中定义的变量,因此当第二个 make
运行时,它使用覆盖的值。这种方法的缺点是你运行make
两次,所以如果它必须做很多工作来检查先决条件的状态,那么你需要做两次所有的工作。以上是关于从同一 Makefile 中的配方更改 make 变量并调用另一个规则?的主要内容,如果未能解决你的问题,请参考以下文章