Makefileで子プロセスの環境変数を設定する方法


135

この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

に:

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

残念ながら、2つ目は機能しません(ノードプロセスはデフォルトで実行されますNODE_ENV

私は何を取りこぼしたか?

回答:


153

make変数は、デフォルトではプロセス環境の呼び出しにエクスポートされません。ただし、make's exportを使用して強制的に強制できます。変化する:

test: NODE_ENV = test

これに:

test: export NODE_ENV = test

(GNU make> = 3.77の十分に新しいバージョンを持っていると仮定します)。


3
私はGNU make 3.81を使用しておりall: <\n\t>export PROJ_ROOT=$(CURDIR)<\n\t>echo $(PROJ_ROOT)<\n>、最初の行に対しては正しい展開を出力しますがecho、2番目の行に対してのみです。PROJ_ROOTmakeの実行後は設定されません。周りのスペースは=、エクスポートに「不正な変数名」を与えます。例のように最初の行を前提条件にすると、「最初のターゲットの前にコマンドが開始されます」
Gauthier 2014年

8
@Gauthierはいはい。それは私が書いたものではありません。の後に<\ n \ t>を追加しましたがall:、これは私の例にはありません。私の例は、記述どおりに使用することを目的としています。これは、ターゲット固有の変数を定義するものであり、コマンドをレシピに追加するものではありません。また、レシピとターゲット固有の変数をターゲットで同時に使用することはできません。ターゲットを2回記述する必要があります。質問の2番目の例を参照し、これが説明に役立たない場合は、新しい質問をしてください。コメントに十分なスペースまたはフォーマットがないためです。
MadScientist 2014年

1
複数の変数はどうですか?
ホルム

1
それは結構ですが、あなたはそれをターゲットの頭に追加しました。ターゲットのコンテキストでそれらをリストするだけでは機能しませんか?それは私には効かないので
holms

2
ターゲット固有の変数は、GNU make 3.77で追加されました。GNU make 3.81からエクスポート可能です。git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

79

以下のようマッドサイエンティストが指摘し、あなたが個々の変数をエクスポートすることができます。

export MY_VAR = foo  # Available for all targets

または、特定のターゲットの変数をエクスポートします(ターゲット固有の変数):

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

.EXPORT_ALL_VARIABLESターゲットを指定することもできます—推測したとおりです!—すべてのものをエクスポート!!!:

.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

.EXPORT_ALL_VARIABLESを参照してください


2
奇妙なことに私は(今ではないことを確認、なぜ...)それは以前にそれが働いていた示したテストを行った。..私は戻って、私は推測するコメントを削除することができます。..
AnthonyC

3
@AnthonyC 2があるので、それが動作するMY_VARのは:1は、メイクファイルの変数のようにアクセスされ${MY_VAR}、別の1のようにアクセスし、bashのエクスポート変数である$$MY_VAR
セルゲイ

有用。ただし、変数のセットのみをエクスポートする方法が見つかりません。
Eric Chen

15

テストコマンドを呼び出すためにローカルで環境変数のみが必要でした。bashシェルで複数の環境変数を設定し、ドル記号をエスケープする例を次に示しますmake

SHELL := /bin/bash

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

6
回答を編集して、説明を含めてください。コードのみの回答は、将来のSOリーダーを教育するためにはほとんど機能しません。あなたの答えは低品質であるため、モデレーションキューに入れられています。
mickmackusa 2017

ThorSummoner、このソリューションは上記のアプローチほど柔軟ではありません。たとえば、コマンドを呼び出すための単一のルールと、環境変数を設定してその動作を変更する他のいくつかのルールが必要になる場合があります。考えてみてください:test:cmd perf:export PERF = "yes" perf:test「cmd」が複雑な場合(通常は複雑です)、このアプローチは保守がはるかに簡単です。cmdルールで環境変数を設定するアプローチでは、これがさらに難しくなります。
キース・ハンラン2017

1

必要な変数が起動するアプリケーションとして同じサブプロセスで定義されていることに注意して、元のターゲットテストを書き直します。

test:
    ( NODE_ENV=test mocha --harmony --reporter spec test )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.