前回につづきプリプロセッサ・オプションです。-Mと-MM。オブジェクトの依存関係をMakefile用に出力してくれるもの。-Mおよび-MMを使用すると-Eオプション同様プリプロセッサ処理までで終了します。Makefileを作るのに役に立つ?でもま最近、Makefileを自分で書くこともあまり無い気がするのですが。
※『オプション沼』投稿順indexはこちら
システム・ヘッダ・ファイルを含める/省略する
今回、試用してみる -M と -MM オプションは、どちらもMakefileで使えそうなファイルの依存関係を出力してくれるオプションです。-Mと-MMの違いは
-
- -M システム・ヘッダ・ファイルを含める
- -MM ユーザ定義のヘッダのみ含め、システム・ヘッダは除く
であるようです。gccの以下のドキュメントなど参照させてもらうと
3.13 Options Controlling the Preprocessor
以下の#include の書き方のうち、<ほにゃらら> はシステム・ヘッダ・ファイル、”ちょめちょめ”はユーザ定義にも思えるのですが、違いました。
#include <ほにゃらら> #include "ちょめちょめ"
以下を御覧じろ。別シリーズの以下の回で試用してみたCairoライブラリのお試しソースです。
トホホな疑問(52) WSL2、Ubuntu、学ばないな、pkg-configでコケる
Cairoライブラリは、Cから呼び出し可能な「画像描画」用ライブラリです。グラフィックエディタで作成するような画像を簡単に生成することができるもの。そのソースの先頭部分を引用させていただきます。
上記のように、#include文は “” でヘッダ・ファイルを指定しています。
cairo/cairo.h は、”” で囲っているのですが、システム側のヘッダファイルのディレクトリ配下に存在するのに、ちゃんとシステム側のファイルだと認識されているみたいっす。
なお、ビルドしているソースファイルは、pkgconfigでライブラリを指定しており、コマンドラインの順番でリンカエラーになったりするのです。しかし、-M、-MMオプションに関して言えば、プリプロセッサ処理だけで止めてしまうので、そんな後の方のことなどお構いなしです。
以下の例ではソースファイル名を末尾において、先にpkg-config(これでcairoライブラリ用のコンパイル/リンカオプションなどを与えている)を書くと、リンカでエラーになりますが、-Mであらばそこまで行く前におしまいです。
上記のエラーになるコマンドラインでも「へいちゃら」なので、下記のようなエラーにならないコマンドラインでは当然OKっす。
ことさらにユーザーヘッダファイルをインクルードしてみる
上記例では、「ホンモノ」のユーザヘッダが無かったので、意味なしなユーザヘッダをインクルードするサンプルを作成してみました。まずはmain関数のファイル、optMmain.c。
#include <stdio.h> #include <stdlib.h> #include "optMsub.h" int main(void) { char *msg; msg = getMessage(); printf("MSG=%s\r\n", msg); free(msg); return 0; }
上記でインクルードしているユーザヘッダ optMsub.h が以下に(同じディレクトリ階層にあり。)
char *getMessage(void);
そして呼び出しているユーザ関数の実体ソース optMsub.c が以下に。
$ cat optMsub.c #include <stdlib.h> #include <string.h> char *getMessage(void) { char temp[] = "Hello!"; char *buf = (char*)malloc(strlen(temp)); strcpy(buf, temp); return buf; }
念のため、以下のようにしてコンパイルしてみれば
$ gcc -g -O0 optMmain.c optMsub.c
これに以下のように-Mオプションをつけてみると
$ gcc -M optMmain.c optMsub.c
出力先頭には、optMmain.cのシステムファイルを含む依存関係が長々と。
一方、-MMオプションの場合が以下に。
$ gcc -MM optMmain.c optMsub.c
出力はこれだけ。システムファイルを無視すればこれだけだと。簡単。
便利なような、でも最近のIDEは、すべからくスマート?なビルドツールを内蔵していて、自分でMakefileを書いたりすることが無いような気がしないでもないです。どうなんだろ。