从同一Makefile中的配方更改make变量并调用另一个规则?

从同一Makefile中的配方更改make变量并调用另一个规则?,makefile,gnu-make,Makefile,Gnu Make,我已经看过了,但我的问题有点不同;考虑这个例子(注意,StaskOffFult.com将选项卡更改为显示中的空格;但是如果尝试编辑,则在源中保留选项卡): 在这里,如果我运行默认目标(pdflatex),我会得到预期的输出: $ make pdflatex echo the engine is pdflatex the engine is pdflatex 但是,对于targetlualatex,我想: 将make变量TEXENGINE更改为lualatex,然后 调用与pdflatex中

我已经看过了,但我的问题有点不同;考虑这个例子(注意,StaskOffFult.com将选项卡更改为显示中的空格;但是如果尝试编辑,则在源中保留选项卡):

在这里,如果我运行默认目标(
pdflatex
),我会得到预期的输出:

$ make pdflatex 
echo the engine is pdflatex
the engine is pdflatex
但是,对于target
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中是否可行。

好吧,我设法找到了一种解决方法,但我并不完全了解它-因此,如果能提供一个更具学识的答案,我将不胜感激。对我来说,这些链接有助于:

下面是修改过的示例-显然,要在以后从规则调用规则(不是作为先决条件,而是作为后决条件),我只能递归调用
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 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!

首先,如果你用它来检查任意的东西,我不会称之为target
pdflatex
。我建议使用
checkEngine
,并将其设置为
.PHONY
。谢谢,@OliverCharlesworth-我认为这很好,因为在这个用例中,
pdflatex
是默认值,因此我只需
make
make pdflatex
(然后,用例是通过指定引擎作为
make
的目标来改变引擎,就像
make lualatex
一样)。干杯!好吧,这取决于你;)(我会发现这相当混乱和糟糕的做法…)你能做
make TEXENGINE=which
,并构造一组使用用户指定的
TEXENGINE
变量的通用目标/规则?再次感谢@OliverCharlesworth-我同意这是一种不好的做法,尤其是在代码构建方面;但是在这种情况下,这种makefile的增长将非常有限,因此我敢为了命令行的便利性而忽略错误的做法
:)
,否则,我就忘记了
make
命令行上的所有变量-在写下面的答案时刚刚记住。干杯谢谢@JonathanWakely——一开始我很困惑,因为先决条件会在
lualatex
之前调用
pdflatex
;但是后来我测试并实现了将
lualatex:
目标一分为二,避免了这个陷阱,而且解决方案也可以在没有递归
make
调用的情况下工作,这非常好。还感谢关于“目标特定变量”的说明。干杯更具体地说,如果您在
lualatex
中不需要做任何事情,而不仅仅是
pdflatex
所做的事情,那么您根本不需要
lualatex
目标上的配方主体。只有两行
lualatex:
就足够了。您可以定义多个变量吗?您的规则在这里所做的是运行另一个
make
实例并显式重写
TEXENGINE
变量。命令行中定义的变量优先于环境或makefile中定义的变量,因此当第二个
make
运行时,它将使用覆盖的值。这种方法的缺点是运行两次
make
,因此如果需要做大量工作来检查先决条件的状态,那么所有这些工作都要做两次。
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!