如何在Makefile中设置子进程的环境变量

bod*_*ser 109 shell makefile environment-variables target

我想更改这个Makefile:

SHELL := /bin/bash
PATH  := node_modules/.bin:$(PATH)

boot:
    @supervisor         \
      --harmony         \
      --watch etc,lib       \
      --extensions js,json      \
      --no-restart-on error     \
        lib

test:
    NODE_ENV=test mocha         \
      --harmony             \
      --reporter spec       \
        test

clean:
    @rm -rf node_modules

.PHONY: test clean
Run Code Online (Sandbox Code Playgroud)

至:

SHELL := /bin/bash
PATH  := node_modules/.bin:$(PATH)

boot:
    @supervisor         \
      --harmony         \
      --watch etc,lib       \
      --extensions js,json      \
      --no-restart-on error     \
        lib

test: NODE_ENV=test
test:
    mocha                   \
      --harmony             \
      --reporter spec       \
        test

clean:
    @rm -rf node_modules

.PHONY: test clean
Run Code Online (Sandbox Code Playgroud)

不幸的是,第二个不起作用(节点进程仍以默认值运行)NODE_ENV.

我错过了什么?

Mad*_*ist 137

默认情况下,Make变量不会导出到进程调用环境中.但是你可以使用make export来强制它们这样做.更改:

test: NODE_ENV = test
Run Code Online (Sandbox Code Playgroud)

对此:

test: export NODE_ENV = test
Run Code Online (Sandbox Code Playgroud)

(假设你有一个足够现代的GNU make版本).

  • @Gauthier当然可以.那不是我写的.你在`all:`之后添加了一个<\n\t>,这不在我的例子中.我的示例旨在以书面形式使用:它定义了一个特定于目标的变量,_NOT_将一个命令添加到配方中.此外,您不能同时在目标上使用配方和特定于目标的变量:您必须两次编写目标.请参阅问题中的第二个示例,并询问一个新问题,如果这无法解释它:评论中没有足够的空间或格式. (8认同)
  • 我有GNU make 3.81,并且`all:<\n\t>导出PROJ_ROOT = $(CURDIR)<\n\t> echo $(PROJ_ROOT)<\n>`输出第一行的正确扩展,但仅限`echo`为第二个.运行make后没有设置`PROJ_ROOT`.`=`周围的空格给出了"坏变量名"用于导出.将第一行作为示例中的先决条件给出"命令在第一个目标之前开始" (2认同)
  • 多个变量呢? (2认同)
  • 特定于目标的变量已添加到GNU make 3.77中。从GNU make 3.81开始,它们可以导出。看到http://git.savannah.gnu.org/cgit/make.git/tree/NEWS (2认同)

Sha*_*Lee 54

正如MadScientist指出的那样,您可以使用以下方法导出单个变量:

export MY_VAR = foo  # Available for all targets
Run Code Online (Sandbox Code Playgroud)

您也可以指定.EXPORT_ALL_VARIABLES目标 - 您猜对了! - 出口所有事情!!!:

my-target: export MY_VAR_1 = foo
my-target: export MY_VAR_2 = bar
my-target: export MY_VAR_3 = baz

my-target: dependency_1 dependency_2
  echo do something
Run Code Online (Sandbox Code Playgroud)

请参阅.EXPORT_ALL_VARIABLES

  • @AnthonyC请在纠正别人之前测试你的答案 (3认同)
  • @AnthonyC之所以起作用,是因为有两个`MY_VAR`:一个是作为$`{MY_VAR}`访问的makefile变量,另一个是作为$$ MY_VAR`访问的bash导出变量。 (3认同)
  • .EXPORT_ALL_VARIABLES 是正确的答案 (3认同)
  • 奇怪的是,我之前进行了测试,证明它可以正常工作..(不知道为什么现在..)我可以返回并删除我猜到的评论。 (2认同)
  • 请注意,如果变量已存在于 makefile 中并且您只想将其导出到另一个命令,则可以使用语法“export var ?=”而不分配新值 (2认同)

Tho*_*ner 13

我只在本地需要环境变量来调用我的测试命令,这里是一个在bash shell中设置多个环境变量并转义美元符号的示例make.

SHELL := /bin/bash

.PHONY: test tests
test tests:
    PATH=./node_modules/.bin/:$$PATH \
    JSCOVERAGE=1 \
    nodeunit tests/
Run Code Online (Sandbox Code Playgroud)

  • 请编辑您的答案以包含一些解释.仅代码答案对于教育未来的SO读者几乎没有作用.您的答案是在审核队列中因为质量低劣. (5认同)