December 04, 2020
自動変数
自動変数(Automatic Variable)は実行するルールが定まると make が自動的に設定する変数です。
タスクランナー的な用途で主に使うのは以下の5個です。
$@
ターゲットのファイル名を表します$^
必要条件(Prerequisite)を表します$<
必要条件の最初の1つを表します$(@F)
ターゲットのファイル名を表します$(@D)
ターゲットのディレクトリ名を表します
$@ $% $<
以前出てきたC言語のプログラムをビルドする Makefile はこうでした。
main.o: main.c
gcc -o main.o main.c
これが自動変数を使うとこう書けます。重複した記述が減らせていい感じです。
main.o: main.c
gcc -o $@ $^
$ make main.o
gcc -o main.o main.c
$ ./main.o
religion
$^
はターゲットに与えられたすべての必要条件を取るため、必要条件を加えると困ってしまうことがあります。
.PHONY: hoge
main.2.o: main.c hoge
gcc -o $@ $^
hoge:
echo "do nothing"
$ make main.2.o
echo "do nothing"
do nothing
gcc -o main.2.o main.c hoge
clang: error: no such file or directory: 'hoge'
make: *** [Makefile:5: main.2.o] Error 1
そういったときは最初の必要条件だけを表す $<
が使えます。
main.3.o: main.c hoge
gcc -o $@ $<
$ make main.3.o
echo "do nothing"
do nothing
gcc -o main.3.o main.c
$(@F) $(@D)
$(@F)
$(@D)
はターゲットのファイル名とディレクトリ名です。
例えばディレクトリの下に生成物を作りたい場合、こんな風に書けます。
bin/main.1.o: main.c
mkdir -p $(@D)
gcc -o $(@D)/$(@F) $<
$ make bin/main.1.o
mkdir -p bin
gcc -o binmain.1.o main.c
ですが、依存関係は必要条件に書くとルールが簡素にできるので、個人的に最近はあまり使わずこのように書くことが多いです。
bin を必要条件に書き、main.c を最初に配置して $<
で gcc の infile に与えています。
bin/main.2.o: main.c bin
gcc -o $@ $<
bin:
mkdir $@
$ make bin/main.2.o
mkdir bin
gcc -o bin/main.2.o main.c