gpt4 book ai didi

shell - 如何防止make将任何变量传递给子make?

转载 作者:行者123 更新时间:2023-12-01 02:25:12 25 4
gpt4 key购买 nike

我无法阻止make从将任何变量传递给子制作。我已经阅读了手册并遵循了他们的建议(重置 MAKEOVERRIDESMAKEFLAGS ),但我认为它仍然无法正常工作。

考虑以下原型(prototype) Makefile:

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

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

all:
echo done!

如果我 make VAR=10 none ,我得到以下信息:
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到子制作。这是正确的行为吗?

我试过 unexport VARbash -c make ...没有任何运气。

编辑:我已修改 none的食谱: bash -c "echo $$MAKEOVERRIDES $$MAKEFLAGS $$VAR" ; make ...
通过这种方式,我发现 VAR 实际上是通过 make 为要执行的命令创建的环境而不是通过其他变量传递的(其他变量也以这种方式传递给 make)。

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

编辑:有人问我为什么要这样做;我会试着在这里回答这个问题。

我有一个“模块”,它使用一个名为 CONFIG 的变量。为了构建这个模块,我需要构建另一个部分不相关的“模块”,它也使用 CONFIG,但具有不同的值。问题是当我尝试构建“子模块”时,CONFIG 包含“ super 模块”的值。我可以在制作“子模块”时指定 CONFIG ,但是两个模块都使用许多具有相同名称的变量,并且试图指定它们都会使模块紧密耦合,这是我无法承受的。

怎么会这么难……

最佳答案

这是错误的:

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

这些变量( MAKEOVERRIDESMAKEFLAGS )由父制造在环境中设置,以传递给子制造。在配方中设置这些值的覆盖将无济于事,因为 make 必须在实际启动配方中的命令之前为配方设置环境(当然)。

您必须在父 makefile 中覆盖/删除这些值,以便父 make 在构造子 make 的环境之前看到这些更改:
MAKEOVERRIDES =
none:
$(MAKE) -f Makefile all

没有完美的方法可以做到这一点。但是,您可以玩一个在大多数情况下都有效的技巧:
unexport $(shell echo '$(MAKEOVERRIDES)' | sed 's/=[^ ]*//g')
MAKEOVERRIDES =

第一行尝试取消导出 MAKEOVERRIDES 中的所有变量。第二行重置 MAKEOVERRIDES。这有几个问题。一个是如果 MAKEOVERRIDES 为空,它将自行使用“unexport”来取消导出所有内容。这可以通过在 shell 函数之前添加一些虚假变量来轻松解决。另一个是如果任何变量的值包含空格,扩展将认为它是一个未导出的变量。这可能没问题,但很奇怪。

我想不出更好的方法来做到这一点。

你并没有真正说出你为什么要这样做。您是否考虑过做一些不同的事情,例如使用 env 运行您想要拥有“vanilla”环境的命令;例如,如果您想使用一组有限且特定的环境变量运行命令,您可以运行:
test:
env -i PATH='$(PATH)' LANG='$(LANG)' runMyCommand --with --my arguments

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

或者,您可以尝试启动一个登录 shell,它将从头开始重新读取用户的 shell 设置环境:
test:
/bin/sh -lc 'runMyCommand --with --my arguments'

编辑:这很困难,因为您要求做的事情(限制子制作的环境)很棘手。

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

因此,如果您的目标是允许子 make 中的变量不受提供给上级 make 的命令行变量的影响,那么所有这些将变量从环境中取出的繁琐操作都是不必要的。在子 makefile 中设置的变量将优先于环境中的值。所以你所要做的就是通过设置 MAKEOVERRIDES 来摆脱在命令行上设置的变量,我已经在上面展示了如何做到这一点。

关于shell - 如何防止make将任何变量传递给子make?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17050611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com