make 改訂版(5章) 続き
シンボルの定義/未定義で実行ファイルの動作を切り替えられるのはとても便利。
でも、コンパイル時の指定を忘れていたり、記憶違いをしていたりすると、
思いもよらない動きをする実行ファイルが作成されてしまう。
(ファイルの編集でなくシンボル定義で切り替えているから、前回のオブジェクトファイルがそのまま使われてしまう)
コンパイル時のシンボル有無が不明なのを回避する方法
また、include命令を使うと、Makefileの情報を別ファイルから読み込むことが出来る。
これにより、マクロ定義だけ別ファイルに定義する、なんてことが可能になる。
強制的にリコンパイル
ダミーターゲットを使用する。
makeにとってダミーターゲットは実在のどんなファイルよりも新しいもの。
なので、コンポーネントにダミーターゲット(force_rebuild)を指定すると、必ずコンパイルが実行されるという仕組み
リコンパイル実行時のみ、内部マクロFRCにforce_rebuildを定義することでオブジェクトファイルの強制リコンパイルを実現
(Makefile)
OBJS = main.o hoge.o piyo.o main : ${MAKE} ${OBJS} "CFLAGS=${CFLAGS}" ${CC} -o $@ ${OBJS} rebuild : ${MAKE} ${OBJS} "CFLAGS=${CFLAGS}" FRC=force_rebuild ${CC} -o main ${OBJS} main.o hoge.o piyo.o : ${FRC} force_rebuild : clean : rm -f main *.o *~
(実行結果)
[kobakoba0723@fedora13-intel64 symbol]$ make make main.o hoge.o piyo.o "CFLAGS=" make[1]: ディレクトリ `symbol' に入ります cc -c -o main.o main.c cc -c -o hoge.o hoge.c cc -c -o piyo.o piyo.c make[1]: ディレクトリ `symbol' から出ます cc -o main main.o hoge.o piyo.o [kobakoba0723@fedora13-intel64 symbol]$ make CFLAGS=-DDEBUG make: `main' は更新済みです [kobakoba0723@fedora13-intel64 symbol]$ make rebuild CFLAGS=-DDEBUG make main.o hoge.o piyo.o "CFLAGS=-DDEBUG" FRC=force_rebuild make[1]: ディレクトリ `symbol' に入ります cc -DDEBUG -c -o main.o main.c cc -DDEBUG -c -o hoge.o hoge.c cc -DDEBUG -c -o piyo.o piyo.c make[1]: ディレクトリ `symbol' から出ます cc -o main main.o hoge.o piyo.o [kobakoba0723@fedora13-intel64 symbol]$ make rebuild make main.o hoge.o piyo.o "CFLAGS=" FRC=force_rebuild make[1]: ディレクトリ `symbol' に入ります cc -c -o main.o main.c cc -c -o hoge.o hoge.c cc -c -o piyo.o piyo.c make[1]: ディレクトリ `symbol' から出ます cc -o main main.o hoge.o piyo.o
ファイル名で切り分け(自分で名前を変更する)
コンパイル時のオプションに応じてオブジェクトファイル、実行ファイルの名前を変える。
こうすることで、どのファイルが何のオプションでコンパイルされたかが明確に判る
(Makefile)
_debug.o のコマンド行で main.o をコピーしているのは、
シンボル無しでコンパイルしたオブジェクトファイルが上書きされるのを防ぐため
OBJS = main.o hoge.o piyo.o OBJS_DEBUG = main_debug.o hoge_debug.o piyo_debug.o main : ${OBJS} ${CC} -o $@ ${OBJS} main_debug : ${OBJS_DEBUG} ${CC} -o $@ ${OBJS_DEBUG} main_debug.o : main.c - cp main.o main.save ${CC} ${CFLAGS} -DDEBUG -c $? mv main.o $@ - mv main.save main.o hoge_debug.o : hoge.c - cp hoge.o hoge.save ${CC} ${CFLAGS} -DDEBUG -c $? mv hoge.o $@ - mv hoge.save hoge piyo_debug.o : piyo.c - cp piyo.o piyo.save ${CC} ${CFLAGS} -DDEBUG -c $? mv piyo.o $@ - mv piyo.save piyo clean : rm -f main main_debug *.o *~
(実行結果)
[kobakoba0723@fedora13-intel64 symbol]$ make main cc -c -o main.o main.c cc -c -o hoge.o hoge.c cc -c -o piyo.o piyo.c cc -o main main.o hoge.o piyo.o [kobakoba0723@fedora13-intel64 symbol]$ make main_debug cp main.o main.save cc -DDEBUG -c main.c mv main.o main_debug.o mv main.save main.o cp hoge.o hoge.save cc -DDEBUG -c hoge.c mv hoge.o hoge_debug.o mv hoge.save hoge cp piyo.o piyo.save cc -DDEBUG -c piyo.c mv piyo.o piyo_debug.o mv piyo.save piyo cc -o main_debug main_debug.o hoge_debug.o piyo_debug.o
ファイル名で切り分け(サフィックスルールを使う)
自分で名前を変えるやり方は、対象ファイルが増えるたびにMakefileの修正が必要となり煩雑。
独自のサフィックスを使用して、シンボル定義/未定義でオブジェクトファイル名、実行ファイル名を変える
サフィックスの名前は、make -p -f/dev/null などで、定義済みでないものを選ぶ。
今回は、DEBUGシンボルなので.dサフィックスを使い、オブジェクトファイルのサフィックスも.d。
シンボルを定義しない方は通常の名前(.o)でオブジェクトファイルを作成するのでデフォルトのサフィックスルールでコンパイル
(Makefile)
OBJS = main.o hoge.o piyo.o OBJS_DEBUG = main.d hoge.d piyo.d .SUFFIXES : .d main : ${OBJS} ${CC} -o $@ ${OBJS} main_debug : ${OBJS_DEBUG} ${CC} -o $@ ${OBJS_DEBUG} .c.d : - cp $*.o $*.save ${CC} ${CFLAGS} -DDEBUG -c $< mv $*.o $@ - mv $*.save $*.o clean : rm -f main main_debug *.o *.d *~
(実行結果)
[kobakoba0723@fedora13-intel64 symbol]$ make main cc -c -o main.o main.c cc -c -o hoge.o hoge.c cc -c -o piyo.o piyo.c cc -o main main.o hoge.o piyo.o [kobakoba0723@fedora13-intel64 symbol]$ main main_debug cp main.o main.save cc -DDEBUG -c main.c mv main.o main.d mv main.save main.o cp hoge.o hoge.save cc -DDEBUG -c hoge.c mv hoge.o hoge.d mv hoge.save hoge.o cp piyo.o piyo.save cc -DDEBUG -c piyo.c mv piyo.o piyo.d mv piyo.save piyo.o cc -o main_debug main.d hoge.d piyo.d
ディレクトリで切り分け
シンボル毎にディレクトリ・Makefileを用意し、その中にオブジェクトファイル、実行ファイルを作成する
(ディレクトリ構成)
トップディレクトリ
- main(DEBUGシンボル未定義) | |
- Makefile2 | |
- main_debug(DEBUGシンボル定義) | |
- Makefile3 | |
- src |
- Makefile1 |
release_build : cd main; ${MAKE} test_build : cd main_debug; ${MAKE} clean : rm -f *~ cd main; make clean cd main_debug; make clean(Makefile2)
OBJS = main.o hoge.o piyo.o main : ${OBJS} ${CC} -o $@ ${OBJS} main.o : ../src/main.c ${CC} ${CFLAGS} -c $< hoge.o : ../src/hoge.c ${CC} ${CFLAGS} -c $< piyo.o : ../src/piyo.c ${CC} ${CFLAGS} -c $< clean : rm -f main *.o *~(Makefile3)
OBJS = main.o hoge.o piyo.o CFLAGS = -DDEBUG main : ${OBJS} ${CC} -o $@ ${OBJS} main.o : ../src/main.c ${CC} ${CFLAGS} -c $< hoge.o : ../src/hoge.c ${CC} ${CFLAGS} -c $< piyo.o : ../src/piyo.c ${CC} ${CFLAGS} -c $< clean : rm -f main *.o *~(実行結果) (DEBUGシンボルを定義しない時)
[kobakoba0723@fedora13-intel64 symbol]$ make release_build cd main; make make[1]: ディレクトリ `main' に入ります cc -c ../src/main.c cc -c ../src/hoge.c cc -c ../src/piyo.c cc -o main main.o hoge.o piyo.o make[1]: ディレクトリ `main' から出ます(DEBUGシンボルを定義した時)
[kobakoba0723@fedora13-intel64 symbol]$ make test_build cd main_debug; make make[1]: ディレクトリ `main_debug' に入ります cc -DDEBUG -c ../src/main.c cc -DDEBUG -c ../src/hoge.c cc -DDEBUG -c ../src/piyo.c cc -o main main.o hoge.o piyo.o make[1]: ディレクトリ `main_debug' から出ます