makefileで、if文 / for文を使う、あるいは複数行のコマンドを書く方法

makefileで、for文を使うなど、コマンドを複数行に分けて記述したいときがあります。その方法と注意点を紹介します。

makefile中で、そのまま複数行のコマンドを書くと、コマンドは行ごとにシェルに渡されてしまうので、エラーとなります。

if文

そのため、次のように\を使って、改行を明示します。

if [ -d tmp ]; then\
  echo "tmp is a directory";\
fi

for文

for文を書く場合は同様に\を使い、次のようにします。

for i in 1 2 3; do\
  echo $$i;\
done

ここでの注意点は、変数を参照する場合には、$を2つ重ねるということです。$のままだと、makeに解釈されてしまいますので、それを防ぎます。

本当にfor文を使ったほうがよいか?

for文で複数ファイルを処理するmakefileを作成する前に考えたいのは、それは本当にmakefileを使用して行うべき処理かということです。

コンパイルにmakeを使う利点の一つは、以前のコンパイル以降に更新されていない依存ファイルは、コンパイルしなおさない、という点です。

for文で複数ファイルを処理する場合は、更新されているかどうかを気にせず処理してしまうことになり、この利点が失われてしまいます。

 

makefileではなく、ただのシェルファイルを書いた方がよい場合ではないか考えてみましょう。

 

makeのターゲットには、ワイルドカード*を使うことができます。

ワイルドカードを使用して実現できる処理の場合は、その方がよいでしょう。

 

ただ、ワイルドカードを使用しても、ディレクトリを再帰的に下っていくことはできませんので気をつけましょう。

依存関係が不特定という場合は少ないでしょうから、ディレクトリを列挙するという方法で対処できると思います。

 

stackoverflow の how to write loop in a makefileのページも参考になります。

 

以上、makefileでfor文を使う、あるいは複数行のコマンドを書く方法でした。