GNU make中的高级变量继承 [英] Advanced variable inheritance in GNU make

查看:87
本文介绍了GNU make中的高级变量继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读GNU make手册,并对变量继承机制感到困惑.让我先了解一下基础知识.

I'm reading the GNU make manual, and got confused about the variable inheritance mechanism. Let me go through the basics first.

我引用了手册章节 6.10来自环境的变量:

制造商中的变量可以来自运行制造商的环境. make 启动时看到的每个环境变量都将转换为具有相同名称和值的 make 变量.

Variables in make can come from the environment in which make is run. Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value.

因此,假设我打开一个外壳程序(称为外壳程序1"),然后定义了两个变量.然后,使用两个选项"op1"和"op2"启动 make .程序 make 本身读取一个makefile并构造一个名为"varC"的第三个变量.我们得到如下图所示的情况:

So imagine that I open a shell (call it "shell 1") and I define two variables. Then I startup make with two options, "op1" and "op2". The program make itself reads a makefile and constructs a third variable, called "varC". We get the situation as in the figure below:

我继续引用手册中的语录:

I continue with a quote from the manual:

make 运行配方时,makefile中定义的变量将放入每个外壳程序的环境中.

When make runs a recipe, variables defined in the makefile are placed into the environment of each shell.

这就是我现在要做的.将执行目标的第一条配方行,为此 make 打开一个临时外壳(称为外壳2").我假设所有变量"varA","varB"和"varC"都存在于此外壳中,因此可以由配方行使用.虽然我不确定100%.

So that's what I am going to do now. The first recipe line for the target gets executed, for which make opens a temporary shell (call it "shell 2"). I presume that all variables "varA", "varB" and "varC" are present in this shell, and thus can be used by the recipe line. Although I am not 100% sure.

本手册继续介绍食谱递归调用 make 的情况:

The manual continues about the case where a recipe calls make recursively:

默认情况下,仅将来自环境或命令行的变量传递给递归调用.您可以使用 export 指令来传递其他变量.

By default, only variables that came from the environment or the command line are passed to recursive invocations. You can use the export directive to pass other variables.

下一个配方行是递归$(MAKE)调用.顶级 make 打开一个临时shell(称为"shell 3")来运行此 sub-make 实例.因为varC没有显式导出,所以我相信它在Shell 3中也不会存在,在 sub-make 中也不存在.我说得对吗?

The next recipe line is a recursive $(MAKE) call. The toplevel make opens a temporary shell (call it "shell 3") to run this sub-make instance. Because varC was not explicitely exported, I believe that it is not present in shell 3, nor in the sub-make. Am I correct?

我发布了这个主题,以使有经验的Makefile编写者得到澄清.我是该主题的新手,但是我正在努力研究手册,并从此开始着手.非常感谢所有帮助:-)

I posted this topic to get clarifications from experienced makefile writers. I am a newbie to this topic, but I'm doing my best to study the manual and get started after that. All help is greatly appreciated :-)

PS:如果您发布答案,请说明您的答案是否适用于Linux和/或Windows.

PS: if you post an answer, please mention if your answer applies to Linux, Windows, or both.

推荐答案

由于我在这里没有Unix环境,因此我只会回答Windows.它应该已经很好地说明了它在GNU make中的工作方式.

I will answer for Windows only since I do not have a Unix environment here. It should already give a good view of how it works in GNU make.

首先,我将假设您所谈论的环境变量具有与正在运行的Shell的生命周期相关联的生命周期,因此它不是系统环境变量.

At first I will assume that the environment variables your are talking about have a life cycle linked with the life cycle of the running shell, so it's not a system environment variable.

在Windows上,有两个程序可以设置变量:SETSETX.可能还有更多的微妙之处,但是为了简单起见,SET将仅为当前shell及其子进程设置一个变量,而SETX将设置一个系统环境变量.我只使用SET,因为我不想处理系统环境变量.

On Windows there are two programs to set a variable : SET and SETX. There a probably more subtleties, but to keep it simple, SET will set a variable only for the current shell and its sub-processes, and SETX will set a system environment variable. I'll only use SET since I don't want to deal with system environment variables.

我将给出一个经验性的答案.我已经对此设置进行了测试:

I will give an empiric answer. I have done the test on this setup :

\---level1
    |   Makefile
    |   
    \---level2
        |   Makefile
        |   
        \---level3
                Makefile

level1-Makefile

LEVEL = LEVEL1
LEVEL1VAR = VAR1
varB = 12
export varB

.PHONY: foo

foo:
    @echo $(LEVEL) var level 1 : $(LEVEL1VAR)
    @echo $(LEVEL) varA is $(varA)
    @echo $(LEVEL) varB is $(varB)
    cd level2 & $(MAKE) foo

level2-Makefile

LEVEL = LEVEL2
LEVEL2VAR = VAR2
MKID = MKID2

varC = 13
export varC

.PHONY: foo

foo:
    @echo $(LEVEL) var level 1 : $(LEVEL1VAR)
    @echo $(LEVEL) var level 2 : $(LEVEL2VAR)
    @echo $(LEVEL) varA is $(varA)
    @echo $(LEVEL) varB is $(varB)
    cd level3 & $(MAKE) foo

level3-Makefile

LEVEL = LEVEL3
LEVEL3VAR = VAR3

.PHONY: foo

foo:
    @echo $(LEVEL) var level 1 : $(LEVEL1VAR)
    @echo $(LEVEL) var level 2 : $(LEVEL2VAR)
    @echo $(LEVEL) var level 3 : $(LEVEL3VAR)
    @echo $(LEVEL) varA is $(varA)
    @echo $(LEVEL) varB is $(varB)
    @echo $(LEVEL) varC is $(varC)

在测试开始时,我在level1文件夹中打开一个外壳程序(Windows命令提示符).我创建一个值为11的变量varA:

At the beginning of the test I open a shell (Windows command prompt) in the level1 folder. I create a variable varA with the value 11 :

SET varA=11

然后,我调用第一个Makefile,后者将调用第二个,而后者将调用第三个.

Then I call the first Makefile, which will call the second, which will call the third.

make foo

以下是输出:

LEVEL1 var level 1 : VAR1
LEVEL1 varA is 11
LEVEL1 varB is 12
cd level2 & make foo
LEVEL2 var level 1 : 
LEVEL2 var level 2 : VAR2
LEVEL2 varA is 11
LEVEL2 varB is 12
cd level3 & make foo
LEVEL3 var level 1 : 
LEVEL3 var level 2 : 
LEVEL3 var level 3 : VAR3
LEVEL3 varA is 11
LEVEL3 varB is 12
LEVEL3 varC is 13

所以我们可以看到:

  • 可以从make的所有子调用中访问shell变量
  • 可以从此Makefile的make的所有子调用中访问导出的Makefile变量
  • 无法从此Makefile的make子调用中访问未导出的Makefile变量
  • The shell variable can be accessed from all the sub-calls of make
  • An exported Makefile variable can be accessed from all the sub-calls of make of this Makefile
  • A non-exported Makefile variable cannot be accessed from the sub-calls of make of this Makefile

您可以轻松地重现此示例以执行更多测试.

You can easily reproduce this example to perform more tests.

请注意,您实际上可以包含另一个Makefile,因此可以获取其变量和规则,请参见

Note that you can actually include another Makefile and therefore acquire its variables and rules, see GNU make: Include. I don't recommend to use this if you don't pay a really close attention to what happens, because you can override rules if they have the same name in the included Makefile as in the one which includes.

这篇关于GNU make中的高级变量继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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