読者です 読者をやめる 読者になる 読者になる

C用Makefileのテンプレートと覚書

サマリ

たまに使うときに毎回調べなくてもよいようにC用Makefileのテンプレートを作った。

はじめに

Cでプログラムを書くときに、Makefileを書こうとして毎回書き方を探し回っている間抜けの極みなんですが、 だいたい書く内容は変わらないので、テンプレを作って使いまわせるようにしておきたくなった。

このテンプレがカバーしない範囲

  • 複数のMakefileを連動させるケースはカバーしない
  • GNU Make以外はカバーしない

テンプレ

gist.github.com

覚書

GNU Makeにおける関数コール

$(<関数名> <引数>)みたいに書くと関数をコールできる。

使っているGNU Makeの関数

Makeにはいくつかビルトインの便利関数がある。カンマ前後はスペースを入れないように。

  • realpath:指定されたディレクトリの単一絶対パス(canonical absolute path)を取得する。 canonicalというのは、...、symlinkを含まないpathのこと。abspathと違ってsymlinkを解決するという違いがあるけども、 この違いがMakefileに及ぼす影響はよくわからない・・・
  • wildcard:wildcardで指定したパターンに該当するものをスペース区切りで出力してくれる関数。 ファイルパスを渡すと、指定したパターンに該当するファイルを出力してくれる。
  • subst$(subst <from>,<to>,<置き換え対象文字列(空白区切り)>)というように、<置き換え対象文字列>内の全てのへ置き換えてくれるもの。
  • patsubst$(<変数名>:<置き換え前suffix>=<置き換え後suffix>)という形式で使っている。指定したパターンを残して置き換えをしてくれる。
  • filter-out:あるパターンに一致するものを除外する。$(filter-out <除外したいパターン>,<空白区切り文字列>)とすると、 除外パターンに完全一致する文字列を除外して文字列を返してくれる。

Phonyターゲット

make cleanみたいに、何もファイルを作らないがコマンドを実行したいときに指定しておくターゲット。 テンプレでは、defaultconfcleanの3つのPhonyターゲットを指定している。

  • default:Makeを引数無しで実行すると実行されるもの。Makefileの変数を出力して、バイナリを作ってくれるようにしている。
  • confMakefileの変数を出力するターゲット。
  • clean:おなじみのやつ。オブジェクトファイルと実行ファイルを消すターゲット。

パターンマッチルール

Makefileにおける以下の部分のこと。%ワイルドカードで、$(OBJDIR)以下の*.oファイルは、 $(SRCDIR)/*.cから作られますよということをMakeに教えてあげるのがパターンマッチルール。

$(OBJDIR)/%.o : $(SRCDIR)/%.c

変数のメモ

  • SRCDIR:ソースファイルを格納するディレクトリ。テンプレではMakefileと同じディレクトリ。 Makefileの置いてあるディレクトリは毎回変わるけども、realpath関数でカレントディレクトリを取得するようにしている。
  • INCDIR:ヘッダファイルを格納するディレクトリ。テンプレではSRCDIRと同じ。
  • OBJDIR:オブジェクトファイルを格納するディレクトリ。テンプレではOBJDIRと同じ。
  • IGNOREコンパイル時に無視してほしいファイルを指定する。SRCDIRがフルパスなので、IGNOREもテンプレみたいにフルパスで指定する必要がある。
  • SRCSSRCDIR内のCファイル全部。いちいち指定するのが大変なので、wildcard関数を使って、ワイルドカードで指定できるようにしている。
  • OBJS:オブジェクトファイル全部。patsubst関数($(SRCS:.c=.o):のこと)を使って、Cファイルの".c"部分を".o"に変えている。 オブジェクトファイル置き場が変わったときのことを考えて、subst関数によりファイルパスのSRCDIR部分をOBJDIRに置き換えるようにしている。

おわりに

だいたい事足りそうなMakefileが書けたと思う。 これでちょこっとCでプログラムを書くときに、長いオプションをつけてgccコマンドを打たなくてよくなると思うと少し気が楽になる。

参考