オプション沼(11) Makefileの友? それほどでもない? gccの-Mオプション

Joseph Halfmoon

前回につづきプリプロセッサ・オプションです。-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から呼び出し可能な「画像描画」用ライブラリです。グラフィックエディタで作成するような画像を簡単に生成することができるもの。そのソースの先頭部分を引用させていただきます。Cairo

上記のように、#include文は “” でヘッダ・ファイルを指定しています。

-Mオプションで処理してみると以下のようです。helloCairo_M

-MMでは以下のようです。helloCairo_MM

 

cairo/cairo.h は、”” で囲っているのですが、システム側のヘッダファイルのディレクトリ配下に存在するのに、ちゃんとシステム側のファイルだと認識されているみたいっす。

なお、ビルドしているソースファイルは、pkgconfigでライブラリを指定しており、コマンドラインの順番でリンカエラーになったりするのです。しかし、-M、-MMオプションに関して言えば、プリプロセッサ処理だけで止めてしまうので、そんな後の方のことなどお構いなしです。

以下の例ではソースファイル名を末尾において、先にpkg-config(これでcairoライブラリ用のコンパイル/リンカオプションなどを与えている)を書くと、リンカでエラーになりますが、-Mであらばそこまで行く前におしまいです。helloCairo_Mpkg

上記のエラーになるコマンドラインでも「へいちゃら」なので、下記のようなエラーにならないコマンドラインでは当然OKっす。helloCairo_Mpkg2

ことさらにユーザーヘッダファイルをインクルードしてみる

上記例では、「ホンモノ」のユーザヘッダが無かったので、意味なしなユーザヘッダをインクルードするサンプルを作成してみました。まずは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

正常に動作するようです。optMmain

これに以下のように-Mオプションをつけてみると

$ gcc -M optMmain.c optMsub.c

出力先頭には、optMmain.cのシステムファイルを含む依存関係が長々と。optM1

出力後半は、optMsub .cの依存関係です。optM2

一方、-MMオプションの場合が以下に。

$ gcc -MM optMmain.c optMsub.c

出力はこれだけ。システムファイルを無視すればこれだけだと。簡単。optMM

便利なような、でも最近のIDEは、すべからくスマート?なビルドツールを内蔵していて、自分でMakefileを書いたりすることが無いような気がしないでもないです。どうなんだろ。

オプション沼(10) gccの-Eオプションを活用する? -dM、-dN、-dDオプション へ戻る

オプション沼(12) 外部からヘッダ・ファイルを与えられる -include オプション へ進む