🐧 Linux 総合学習プラットフォーム
C・ビルドツール ・ 中級〜上級

configure・CMakeの世界地図

インターネットで拾ってきたソースコード一式を自分でビルドしようとすると、多くの場合「./configure && make && make install」か「cmake -B build」のどちらかに出会います。これらはMakefileを手で書く代わりに、環境に合わせて自動生成してくれる仕組みです。ここではAutotoolsのconfigureとCMakeという2大流派の正体、out-of-sourceビルドの考え方、依存ライブラリの旗を教えてくれるpkg-configまでをまとめて見取り図にします。この回を終えると、世に出回っているたいていのC/C++プロジェクトを臆せずビルドできるようになります。

GitHubから面白そうなC/C++プロジェクトを拾ってきて、いざビルドしようとすると、多くの場合README には2種類の呪文のどちらかが書いてある。./configure && make && make install か、cmake -B build && cmake --build build のどちらかだ。

🔗
たとえこれまで学んできたMakefileは「1つの料理のレシピ」だった。configureやCMakeは、キッチンの設備(コンパイラの種類・ライブラリの有無・OSの違い)を先に調べてから、その環境向けのレシピそのものを自動生成してくれる下ごしらえ役だ。

🗺️ 2つの流派——Autotools系とCMake系

歴史的に古くから使われてきたのがAutotools(GNU Autoconf/Automake)という仕組みで、その使用者側の窓口がconfigureスクリプトだ。より新しく、多くのプラットフォームで人気なのがCMakeで、CMakeLists.txtという設定ファイルを起点にする。

どちらも目指すゴールは同じで、「このマシンにはどんなコンパイラがあるか」「必要なライブラリは揃っているか」を調べたうえで、実際にビルドするためのMakefile(やそれに相当するもの)を作り出すことにある。

Autotools系./configureCMake系CMakeLists.txt環境を検査してMakefile生成make で実際にビルド
💡
ポイントconfigureもCMakeも、Makefileを手で書く代わりに「環境に合わせて生成する」役割を担う。手書きMakefileの延長線上にある道具だと捉えると理解しやすい。

⚙️ configure——Autotoolsが調べて生成する

configureを実行すると、画面には「〜のヘッダを探しています... yes」のような検査ログが大量に流れる。これはコンパイラの種類、利用可能な関数、必要なライブラリの有無などを1つずつ調べているためだ。

$ ./configure --prefix=/usr/local $ make $ sudo make install --prefixはインストール先を指定するオプションの代表例で、configureにはこのように多数のオプションが用意されていることが多い。詳細は各プロジェクトの ./configure --help で確認できる。
つまずきconfigureスクリプト自体は各プロジェクトが用意しているものであり、書き方や生成元のAutoconfのバージョンによって細部が異なる。困ったときはプロジェクト付属のINSTALLファイルやREADMEを必ず確認する。

🧊 CMake——CMakeLists.txtから多様なビルド系を生成

CMakeはconfigureよりも新しい設計で、Makefileだけでなく、環境によってはNinjaというビルドツール向けのファイルや、統合開発環境向けのプロジェクトファイルまで生成できる、いわば「メタビルドツール」(cba-meta-build)だ。

$ cmake -B build $ cmake --build build -Bは生成物を置くディレクトリを指定するオプションで、ここではbuildという名前のディレクトリにMakefile等がまとめて作られる。cmake --build buildは、その中身に応じて実際のビルドコマンド(多くの場合make)を呼び出してくれる。

📂 out-of-sourceビルド——buildディレクトリを分ける理由

上の例で気づいた通り、CMakeは生成物をソースコードと同じ場所ではなく、buildという別のディレクトリにまとめて作る。これをout-of-sourceビルド(cba-out-of-source)と呼ぶ。

プロジェクト直下CMakeLists.txtsrc/main.cbuild/(生成物専用)buildの中だけにMakefileや.oファイルが溜まるので、ソース側は汚れない。掃除したいときはbuildごと削除するだけでよい。
💡
ポイントout-of-sourceビルドでは、生成物がすべてbuildディレクトリの中に閉じ込められる。やり直したくなったらbuildディレクトリを丸ごと削除するだけでよく、ソースコード側は常にきれいなまま保たれる。
🔗
たとえソースコードの隣で直接ビルドするのは、作業机の上で調理して食べかすもそのまま置いておくようなものだ。out-of-sourceビルドは、調理は別のシンクでやって、机の上(ソース)は常に片付いた状態に保つ工夫といえる。
コツAutotools系のプロジェクトでも、ソースディレクトリの外に別のディレクトリを作ってそこから../configureを呼び出せば、同じようにout-of-sourceビルドができる。CMakeほど徹底されてはいないが、覚えておくと便利な小技だ。

🚩 pkg-configで依存ライブラリの旗を受け取る

自分のプログラムが外部ライブラリ(例えばOpenSSLやzlibなど)に依存しているとき、そのライブラリのヘッダがどこにあるか、リンクにどんなオプションが必要かを手で調べるのは面倒だ。この情報を教えてくれるのがpkg-configだ。

$ pkg-config --cflags --libs zlib -I/usr/include -lz --cflagsはコンパイル時に必要なオプション(ヘッダの場所など)、--libsはリンク時に必要なオプション(ライブラリ名など)を、まとめて「旗」として吐き出してくれる。
つまずきpkg-configが返す情報は、対象ライブラリが.pcという設定ファイルを提供している場合に限られる。見つからないときはライブラリ側のドキュメントを確認する。

🌍 読めるようになると、世界のOSSが手元でビルドできる

ここまで見てきたconfigure・CMake・pkg-configは、それぞれ単体では小さな道具だが、組み合わさることで「環境の違いを吸収して、誰の手元でも同じようにビルドできる」という大きな仕組みを実現している。

最初は呪文にしか見えなかった./configure && make や cmake -B build も、正体が分かれば「環境を調べてMakefileを作り、それを実行しているだけ」だと分かる。今までMakefileを手で書いてきた経験が、そのままこの理解の土台になっている。この見取り図を持てば、世の中のC/C++プロジェクトのREADMEに書かれたビルド手順がどちらの流派で何をしているコマンドなのか、読み解けるようになっているはずだ。

この項目に出てくる用語

out-of-sourceビルドあうとおぶそーすびるど
ソースコードとは別のディレクトリにビルド成果物をまとめて生成する方式。CMakeで標準的。
メタビルドツールめたびるどつーる
Makefile自体を環境に応じて生成する、ビルドツールより一段上の道具。CMakeなど。

関連コマンド

cmakepkg-config

▶ 学習アプリでこの続きを学ぶ・演習する