【问题标题】:Source shell script into makefile源 shell 脚本到 makefile
【发布时间】:2014-09-30 06:48:12
【问题描述】:

我有一个 bash shell 脚本,我通常将它导入到我的 shell 中,其中定义了很多环境变量,这些环境变量是导出的。我不想:

  1. 导出变量,因为这会使可导出的环境太大,最终使整个系统变慢(从shell运行每个命令时都必须导出)
  2. 在 makefile (DRY) 中重新定义这些变量

我想将相同的 shell 脚本导入到 makefile 的环境中,以便我可以访问这些变量。这可能吗?我怎样才能做到这一点?理想情况下,我会在 makefile 中做:

source setup-env.sh

makefile 没有source 命令,但可能是等效的?有什么特别的技巧可以用来模拟相同的效果吗?

【问题讨论】:

  • 确实重复(我在之前的搜索中没有找到这个问题)。但是没有一个解决方案(黑客?)建议对我有吸引力。我认为最干净的解决方案是在调用 makefile 之前将整个环境标记为可导出。这可能吗,用一个命令? (我正在使用 bash)

标签: bash shell makefile environment-variables


【解决方案1】:

根据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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多