How to set child process' environment variable in Makefile

ShellMakefileEnvironment VariablesTarget

Shell Problem Overview


I would like to change this 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

to:

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

Unfortunately the second one does not work (the node process still runs with the default NODE_ENV.

What did I miss?

Shell Solutions


Solution 1 - Shell

Make variables are not exported into the environment of processes make invokes... by default. However you can use make's export to force them to do so. Change:

test: NODE_ENV = test

to this:

test: export NODE_ENV = test

(assuming you have a sufficiently modern version of GNU make >= 3.77 ).

Solution 2 - Shell

As MadScientist pointed out, you can export individual variables with:

export MY_VAR = foo  # Available for all targets

Or export variables for a specific target (target-specific 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

You can also specify the .EXPORT_ALL_VARIABLES target to—you guessed it!—EXPORT ALL THE THINGS!!!:

.EXPORT_ALL_VARIABLES:

MY_VAR_1 = foo
MY_VAR_2 = bar
MY_VAR_3 = baz

test:
  @echo $$MY_VAR_1 $$MY_VAR_2 $$MY_VAR_3

see .EXPORT_ALL_VARIABLES

Solution 3 - Shell

I only needed the environment variables locally to invoke my test command, here's an example setting multiple environment vars in a bash shell, and escaping the dollar sign in make.

SHELL := /bin/bash

.PHONY: test tests
test tests:
    PATH=./node_modules/.bin/:$$PATH \
    JSCOVERAGE=1 \
    nodeunit tests/

Solution 4 - Shell

I would re-write the original target test, taking care the needed variable is defined IN THE SAME SUB-PROCESS as the application to launch:

test:
    ( NODE_ENV=test mocha --harmony --reporter spec test )

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbodokaiserView Question on Stackoverflow
Solution 1 - ShellMadScientistView Answer on Stackoverflow
Solution 2 - ShellShammel LeeView Answer on Stackoverflow
Solution 3 - ShellThorSummonerView Answer on Stackoverflow
Solution 4 - ShellGuiyo MView Answer on Stackoverflow