🙆

Makefile#1: Simple Makefile

2020/09/22に公開

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>って形式) 下記の順でライブラリを探すらしい
    1. lib NAME .so
    2. 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