Makefile 動的な変数の使い分け

課題

Makefileのターゲット内で動的に変数を設定したい。

解決方法

変数がターゲット実行時に確定する場合

  • 環境変数を利用する
  • シェルのコマンド置換$(...)を利用する
    • Makeのshell関数$(...)だと、ターゲット実行前に実行されるから
  • 各行を;でつなげて、変数定義と変数利用する箇所をひとつのシェル内で実行する
    • Makefileの各行は異なるシェルで実行され、行をまたぐと環境変数が引き継がれないから
task:
        touch sample.txt
        DIR="$$(ls)"; echo "$$DIR"
$ ls
Makefile
$ make task
touch sample.txt
DIR="$(ls)"; echo "$DIR"
Makefile
sample.txt

変数がターゲット実行前に確定する場合

  • Makefileの変数を利用する
  • $(eval ...)を利用する
task:
        $(eval TIMESTAMP=$(shell date))
        sleep 1
        echo $(TIMESTAMP)
        sleep 1
        echo $(TIMESTAMP)
$ make task
sleep 1
echo 2018年  6月  9日 土曜日 11:00:49 JST
2018年 6月 9日 土曜日 11:00:49 JST
sleep 1
echo 2018年  6月  9日 土曜日 11:00:49 JST
2018年 6月 9日 土曜日 11:00:49 JST

参考 Makefileの関数#eval

検証環境

$ make -version
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
Copyright (C) 2010  Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.