GNUレシピに変数を含めることは可能ですか?
このようなものは動作しません:
%_t.mkd : %.mkd
REV=$$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ )
echo $${REV}
それをまったく機能させる方法はありますか?
ご覧のとおり、ファイルが変更されたリビジョンを抽出し、後でそれを完全なレシピで使用します。残念ながら、私はsvn:keywords
問題の文書の外にあるリビジョン番号が必要なので。
make
ツールは、各レシピ行に対して新しいシェルプロセスを開始するため、これは機能しません。また、シェル変数(「エクスポートされた」環境変数でさえ)は、「上方」に伝播することはできません。シェルプロセスが終了するとすぐになくなります。
従来の方法は、Makefileで\
を使用してレシピ行を結合することです。
foo: bar baz
line1; \
line2; \
line3
(バックスラッシュは同じ行結合を行うシェルにも渡されるため、;
または&&
を使用してコマンドを区切る必要があることに注意してください。)
GNU Make manualの info make "Splitting Lines"
と info make "Splitting Recipe Lines"
も参照してください。
もう1つの方法は、make
に.ONESHELL
ディレクティブを使用して、レシピ全体に対して常に1つのシェルプロセスを使用するように指示することです。
.ONESHELL:
foo: bar baz
line1
line2
line3
info make "One Shell"
を参照してください。
(.ONESHELL
はPOSIXで推奨されていますが、 すべてのmakeバージョンでサポートされているわけではありません ;たとえば、BSD makeにはコマンドラインフラグしかないため、問題ありません。 )
おかげで https://stackoverflow.com/questions/6519234/cant-assign-variable-inside-recipe
これは、レシピの変数を変更するためのソリューションです。
recipe: $(eval variablename=whatever)
Gnu Make 6.5設定変数 によると:
シェル割り当て演算子
!=
を使用して、プログラムを実行し、変数をその出力に設定できます。この演算子は最初に右側を評価し、次にその結果をシェルに渡して実行します。実行の結果が改行で終わる場合、その1つの改行は削除されます。他のすべての改行はスペースに置き換えられます。結果の文字列は、名前付きの再帰的に展開された変数に配置されます。
したがって、以下を試すことができます(テストされていません)。
REV != $$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ ) \
echo $${REV}
@ user3645902が言及したことを踏まえて、主な質問に対する解決策を次に示します。
recipe:
@$(eval REV=`svn info $<|grep 'Last Changed Rev'|cut -f4 -d`)
@echo $(REV)