如何防止make将任何变量传递给子make? [英] How to prevent make from communicating any variable to a submake?

查看:210
本文介绍了如何防止make将任何变量传递给子make?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法阻止make将任何变量传递给子品牌.我已经阅读了手册,并遵循了他们的建议(重置MAKEOVERRIDESMAKEFLAGS),但是如果我认为应该仍然没有用.

I am unable to prevent make from communicating any variables to a submake. I've read the manual and I've followed their advice (resetting MAKEOVERRIDES and MAKEFLAGS) but it's still not working has I think it should.

考虑以下原型Makefile:

Consider the following prototype Makefile:

${warning $(MAKEOVERRIDES)}
${warning $(MAKEFLAGS)}
${warning $(VAR)}

none:
    $(MAKE) -f Makefile MAKEOVERRIDES= MAKEFLAGS= all

all:
    echo done!

如果我make VAR=10 none,我得到以下信息:

If I make VAR=10 none, I get the following:

Makefile:2: VAR=10
Makefile:3: 
Makefile:4: 10
make -f Makefile MAKEOVERRIDES= MAKEFLAGS= all
make[1]: Entering directory `/home/adriano/sandbox/makes'
Makefile:2: 
Makefile:3: 
Makefile:4: 10
echo done!
done!
make[1]: Leaving directory `/home/adriano/sandbox/makes'

表示make是与子品牌的通信VAR.这是正确的行为吗?

Meaning that make is communication VAR to the submake. Is this the correct behaviour?

我尝试了unexport VARbash -c make ...却没有任何运气.

I've tried unexport VAR and bash -c make ... without any luck.

我已经将none的配方修改为:bash -c "echo $$MAKEOVERRIDES $$MAKEFLAGS $$VAR" ; make ...

I've modified none's recipe to: bash -c "echo $$MAKEOVERRIDES $$MAKEFLAGS $$VAR" ; make ...

通过这种方式,我发现VAR实际上是通过make创建要执行的命令的环境传递的,而不是通过其他变量传递的(其他变量也通过make传递).

This way I found out that VAR is actually being passed through the environment that make creates for the commands to be executed and not through the other variables (the other variables are also passed this way to make).

我想我现在的问题是:如何创建一个新的shell/环境来运行我的sub make?

I think my question now is: how can I create a fresh shell/environment to run my sub make?

有人问我为什么要这样做?我会在这里尝试回答.

Someone asked why am I trying to this; I'll try to answer to that here.

我有一个模块",它使用一个名为CONFIG的变量.为了构建此模块,我需要构建另一个部分不相关的模块",该模块也使用CONFIG,但具有不同的值.问题是,当我尝试构建子模块"时,CONFIG包含超级模块"的值.我可以在制作子模块"时指定CONFIG,但是两个模块都使用许多同名变量,而尝试全部指定它们将使模块紧密耦合,这是我买不起的.

I have a "module" which uses a variable named CONFIG. In order to build this module I need to build another partially unrelated "module" which also uses CONFIG, but with a different value. The problem is that when I try to build the "sub-module" CONFIG contains the value of the "super-module." I could specify CONFIG when making the "sub-module" however both modules use many variables with the same name and trying to specify them all would make the modules tightly coupled which is something I cannot afford.

这怎么这么困难...

How can this be so difficult...

推荐答案

这是错误的:

none:
        $(MAKE) -f Makefile MAKEOVERRIDES= MAKEFLAGS= all

这些变量(MAKEOVERRIDESMAKEFLAGS)由父make在环境中设置,然后传递给子make.在配方内部设置这些值的替代值将无济于事,因为make必须在实际启动配方中的命令之前设置配方的环境(当然).

These variables (MAKEOVERRIDES and MAKEFLAGS) are set in the environment by the parent make to be passed down to the sub-makes. Setting overrides on these values inside the recipe won't help, because make has to set the environment for the recipe before it actually starts the commands in the recipe (of course).

您必须在父Makefile中覆盖/删除这些值 ,以便父Make在构造子Make的环境之前可以看到这些更改:

You have to override/remove these values in the parent makefile, so that those changes are seen by the parent make before it constructs the sub-make's environment:

MAKEOVERRIDES =
none:
        $(MAKE) -f Makefile all

没有完美的方法来做到这一点.但是,您可以玩一个在大多数时间都有效的技巧:

There's no perfect way to do this. However, you can play a trick that will work most of the time:

unexport $(shell echo '$(MAKEOVERRIDES)' | sed 's/=[^ ]*//g')
MAKEOVERRIDES =

第一行尝试取消导出MAKEOVERRIDES中的所有变量,第二行重置MAKEOVERRIDES.这有一些问题.一种是,如果MAKEOVERRIDES为空,它将单独使用"unexport",从而取消导出所有内容.通过在shell函数之前粘贴一些伪造变量,可以轻松解决此问题.另一个是如果任何变量的值包含空格,则扩展将认为它是未导出的变量.可能没关系,但这很奇怪.

The first line tries to unexport all the variables in MAKEOVERRIDES and the second line resets MAKEOVERRIDES. There are a few issues with this. One is that if MAKEOVERRIDES is empty, it will use "unexport" by itself which unexports everything. That can be easily worked around by sticking some bogus variable before the shell function. The other is that if any variable's value contains whitespace, the expansion will consider it a variable to be unexported. That's probably OK, but it's odd.

我想不出更好的方法.

您并不是真的要说为什么.您是否考虑过做一些不同的事情,例如使用env在您希望拥有原始"环境的地方运行命令;例如,如果您要运行带有一组有限且特定的env vars的命令,则可以运行:

You don't really say why you want to do this. Have you considered doing something different, such as running the commands where you want to have a "vanilla" environment using env; for example if you want to run a command with a limited and specific set of env vars, you can run:

test:
        env -i PATH='$(PATH)' LANG='$(LANG)' runMyCommand --with --my arguments

不幸的是,某些版本的env使用-而不是-i;检查您的手册页.

Unfortunately some versions of env use - instead of -i; check your man page.

或者,您可以尝试启动登录外壳程序,它将从头开始重新读取用户的外壳程序安装环境:

Alternatively, you can try to start a login shell which will re-read the user's shell setup environment from scratch:

test:
        /bin/sh -lc 'runMyCommand --with --my arguments'

这很困难,因为您要执行的操作(限制子品牌的环境)很棘手.

It's difficult because what you're asking to do (restrict the environment of the sub-make) is tricky.

幸运的是,根据您的描述,这似乎没有必要. Make具有查找变量值的重要性层次结构.命令行是最高级别(嗯,有override,但我们将忽略它).之后是在makefile本身中设置的变量.从环境中导入的变量是最后也是最低的(当然,默认变量更低,但我们也将忽略它).

Luckily based on your description, it doesn't seem necessary. Make has a hierarchy of importance for finding variable values. The command line is the highest level (well, there's override but we'll ignore that). After that comes variables set in the makefile itself. And last and lowest comes variables imported from the environment (well, default variables are even lower but we'll ignore that too).

因此,如果您的目标是使子make中的变量不受分配给上级make的命令行变量的影响,那么将变量移出环境的所有繁琐工作就没有必要了.在子makefile文件中设置的变量将优先于环境中的值.因此,您要做的就是摆脱在命令行上设置的变量,通过设置MAKEOVERRIDES,我已经在上面演示了如何做.

So if your goal is to allow the variables in the sub-makes to not be affected by command line variables given to the upper-level makes, then all this rigmarole of getting the variables out of the environment is not necessary. Variables set in the sub-makefiles will take precedence over the values in the environment. So all you have to do is get rid of the variables set on the command line, which I've already shown how to do above, by setting MAKEOVERRIDES.

这篇关于如何防止make将任何变量传递给子make?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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