makefileで変数を出力する方法


246

私のメイクファイルには、変数「NDK_PROJECT_PATH」があります。私の質問は、コンパイル時にそれを出力するにはどうすればよいですか?

"$ PATH"文字列表示するMake file echoを読んでみました:

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)

どちらも私に与える

"build-local.mk:102: *** missing separator.  Stop."

なぜそれが私にとってうまくいかないのか誰か知っていますか?

回答:


222

makefileが読み取られたときに変数を出力できます(この質問に適切にタグを付けたので、GNU makeが想定されます)。

$(info $$var is [${var}])

このコンストラクトをレシピに追加して、makeがシェルに渡す内容を確認できます。

.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world

ここで、makeはレシピ全体を$(info $$var is [${var}])echo Hello world単一の再帰的に展開された変数として格納します()。makeがレシピを実行することを決定したとき(たとえば、ビルドするように指示したときall)、変数を展開し、結果の各行を個別にシェルに渡します。

だから、痛みを伴う詳細:

  • 拡大する $(info $$var is [${var}])echo Hello world
  • これを行うには、まず拡張します $(info $$var is [${var}])
    • $$ 文字通りになる $
    • ${var}になる:-)(言う)
    • 副作用は、$var is [:-)]標準出力に表示されることです
    • でも拡張$(info...)は空です
  • メイクは残っています echo Hello world
    • echo Hello worldまずstdoutに印刷して、シェルに何を要求するかを知らせます
  • シェルHello worldはstdoutに出力します。

2
PHONYの代わりに(ドット).PHONYにする必要がありますか?
2018年

172

あたりとしてGNUマニュアル作りとも答えの下に、あなたが使用できるの「bobbogo」で指さ情報 / 警告 / エラーを表示テキストに。

$(error   text…)
$(warning text…)
$(info    text…)

変数を出力するには、

$(error   VAR is $(VAR))
$(warning VAR is $(VAR))
$(info    VAR is $(VAR))

「エラー」は、エラー文字列を表示した後、メイクの実行を停止します


うわー、これは知りませんでした。ログにコマンドを複製するエコーよりもはるかに優れています。
deepelement 2017年


44

単に出力が必要な場合は$(info)、それ自体を使用します。これはMakefileのどこでも行うことができ、その行が評価されると表示されます。

$(info VAR="$(VAR)")

VAR="<value of VAR>"その行を処理するたびに出力されます。この動作は非常に位置に依存するため、$(info)変更できるすべてのもの$(VAR)がすでに発生した後で、展開が発生することを確認する必要があります。

より一般的なオプションは、変数の値を出力するための特別なルールを作成することです。一般的に、ルールは変数が割り当てられた後に実行されるため、実際に使用されている値が表示されます。(ただし、ルールで変数を変更することは可能です。)適切なフォーマットは、変数が何に設定されているかを明確にするのに役立ち、$(flavor)関数は何かの変数の種類を教えてくれます。したがって、このルールでは:

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $*ルールで% パターンが一致した語幹に展開されます。
  • $($*)によって名前が指定される変数の値に展開され$*ます。
  • 明確に変数の展開を描きます。また、使用することができますし、または類似しました。[]""
  • $(flavor $*)それがどんな種類の変数かを教えてくれます。注:$(flavor) 変数名を受け取りますが、その展開は受け取りません。したがって、と言うとmake print-LDFLAGS、が得られ$(flavor LDFLAGS)ます。
  • $(info text)出力を提供します。 作るプリントをtext拡大副作用としてそのSTDOUTに。$(info)ただしの展開は空です。あなたはそれをのよう@echoに考えることができますが、重要なことに、シェルを使用しないので、シェルのクォート規則について心配する必要はありません。
  • @trueルールのコマンドを提供するためだけにあります。それがなければ、 makeも出力しますprint-blah is up to date。何@trueもしないことを意図していることをより明確に感じます。

実行すると、

$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]

これは質問に対する答えを提供しません。批評したり、作者に説明を求めたりするには、投稿の下にコメントを残します。自分の投稿にはいつでもコメントできます。十分な評判得られれ、どの投稿にもコメントできます。- 口コミより
ドラゴンエナジー

レビューありがとうございます。評判が良ければコメントできるとのことですが、それではどうすればいいですか?私の答えは付加価値を提供すると信じていますので、それを追加してはいけませんか?
ジムナスビー

1
これを、その回答に対する場違いなコメントとして表現するのではなく、コメントしているものと競合するスタンドアロンの回答になるように書き直すことをお勧めします。
Charles Duffy

@JimNasbyはい、チャールズが提案したもの。実際のところ、「申し訳ありませんが、コメントするには不十分です」という種類の部分を削除することは、赤旗のようなものなので、最初は役立つかもしれません。あなたがそれを完全な答えに変える(あなたが好きなようにそれを編集することができる)ならば、それはかなりうまくいくはずです。乾杯。
Dragon Energy、

すばらしい-これは今のところずっと良い答えです。:)
Charles Duffy、

6

@echo $(NDK_PROJECT_PATH)はそれを行う良い方法です。エラーはそこから来るとは思わない。通常、このエラーは、意図を誤って入力したときに表示されます。タブを配置する必要がある場所にスペースがあると思います。


2
「@echo $(NDK_PROJECT_PATH)」を試しましたが、「build-local.mk:102:***行方不明のセパレータです。停止」というエラーが表示されます。「echo」の後にスペースが1つあるだけですが、「@ echo」の前にスペースもタブもありません。
マイケル2013年

エラーはこの行からのものですか?この行はルールにありますか?彼女はおそらく...インデントされなければならない

6

のすべてのバージョンでmakeは、コマンド行を行の最初の文字として(スペースではなく)タブでインデントする必要があります。問題の2行だけでなく、ルール全体を示した場合、より明確な答えを出すことができますが、次のようになります。

myTarget: myDependencies
        @echo hi

2行目の最初の文字はTABでなければなりません。


4

走る make -n ; 変数の値が表示されます。

Makefile ...

all:
        @echo $(NDK_PROJECT_PATH)

コマンド:

export NDK_PROJECT_PATH=/opt/ndk/project
make -n 

出力:

echo /opt/ndk/project

これはかなり便利ですが、私--just-print代わりにExecution
Fredrick Gauss

3

これによりmakefile、「セパレーターがありません」というエラーメッセージが生成されます。

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

の前にはタブがあります@echo "All done"(ただし、done:ルールとアクションはほとんど不要ですが)。@echo PATH=$(PATH)

問題は、行の先頭にallコロン:または等号が必要であることです=があり、それがターゲット行またはマクロ行であることを示す必要があり、どちらもないため、セパレーターが欠落していることです。

変数の値をエコーするアクションは、ターゲット、おそらくダミーまたはPHONEYターゲットに関連付ける必要があります。そして、そのターゲット行にはコロンが必要です。例で:後を追加allした場合makefileし、次の行の先頭の空白をタブで置き換えると、正常に機能します。

おそらく、オリジナルの102行目付近に同様の問題がありmakefileます。失敗しているエコー操作の前に非ブランク、非コメントの5行を表示した場合、おそらく診断を終了することができます。ただし、質問は2013年5月に行われたため、makefile現在(2014年8月)に故障がまだ利用可能である可能性は低いため、この回答を正式に検証することはできません。問題が発生したもっともらしい方法を説明するためにのみ使用できます。


3

Makefileを変更する必要はありません。

$ cat printvars.mak
print-%:
        @echo '$*=$($*)'

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE

2

問題は、エコーが実行ブロックでのみ機能することです。つまり、「xx:」の後のすべて

したがって、最初の実行ブロックより上のものはすべて初期化であり、実行コマンドは使用できません。

実行ブロックを作成します


1

これは一般的な方法で行うことができ、複雑なメイクファイルをデバッグするときに非常に役立ちます。別の回答で説明されているのと同じ手法に従って、以下を任意のメイクファイルに挿入できます。

# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)

  # take the rest of the arguments as variable names
  VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

  # turn them into do-nothing targets
  $(eval $(VAR_NAMES):;@:))

  # then print them
  .PHONY: print
  print:
          @$(foreach var,$(VAR_NAMES),\
            echo '$(var) = $($(var))';)
endif

その後、「make print」を実行して、任意の変数の値をダンプできます。

$ make print CXXFLAGS
CXXFLAGS = -g -Wall


0

Makefile自体を変更したくない場合は、を使用--evalして新しいターゲットを追加し、新しいターゲットを実行できます。たとえば、

make --eval='print-tests: @echo TESTS $(TESTS) ' print-tests

次のコマンドを使用して、必要なタブ文字をコマンドラインに挿入できます。 CTRL-V, TAB

上記のMakefileの例:

all: do-something

TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'

do-something:
        @echo "doing something"
        @echo "running tests $(TESTS)"
        @exit 1

スクリプトを実行しようとしていますが、エラーが発生しますmake: *** missing separator. Stop.
リナルディセゲシン

ああ、すみません、修正しました。「print-tests」ターゲットの最後にコロンがない。
ウェイド

実際には必要のない改行やタブは、セミコロンで十分です:make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
bobbogo

0

android make(mka)を使用する@echo $(NDK_PROJECT_PATH)と機能せず、エラーが表示され*** missing separator. Stop." ますandroid makeで変数を印刷しようとすると、この回答を使用します

NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))

それは私のために働いた


0

変数の値を確認したい場合は、通常、エラーを表示してエコーします(値を確認したい場合のみ。実行が停止します)。

@echo $(error NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))

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