根据additional question in the comment,这是一种有效地将整个环境标记为导出的方法:
for var in $(compgen -v); do export $var; done
compgen -v 按照bash manual, section 8.7 Programmable Completion Builtins 简单地输出所有变量名。然后我们简单地遍历这个列表和export每个。
感谢https://stackoverflow.com/a/16337687/2113226 - compgen 对我来说是新的。
有两种方法可以将其集成到您的制作工作流程中:
- Shell 脚本包装器
只需编写一个 shell 脚本,获取 setup-env.sh 的源代码,导出所有变量如上,然后调用 make 本身。比如:
#!/bin/bash
./source setup-env.sh
for var in $(compgen -v); do export $var; done
make $@
- 递归生成
可能是您不想要一个 shell 脚本包装器,并且出于任何原因想要直接调用 make。您可以在一个递归调用自身的 Makefile 中完成这一切:
$(info MAKELEVEL=$(MAKELEVEL) myvar=$(myvar))
ifeq ($(MAKELEVEL), 0)
all:
bash -c "source ./setup-env.sh; \
for var in \$$(compgen -v); do export \$$var; done; \
$(MAKE) $@"
else
all: myprog
myprog:
echo "Recipe for myprog. myvar=$(myvar)"
endif
这个 Makefile 的输出是:
$ make
MAKELEVEL=0 myvar=
bash -c "source ./setup-env.sh; \
for var in \$(compgen -v); do export \$var; done; \
make all"
MAKELEVEL=1 myvar=Hello World
make[1]: Entering directory `/home/ubuntu/makesource'
echo "Recipe for myprog. myvar=Hello World"
Recipe for myprog. myvar=Hello World
make[1]: Leaving directory `/home/ubuntu/makesource'
$
我们检查 GNU Make 内置变量 MAKELEVEL 以了解我们所处的递归级别。如果级别为 0,则我们递归调用所有目标的 make,但首先获取 ./setup-env.sh 并导出所有变量。如果递归级别是别的什么,我们只做正常的 makefile 的东西,但你会看到你需要的变量现在可用。 Makefile 顶部的 $(info ) 行突出显示了这一点,它显示了递归级别,以及 myvar 的值(或不是)。
注意事项:
-
我们必须使用bash -c,因为compgen 严格来说是一个bash 内置函数,并且在Posix 模式下不可用——即当make 默认以sh -c 调用shell 时。
-
第一个all: 配方中的$ 需要非常小心地转义。 $$ 逃脱了 $ 被 make 扩展,\$$ 逃脱了 $ 被隐式 sh 扩展
-
有大量文献认为“递归生成被认为是有害的”。例如。 http://aegis.sourceforge.net/auug97.pdf