加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

shell – 如何防止make将任何变量传递给submake?

发布时间:2020-12-15 20:59:35 所属栏目:安全 来源:网络整理
导读:我无法阻止make将任何变量传递给子制作.我已经阅读了手册,并且我已经按照他们的建议(重置MAKEOVERRIDES和MAKEFLAGS),但我认为它仍然无法正常工作. 考虑以下原型Makefile: ${warning $(MAKEOVERRIDES)}${warning $(MAKEFLAGS)}${warning $(VAR)}none: $(MAKE
我无法阻止make将任何变量传递给子制作.我已经阅读了手册,并且我已经按照他们的建议(重置MAKEOVERRIDES和MAKEFLAGS),但我认为它仍然无法正常工作.

考虑以下原型Makefile:

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

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

all:
    echo done!

如果我使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是submake的通信VAR.这是正确的行为吗?

我试过了无法运行VAR和bash -c make ……没有任何运气.

编辑:我已经修改了没有的食谱:bash -c“echo $$MAKEOVERRIDES $$MAKEFLAGS $$VAR”;做…

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

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

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

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

怎么会这么难……

解决方法

这是错的:

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

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

您必须在父makefile中覆盖/删除这些值,以便在构造sub-make的环境之前,父make会看到这些更改:

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

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

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

第一行尝试取消导出MAKEOVERRIDES中的所有变量,第二行重置MAKEOVERRIDES.这有一些问题.一个是如果MAKEOVERRIDES为空,它将使用“unexport”本身,它取消了所有内容.通过在shell函数之前粘贴一些虚假变量,可以很容易地解决这个问题.另一个是如果任何变量的值包含空格,则扩展会将其视为未导出的变量.那可能没问题,但这很奇怪.

我想不出更好的办法.

你真的不想说你为什么要这样做.您是否考虑过做一些不同的事情,例如使用env运行您希望拥有“vanilla”环境的命令;例如,如果要运行具有有限且特定的env变量集的命令,则可以运行:

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

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

或者,您可以尝试启动一个登录shell,它将从头开始重新读取用户的shell设置环境:

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

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

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

因此,如果您的目标是允许子品牌中的变量不受给予上级品牌的命令行变量的影响,则不必将所有这些变量从环境中取出.子makefile中设置的变量将优先于环境中的值.因此,您所要做的就是通过设置MAKEOVERRIDES来摆脱命令行上设置的变量,我已经在上面展示了如何操作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读