コマンドラインからmakeに追加の変数を渡す


614

変数をコマンドライン引数としてGNU Makefileに渡すことはできますか?つまり、Makefileで最終的に変数になる引数を渡したいのです。

回答:


754

makefileの外部から変数を設定するには、いくつかのオプションがあります。

  • 環境から -各環境変数は、同じ名前と値を持つmakefile変数に変換されます。

    -eオプション(別名--environments-override)をオンに設定することもできます。環境変数はmakefileへの割り当てをオーバーライドします(これらの割り当て自体がoverrideディレクティブを使用している場合を除く)。ただし、これはお勧めできません。?=割り当て(条件変数代入演算子。変数がまだ定義されていない場合にのみ効果があります):

    FOO?=default_value_if_not_set_in_environment
    

    特定の変数は環境から継承されないことに注意してください:

    • MAKE スクリプトの名前から取得されます
    • SHELLmakefile内で設定されるか、デフォルトに設定されます/bin/sh(根拠:コマンドはmakefile内で指定され、それらはシェル固有です)。
  • コマンドラインから - コマンドラインのmake一部として変数割り当てを受け取り、ターゲットと混在させることができます。

    make target FOO=bar
    

    ただし、ディレクティブを割り当てで使用ない限り、メイクファイル内の変数へのすべての割り当てFOOは無視されます。(効果は、環境変数のオプションの場合と同じです)。override-e

  • 親Makeからのエクスポート-MakefileからMakeを呼び出す場合は、通常、次のように明示的に変数の割り当てを記述しないでください。

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

    代わりに、これらの変数をエクスポートすることをお勧めします。変数をエクスポートすると、すべてのシェル呼び出しの環境になります。これらのコマンドからのMake呼び出しは、上記のようにこれらの環境変数を選択します。

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    引数なしで使用して、すべての変数をエクスポートすることもできexportます。


11
コマンドラインから渡すには、スペースが必要ですmake A='"as df"'
Ciro Santilli郝海东冠状病六四事件法轮功

4
環境変数を気にするなら、あなたはトラブルを求めているようです。1つには、環境が異なるという理由だけで、Bの場所ではなくAの場所で動作する場合、それはデバッグの悪夢です。
James Moore、

12
経験に基づくと、CFLAGSのようなものをエクスポートすることは、大規模プロジェクトの悪夢のレシピです。大規模なプロジェクトには、特定のフラグのセットでのみコンパイルできるサードパーティのライブラリが含まれていることがよくあります(誰も修正する必要はありません)。CFLAGSをエクスポートすると、プロジェクトのCFLAGSがサードパーティのライブラリを上書きしてしまい、コンパイルエラーが発生します。別の方法export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)として、それをとして定義して渡すこともできmake -C folder $(PROJECT_MAKE_FLAGS)ます。ライブラリのmakefileに環境を無視するように指示する方法がある場合、それは理想的です(-eの反対)。
RD

24
警告:上記の「親Makeからのエクスポート」のセクションでは、「これを行わないでください!」ある批判的に誤解を招きます。コマンドラインで変数を渡すと、サブメイクファイルの割り当てがオーバーライドされますが、エクスポートされた変数は、サブメイクファイルの割り当てをオーバーライドしません。変数をサブメイクファイルに渡すこれらの2つの方法同等ではなく、混同しないでください。
ジョナサンベンアブラハム、2015

4
何か違いは? make target FOO=bar make FOO=bar target
gfan 2018年

213

最も簡単な方法は次のとおりです。

make foo=bar target

その後、メイクファイルでを参照できます$(foo)。これはサブメイクに自動的に伝播しないことに注意してください。

サブメイクを使用している場合は、この記事を参照してください:サブメイクへの変数の通信


2
サブメイクとincludedは、メインのメイクファイルのメイクファイルを意味しますか?
パブロ

2
@Michael:これは、makefile内からmakeを再度呼び出すことを意味します。この詳細に興味をお持ちのようですので、回答を更新しました。
Mark Byers、

2
「これはサブメイクに自動的に伝播しないことに注意してください。」嘘だ!「デフォルトでは、環境またはコマンドラインからの変数のみが再帰呼び出しに渡されます。エクスポートディレクティブを使用して他の変数を渡すことができます。」gnu.org/software/make/manual/html_node/...
ThomasMcLeod

82

次のようなmakefileがあるとします。

action:
    echo argument is $(argument)

あなたはそれを呼び出すでしょう make action argument=something


5
したがって、ターゲットと引数は位置に関して交換できますか?
パブロ

4
@Michael:はい(Mark Byersの回答を参照)
nc3b 2010年

25

マニュアルから:

makeの変数は、makeが実行されている環境から取得できます。makeが起動時に参照するすべての環境変数は、同じ名前と値を持つmake変数に変換されます。ただし、makefileでの明示的な割り当て、またはコマンド引数による指定は、環境をオーバーライドします。

だからあなたは(bashから)することができます:

FOOBAR=1 make

FOOBARMakefileに変数が生成されます。


2
もう1つの方法は、ほぼすべてのケースで確かに優れています。完全を期すため、ここではここにしておきます。
トーマス

これは、同じ行のmakeコマンドのの変数の割り当てを示す唯一の回答です。これは構文エラーではないことを知っておく価値があります。
M_M

7

StallmanとMcGrathによるGNU Makeブックに含まれている、ここで引用されていない別のオプションがあります(http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.htmlを参照)。それは例を提供します:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

特定のパラメータがに表示されるかどうかを確認する必要がありますMAKEFLAGS。たとえば、c ++ 11のスレッドについて研究していて、研究を複数のファイル(class01、...、classNM)に分割していて、次のことを実行したいとします。すべてをコンパイルして個別に実行するか、1つずつコンパイルする時間を設定し、フラグが指定されている場合は実行します(-rたとえば)。したがって、次のことを考え出すことができますMakefile

CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread

SOURCES = class01 class02 class03

%: %.cxx
    $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

それがあれば、あなたは:

  • wをmake -r class02含むファイルをビルドして実行します。
  • すべてをw / makeまたはmake all;
  • すべて構築して実行しますmake -r(それらのすべてに特定の種類のアサートスタッフが含まれていて、それらすべてをテストしたいとします)

6

そうみたいです

コマンド引数は環境変数を上書きします

Makefile

send:
    echo $(MESSAGE1) $(MESSAGE2)

実行例

$ MESSAGE1=YES MESSAGE2=NG  make send MESSAGE2=OK
echo YES OK
YES OK

5

Makefileというファイルを作成し、この$(unittest)のような変数を追加すると、ワイルドカードを使用しても、Makefile内でこの変数を使用できるようになります。

例:

make unittest=*

私はBOOST_TESTを使用し、パラメーター--run_test = $(unittest)にワイルドカードを指定することで、正規表現を使用して、Makefileで実行するテストをフィルターで除外できます。


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