1. ホーム
  2. メイクファイル

[解決済み】ルール実行時にmake変数を定義する。

2022-04-06 16:54:30

質問

GNUmakefileに、一時ディレクトリを使用するルールを設けたいと思います。 たとえば、以下のようなものです。

out.tar: TMP := $(shell mktemp -d)
        echo hi $(TMP)/hi.txt
        tar -C $(TMP) cf $@ .
        rm -rf $(TMP)

書かれているように、上記のルールは、一時ディレクトリを作成した時点で、そのルールが パースされる . これでは、いつもout.tarを作っているわけでもないのに、たくさんの一時ディレクトリが作られてしまいます。 tmpに未使用の一時ディレクトリが散乱するのは避けたいところです。

変数が定義されたときだけでなく、ルールが実行されたときにも定義されるようにする方法はありますか?

主に考えているのは、mktempとtarをシェルスクリプトにダンプすることですが、それはやや見苦しいような気がします。

解決方法は?

あなたの例では TMP 変数が設定されるたびに(そして一時ディレクトリが作成される)。 ルール に対して out.tar が評価されます。のときだけディレクトリを作成するために out.tar が実際に発生した場合、ディレクトリの作成をステップに移す必要があります。

out.tar : 
    $(eval TMP := $(shell mktemp -d))
    @echo hi $(TMP)/hi.txt
    tar -C $(TMP) cf $@ .
    rm -rf $(TMP)

評価 は、あたかも makefile に手書きで入力されたかのように文字列を評価します。この場合 TMP の結果を shell 関数を呼び出す。

編集 (コメントを受けて)。

ユニークな変数を作るには、次のようにすればよいでしょう。

out.tar : 
    $(eval $@_TMP := $(shell mktemp -d))
    @echo hi $($@_TMP)/hi.txt
    tar -C $($@_TMP) cf $@ .
    rm -rf $($@_TMP)

この場合、変数の先頭にターゲットの名前(この場合はout.tar)が追加され、以下のような名前の変数が生成されます。 out.tar_TMP . うまくいけば、これでコンフリクトを防ぐことができます。