🙆
Makefile#1: Simple Makefile
1.1 基本
ファイル内トップダウン構造。ふつーは
- 先頭に all ターゲット
- 最後に clean ターゲット
- コメントは
#
だが、コマンド無いの#
は認識されない - 先頭タブの後ろは、何でもコマンド行とみなされる
-
\
が行跨ぎ
target_1 target_2 : prereq_1 prereq_2
command_1
command_2
- target_n: 作り出される一つ以上のターゲット
- prereq_n: 0個以上の必須項目。ターゲット生成される前には存在してないとダメなものです。必須項目が無いターゲットは、ターゲットで存在しないものがある場合に処理される。
- command_n: コマンド行。ターゲットの作るためのコマンド。ちなみにシェル(サブシェル)として実行される。
単純例
foo.o: foo.c foo.h
gcc -c foo.c
1.2 依存関係の解決とか -l 必須項目とか
こんなmain.c
- main.c
#include <stdio.h>
extern int count_fee, ...; // カウンタの変数
extern void yyax(void); // なんかスキャナの実態
void main(void)
{
yyax();
printf(" count_fee:%d, ...." count_fee);
exit(0);
}
yyax()は別ソースコードでなんか外部ライブラリ(-l オプションでしていするやつ)でどうさするものとする。
んでそのMakefile
count_words: main.o lexer.o -lfl
gcc main.o lexer.o -lfl -o count_words
main.o: main.c
gcc -c main.c
lexer.o: lexer.c
gcc -c lexer.c
lexer.c: lexer.l
flex -t lexer.l > lexer.c
特筆すべきは
- main.c というターゲットはないので main.c のファイルの存在が必須項目になる
-
prereq に -l オプションを入れると(-l<NAME>って形式) 下記の順でライブラリを探すらしい
- lib NAME .so
- lib NAME .a
たとえば、 lexer.l だけを更新した場合、makeはタイムスタンプをターゲットと比較して lexer.l は更新されていると認識し処理の対象に、 main.c 更新されてないと認識し処理の対象にしない。
1.3 Makeの実行出力
-
Mkaefile内に列挙したターゲットは何れも指定できる
$ make lexer.c
makeは実行結果を以下のような感じで出力
-
最新だよー
$ make lexer.c make: `lexer.c` is up to date.
-
なんもターゲットがないです
$ make lexer.c make: *** No rule to make target `non-existent-target`. Stop.
コマンドラインオプション
各種変数
上書きになるらしい
--just-print (-n)
各コマンド行は実行せず表示だけ行う
--print-data-base (-p)
組み込みルールとか自動変数の設定内容とかを出力する。
Discussion