公開:

Makefileとは?意味をわかりやすく簡単に解説

text: XEXEQ編集部


Makefileとは

Makefileとは、プログラムのビルドを自動化するためのファイルです。プログラムのソースコードから実行可能なバイナリファイルを生成する手順を記述したものになります。

Makefileには、ターゲットとなるファイルとそれを生成するための依存関係やコマンドが記述されています。これにより、プログラムのビルド作業を効率化し、ミスを減らすことができます。

Makefileの記述には、特有の文法が使用されます。ターゲットとなるファイル名、依存するファイル名、ビルドに必要なコマンドなどを適切に記述する必要があります。

一般的に、Makefileはプロジェクトのルートディレクトリに配置されます。そして、makeコマンドを実行することで、Makefileに記述された手順に従ってプログラムのビルドが自動的に行われます。

Makefileを利用することで、プログラムの開発や保守作業が容易になります。特に、大規模なプロジェクトにおいては、Makefileの存在が欠かせないものとなっています。

Makefileの基本的な構文

Makefileに関して、以下3つを簡単に解説していきます。

  • ターゲットとなるファイル名の記述方法
  • 依存関係の定義と記述方法
  • ビルドコマンドの記述方法

ターゲットとなるファイル名の記述方法

Makefileでは、ターゲットとなるファイル名を記述します。ターゲットは、生成されるファイルや実行するアクションを表します。

ターゲットの記述は、ファイル名やラベルを使用します。例えば、実行可能ファイルの名前や、クリーンアップ用のラベルなどが該当します。

myapp: main.o utils.o
    gcc -o myapp main.o utils.o

clean:
    rm -f *.o myapp

依存関係の定義と記述方法

Makefileでは、ターゲットとなるファイルの依存関係を定義します。依存関係とは、あるファイルを生成するために必要な他のファイルのことを指します。

依存関係の記述は、ターゲットの後にコロン(:)を続け、その後に依存するファイル名を空白区切りで記述します。これにより、ターゲットを生成する前に、依存するファイルが最新の状態であることを確認できます。

main.o: main.c utils.h
    gcc -c main.c

utils.o: utils.c utils.h
    gcc -c utils.c

ビルドコマンドの記述方法

Makefileでは、ターゲットを生成するためのビルドコマンドを記述します。ビルドコマンドは、コンパイルやリンク、ファイルの移動やコピーなど、様々な処理を行います。

ビルドコマンドの記述は、ターゲットと依存関係の定義の次の行から始めます。各行の先頭にタブ文字を入れ、実行するコマンドを記述します。複数のコマンドを記述する場合は、各コマンドを別の行に記述します。

myapp: main.o utils.o
    gcc -o myapp main.o utils.o

main.o: main.c utils.h
    gcc -c main.c

utils.o: utils.c utils.h
    gcc -c utils.c

Makefileのマクロと変数

Makefileに関して、以下3つを簡単に解説していきます。

  • マクロの定義と使用方法
  • 自動変数の種類と使い方
  • 条件分岐と関数の使用方法

マクロの定義と使用方法

Makefileでは、マクロを使用して変数のような働きをさせることができます。マクロは、値を持つ名前付きの記号であり、Makefile内で使用できます。

マクロの定義は、名前と値を等号(=)で結びつけて行います。マクロの参照は、$(マクロ名)or${マクロ名}の形式で行います。マクロを使用することで、Makefileの可読性や保守性が向上します。

CC = gcc
CFLAGS = -Wall -O2

myapp: main.o utils.o
    $(CC) -o myapp main.o utils.o

main.o: main.c utils.h
    $(CC) $(CFLAGS) -c main.c

utils.o: utils.c utils.h
    $(CC) $(CFLAGS) -c utils.c

自動変数の種類と使い方

Makefileには、自動変数と呼ばれる特殊な変数があります。自動変数は、ターゲットやそれに依存するファイルの名前を自動的に参照するために使用されます。

代表的な自動変数として、$@はターゲットの名前、$^は依存するファイルの名前、$<は最初の依存ファイルの名前を表します。自動変数を使用することで、ルールの記述を簡潔にできます。

myapp: main.o utils.o
    $(CC) -o $@ $^

main.o: main.c utils.h
    $(CC) $(CFLAGS) -c $<

utils.o: utils.c utils.h
    $(CC) $(CFLAGS) -c $<

条件分岐と関数の使用方法

Makefileでは、条件分岐や関数を使用して、より柔軟なビルド制御を行うことができます。条件分岐は、ifdef, ifeq, ifneqなどのディレクティブを使用して行います。

また、Makefileには、文字列操作や変数操作などの組み込み関数が用意されています。関数を使用することで、Makefileの記述をより簡潔で可読性の高いものにできます。

ifeq ($(OS),Windows_NT)
    CFLAGS += -DWINDOWS
endif

TARGET = myapp
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))

$(TARGET): $(OBJS)
    $(CC) -o $@ $^

%.o: %.c
    $(CC) $(CFLAGS) -c $<

Makefileの応用的な使い方

Makefileに関して、以下3つを簡単に解説していきます。

  • サフィックスルールの使用方法
  • 再帰的なMakefileの作成方法
  • フェイクターゲットの使用方法

サフィックスルールの使用方法

Makefileでは、サフィックスルールを使用して、拡張子に基づくルールを定義できます。サフィックスルールは、あるファイルの拡張子から別の拡張子へのルールを表します。

サフィックスルールを使用することで、同じパターンのファイルに対するルールを簡潔に記述できます。例えば、.cファイルから.oファイルへのコンパイルルールを定義できます。

.SUFFIXES: .c .o

.c.o:
    $(CC) $(CFLAGS) -c $<

myapp: main.o utils.o
    $(CC) -o $@ $^

再帰的なMakefileの作成方法

Makefileは、サブディレクトリ内の別のMakefileを呼び出すことで、再帰的なビルドを行うことができます。これにより、プロジェクトを階層的に管理し、モジュール単位でビルドできます。

再帰的なMakefileの作成には、サブディレクトリ内のMakefileをコールするルールを定義します。また、サブディレクトリ内のMakefileでは、親ディレクトリの変数を参照することもできます。

SUBDIRS = src include

all:
    for dir in $(SUBDIRS); do 
        $(MAKE) -C $$dir; 
    done

clean:
    for dir in $(SUBDIRS); do 
        $(MAKE) -C $$dir clean; 
    done

.PHONY: all clean

フェイクターゲットの使用方法

Makefileでは、フェイクターゲットと呼ばれる特殊なターゲットを定義できます。フェイクターゲットは、ファイルを生成するのではなく、特定のアクションを実行するために使用されます。

フェイクターゲットは、.PHONYディレクティブを使用して定義します。これにより、同名のファイルがあってもターゲットが実行されます。代表的なフェイクターゲットとして、all, clean, installなどがあります。

.PHONY: all clean

all: myapp

myapp: main.o utils.o
    $(CC) -o $@ $^

clean:
    rm -f myapp *.o

※上記コンテンツはAIで確認しておりますが、間違い等ある場合はコメントよりご連絡いただけますと幸いです。

「コンピュータ」に関するコラム一覧「コンピュータ」に関するニュース一覧
ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。