web-dev-qa-db-ja.com

GNUの変数はレシピを作成します、それは可能ですか?

GNUレシピに変数を含めることは可能ですか?

このようなものは動作しません:

%_t.mkd : %.mkd
    REV=$$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ )
    echo $${REV}

それをまったく機能させる方法はありますか?

ご覧のとおり、ファイルが変更されたリビジョンを抽出し、後でそれを完全なレシピで使用します。残念ながら、私はsvn:keywords問題の文書の外にあるリビジョン番号が必要なので。

16
Magnus

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にはコマンドラインフラグしかないため、問題ありません。 )

10
user1686

おかげで https://stackoverflow.com/questions/6519234/cant-assign-variable-inside-recipe

これは、レシピの変数を変更するためのソリューションです。

recipe: 
        $(eval variablename=whatever)
11
user3645902

Gnu Make 6.5設定変数 によると:

シェル割り当て演算子!=を使用して、プログラムを実行し、変数をその出力に設定できます。この演算子は最初に右側を評価し、次にその結果をシェルに渡して実行します。実行の結果が改行で終わる場合、その1つの改行は削除されます。他のすべての改行はスペースに置き換えられます。結果の文字列は、名前付きの再帰的に展開された変数に配置されます。

したがって、以下を試すことができます(テストされていません)。

REV != $$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ ) \
echo $${REV}
1
DavidPostill

@ user3645902が言​​及したことを踏まえて、主な質問に対する解決策を次に示します。

recipe:
    @$(eval REV=`svn info $<|grep 'Last Changed Rev'|cut -f4 -d`)
    @echo $(REV)
1
vimdude