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

sda*_*aau 25 makefile gnu-make

我已经看过如何从make目标手动调用另一个目标?,但我的问题有点不同; 考虑这个例子(注意,stackoverflow.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!
Run Code Online (Sandbox Code Playgroud)

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

$ make pdflatex 
echo the engine is pdflatex
the engine is pdflatex
Run Code Online (Sandbox Code Playgroud)

但是,有了目标lualatex,我想:

  • make变量更改TEXENGINElualatex,然后
  • 调用与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!
Run Code Online (Sandbox Code Playgroud)

...所以我真的想知道Makefiles中是否有这样的东西.

Jon*_*ely 33

使用特定目标的变量

目标特定变量还有一个特殊功能:当您定义特定于目标的变量时,变量值对此目标的所有先决条件及其所有先决条件等都有效(除非这些先决条件使用它们覆盖该变量)拥有特定于目标的变量值).

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!
Run Code Online (Sandbox Code Playgroud)

输出是:

$ 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!
Run Code Online (Sandbox Code Playgroud)

  • 更具体地说,如果你不需要在`lualatex`中做任何事情,而不仅仅是`pdflatex`,那么你根本就不需要`lualatex`目标上的食谱体.只有两个`lualatex:`行就足够了. (2认同)
  • @CpILL是的,您可以添加多个“lualatex:foo = bar”行,每行一个附加变量。(我不确定是否可以在一行上执行多个变量)。 (2认同)

sda*_*aau 6

好吧,我设法找到了一种解决方法,但我不太了解它-因此将不胜感激。对我来说,这些链接有帮助:

所以这是修改过的示例 - 显然,为了在之后从规则中调用规则(不是作为先决条件,而是作为后置条件),我只能递归调用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
Run Code Online (Sandbox Code Playgroud)

输出比我想要的更冗长,但它有效:

$ 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'
Run Code Online (Sandbox Code Playgroud)

...这就是我纯粹想要的命令行交互方式,但我知道这不是最好的解决方案(见下面@JonathanWakely 的评论)

  • 您的规则在这里所做的是运行另一个 `make` 实例并显式覆盖 `TEXENGINE` 变量。在命令行中定义的变量优先于在环境或 makefile 中定义的变量,因此当第二个 `make` 运行时,它使用覆盖的值。这种方法的缺点是你运行 `make` 两次,所以如果它必须做很多工作来检查先决条件的状态,那么你需要做两次所有的工作。 (4认同)