configure, make, make install と書いてあるがそれぞれ何をしているか理解できていない。
Makefileの書き方を覚えれば、複数ファイルのビルドを自動化できます。
この記事では、makeコマンドの基本操作からMakefileの構造、
configure→make→make installの流れ、CMakeとの違い、よくあるエラーまで体系的に解説します。
RHEL 9 / Rocky Linux 9 / Ubuntu 24.04 LTS で動作確認済みです。
この記事のポイント
・Makefileのターゲット・依存・コマンドの3要素を理解できる
・configure → make → make install の流れと各ステップの役割がわかる
・makeコマンドのよく使うオプション(-n, -j, -C)を実践で使える
・CMakeとの違いと、どちらを使うべきか判断できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
makeコマンドとはなにか?なぜ必要なのか
Linuxでソースコードからソフトウェアをビルドするとき、ファイルが1つなら
gcc main.c -o myapp で済みます。ですが、実際のソフトウェアは数十~数百のファイルで構成されており、
変更されたファイルだけを再コンパイルして最終的な実行ファイルを作る仕組みが必要です。
これを担うのが make コマンドです。
make は「Makefile」(またはmakefile)という設定ファイルを読み込み、
どのファイルをどの順番でビルドするかを判断します。
ファイルのタイムスタンプを比較して「変更されたファイルだけ」を再ビルドするため、
大規模プロジェクトでも効率的に動作します。
Makefileの基本構造
Makefile はルール(rule)の集合体です。各ルールは「ターゲット」「依存関係」「コマンド」の3要素で構成されます。
# Makefileの基本書式 ターゲット: 依存ファイル1 依存ファイル2 コマンド(先頭はタブ文字。スペース禁止)
# シンプルなCプログラムのMakefile例 CC = gcc CFLAGS = -Wall -O2 myapp: main.o utils.o $(CC) $(CFLAGS) -o myapp main.o utils.o main.o: main.c $(CC) $(CFLAGS) -c main.c utils.o: utils.c utils.h $(CC) $(CFLAGS) -c utils.c clean: rm -f myapp *.o
・myapp:main.o と utils.o に依存する最終ターゲット
・main.o:main.c をコンパイルして生成
・utils.o:utils.c と utils.h に依存してコンパイル
・clean:ビルド成果物を削除(ファイルを生成しない「擬似ターゲット」)
重要: コマンドの行頭は必ずタブ文字(スペースは不可)です。
スペースで書いた場合は「*** missing separator」エラーになります。
1. makeコマンドを実行する
# カレントディレクトリのMakefileを実行(最初のターゲットが実行される) make # 特定のターゲットを指定して実行 make myapp # ビルドをクリーンにする make clean
[root@web01 httpd-2.4.62]# make Making all in srclib/apr make[1]: ディレクトリ '/usr/local/src/httpd-2.4.62/srclib/apr' に入ります /bin/sh /usr/local/src/httpd-2.4.62/srclib/apr/libtool --silent --mode=compile ...(省略)... make[1]: ディレクトリ '/usr/local/src/httpd-2.4.62/srclib/apr' から出ます [root@web01 httpd-2.4.62]#
makeコマンドのよく使うオプション
| オプション | 意味 | 使用例 |
|---|---|---|
| -n | ドライラン(実際には実行しない) | make -n install |
| -j N | N個の並列ジョブで高速ビルド | make -j4 |
| -C dir | 指定ディレクトリに移動してmakeを実行 | make -C /usr/local/src/nginx |
| -f file | Makefile以外のファイルを使う | make -f MyMakefile |
| -k | エラーが出ても続行する | make -k |
| -s | 実行するコマンドを表示しない(サイレント) | make -s |
| -B | 強制的に全ターゲットをビルド | make -B |
CPUコア数を指定することで大幅にビルド時間を短縮できます。
# CPUコア数を確認 nproc # 実行例: 8コアなら -j8 で並列ビルド make -j$(nproc)
configure → make → make install の流れ
OSSのソースコードをインストールする場合、以下の3ステップが一般的です。1. configure(./configure)
configure スクリプトは、現在の環境(OS、コンパイラ、ライブラリ)を調べてMakefile を自動生成します。
# 基本的な実行(インストール先を/usr/localに設定) ./configure --prefix=/usr/local # configureのオプションを確認する ./configure --help # Apacheの場合の例 ./configure \ --prefix=/usr/local/apache2 \ --enable-ssl \ --enable-rewrite \ --with-pcre=/usr/local/pcre
エラーメッセージに
not found と表示されたら、そのライブラリのdevelパッケージをインストールします。# configureエラーの例 configure: error: pcre2 library not found # RHEL系でdevelパッケージをインストール sudo dnf install pcre2-devel # Ubuntu系でdevパッケージをインストール sudo apt install libpcre2-dev
2. make(ビルド)
configure で生成された Makefile を使ってソースをコンパイルします。これが最も時間のかかるステップです。
# ビルド実行(並列化で高速化) make -j$(nproc)
3. make install(インストール)
ビルドした実行ファイルや設定ファイルを指定のディレクトリ(--prefix で設定したパス)にコピーします。# インストール(root権限が必要な場合が多い) sudo make install # インストール先を確認 ls /usr/local/apache2/bin/ # インストールを元に戻す(make install したものを削除) sudo make uninstall
Makefileの応用:変数とパターンルール
Makefile の本領は、変数とパターンルールを使った汎用的な記述にあります。1. 変数の使い方
# 変数の定義と使い方 CC = gcc CFLAGS = -Wall -O2 -g LDFLAGS = -lm TARGET = myapp SRCS = main.c utils.c network.c OBJS = $(SRCS:.c=.o) # .cを.oに置換 # 変数を使ったルール $(TARGET): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ # $@ : ターゲット名(myapp) # $^ : 全ての依存ファイル(main.o utils.o network.o) # $< : 最初の依存ファイル(main.o)
2. パターンルール
同じルールを何度も書かずに、パターンで一括定義できます。# .c から .o を生成するパターンルール(%がワイルドカード) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # これ1行で、main.c→main.o, utils.c→utils.o などを全てカバーできる
3. PHONYターゲット
clean や all など、実際のファイルを生成しないターゲットは.PHONY で宣言します。同名のファイルが存在してもルールが実行されることを保証します。
.PHONY: all clean install test all: $(TARGET) clean: rm -f $(TARGET) $(OBJS) install: $(TARGET) install -m 755 $(TARGET) /usr/local/bin/ test: $(TARGET) ./run_tests.sh
4. 自動依存関係の生成
ヘッダファイルが変更された場合も再コンパイルするための仕組みです。大規模プロジェクトでは必須の技法です。
# -MMD でヘッダ依存を自動生成する設定 CC = gcc CFLAGS = -Wall -O2 -MMD -MP SRCS = main.c utils.c OBJS = $(SRCS:.c=.o) DEPS = $(SRCS:.c=.d) $(TARGET): $(OBJS) $(CC) -o $@ $^ %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # 自動生成した依存ファイルをインクルード -include $(DEPS)
makeを活用したタスク自動化
Makefile はビルドだけでなく、タスクランナーとして使うエンジニアも多くいます。deploy, test, lint などのタスクを Makefile にまとめると、
チーム全員が
make deploy だけで統一的に操作できるようになります。# タスクランナーとしてのMakefile例 .PHONY: all build test lint deploy clean # ヘルプ表示(makeだけで使い方を表示) help: @echo "利用可能なターゲット:" @echo " make build - ビルドを実行" @echo " make test - テストを実行" @echo " make deploy - 本番環境にデプロイ" @echo " make clean - ビルド成果物を削除" build: @echo "ビルド開始..." go build -o bin/server ./cmd/server/ test: go test ./... -v lint: golangci-lint run ./... deploy: build test rsync -avz bin/server user@web01.example.com:/usr/local/bin/ ssh user@web01.example.com "systemctl restart myapp" clean: rm -rf bin/
CMakeとmakeの違いはなにか
近年の大規模プロジェクトでは CMake が採用されるケースが増えています。makeの特徴:
・Makefile を手書きまたは configure で生成する
・Unix/Linux 環境に特化した伝統的なビルドシステム
・古いOSSや中小規模プロジェクトで広く使われている
CMakeの特徴:
・CMakeLists.txt という設定ファイルを書く
・クロスプラットフォーム(Linux/Windows/macOS)に対応
・最終的にはLinuxではMakefileを生成してmakeを実行する(フロントエンド)
・大規模プロジェクト(LLVM、KDE、MySQL等)で採用されている
# CMakeを使ったビルドの流れ mkdir build && cd build cmake .. # Makefileを生成 make -j$(nproc) # ビルド sudo make install # インストール # またはcmake --buildで統一的に実行 cmake --build . --parallel $(nproc)
Autotools(./configure)の仕組みをもう少し理解する
OSSのソースパッケージに含まれる configure スクリプトは、「Autotools」という仕組みで生成されています。
Autotools は configure.ac と Makefile.am というテンプレートから configure と Makefile.in を生成します。
ユーザーとしては configure を実行するだけですが、
その背後で何が起きているかを知っていると、エラーの意味が理解しやすくなります。
1. configure.log を確認する
configure が失敗したとき、エラーの詳細は config.log に記録されます。# configure 失敗後にログを確認 tail -50 config.log # よくある原因の検索 grep "error:" config.log grep "No such" config.log
2. pkgconfig(pkg-config)でライブラリを確認する
configure は pkg-config を使ってシステムにインストールされているライブラリの情報を取得します。# インストール済みのライブラリを確認 pkg-config --list-all | grep ssl # 特定ライブラリのバージョンとコンパイルフラグを確認 pkg-config --modversion openssl pkg-config --cflags --libs openssl # 実行例 -I/usr/include/openssl -lssl -lcrypto
3. make distclean で完全リセット
configure のやり直しをするときはmake clean では不十分なことがあります。# make clean: コンパイル生成物のみ削除(Makefile は残る) make clean # make distclean: configure が生成したファイルも削除(完全リセット) make distclean # distclean 後に再configure ./configure --prefix=/usr/local --enable-ssl
よくあるエラーと対処法
1. *** missing separator エラー
Makefile:5: *** missing separator. Stop.
エディタで「タブ文字を表示する」設定にして、スペースをタブに置き換えてください。
2. make: gcc: No such file or directory
# RHEL系:開発ツールをまとめてインストール sudo dnf groupinstall "Development Tools" # Ubuntu系 sudo apt install build-essential
3. make: *** [ターゲット] Error 1
コマンドが非ゼロの終了コードを返しています。エラーメッセージをさかのぼって確認し、具体的な原因を特定します。
・ライブラリ不足 → devel/devパッケージをインストール
・コンパイラの警告がエラー扱い → CFLAGS から -Werror を外す
・不完全なソース → ソースを再ダウンロードして試す
4. configure: error: C compiler cannot create executables
gcc がインストールされていないか、正常に動作していません。# gcc の確認 gcc --version # インストール sudo dnf install gcc gcc-c++
5. make install 後に実行ファイルが見つからない
--prefix で指定したディレクトリが PATH に含まれていない場合に起きます。# インストール先のbinを確認 ls /usr/local/apache2/bin/ # PATH に追加(~/.bashrc に追記する) export PATH=/usr/local/apache2/bin:$PATH # 即時反映 source ~/.bashrc # コマンドの場所を確認 which httpd
6. ld: cannot find -lXXX(リンクエラー)
ビルドは成功したが、リンクステップでライブラリが見つからないエラーです。# エラー例 /usr/bin/ld: cannot find -lssl # 原因と対処 # 1. devel パッケージが未インストール sudo dnf install openssl-devel # 2. ライブラリのパスが通っていない echo $LD_LIBRARY_PATH export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH # 3. ldconfig でライブラリキャッシュを更新 sudo ldconfig
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| makeを実行する | make |
| ドライラン(実行内容を確認) | make -n |
| 並列ビルド(高速化) | make -j$(nproc) |
| ビルド成果物をクリーン | make clean |
| ソースのインストール | sudo make install |
| configureを実行する | ./configure --prefix=/usr/local |
| CMakeでMakefileを生成 | cmake .. |
| 開発ツール一式をインストール(RHEL系) | dnf groupinstall "Development Tools" |
またシェルスクリプトの代わりに Makefile でタスクを管理するエンジニアも多く、
インフラ自動化の現場でも Makefile の読み書きが求められることがあります。
まずは
make -n でドライランしながら動作を確認してみてください。実際にビルドが走る前に何をやろうとしているか確認できるので、学習にも最適です。
現場では「パッケージ(RPM/DEB)があればソースビルドは避ける」のが鉄則です。
ソースビルドはパッケージ管理システムが追跡できないため、
アップデートや削除が煩雑になります。
ただし、最新バージョンを使いたい場合やカスタムオプションが必要な場合は、
ここで解説した手順がそのまま使えます。
ファイルシステムの作成とフォーマットについては、Linuxでファイルシステムを作成する方法もあわせてご覧ください。
起動プロセスの詳細については、Linuxのsystemdによる起動プロセスを理解するで解説しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます