CMakeは、コンパイラに依存しない命令を使用してアプリケーションを構築するための、無料のクロスプラットフォームソフトウェア開発ツールです。テスト、パッケージング、インストールを自動化することもできます。さまざまなプラットフォームで動作し、多くのプログラミング言語をサポートしています。[ 3 ]
メタビルドツールとして、CMake はネイティブビルドツールを構成し、それらのツールがコードベースをビルドします。CMake は、 CMake 固有の構成ファイルに基づいて、他のビルドツール用の構成ファイルを生成します。他のツールは、生成されたファイルを使用して、より直接的にビルドを実行します。単一の CMake 固有の構成ファイルセットを使用して、複数のプラットフォームのネイティブビルドツールでコードベースをビルドできます。[ 4 ]
CMakeでサポートされている主なネイティブビルドツールには、Make、Qt Creator、Ninja、Android Studio、Xcode、Visual Studioなどがあります。[ 4 ]
CMakeは、寛容なBSD-3-Clauseライセンスの下で、フリーかつオープンソースのソフトウェアとして配布されています。[ 5 ]
初期開発は1999年にKitwareで開始され、米国国立医学図書館からの資金提供を受け、Visible Human Projectの一環として行われた。[ 4 ] CMakeは2000年に初めてリリースされた。
CMake は、複数のプラットフォーム向けにInsight Segmentation and Registration Toolkit (ITK) をビルドするために開発されました。目標には、autoconfやlibtoolなどの最新のツールの長所を維持しつつ弱点に対処すること、そして当時の最先端のビルド技術、つまりUnixプラットフォーム用の構成スクリプトとMakeファイル、およびWindows用のVisual Studioプロジェクト ファイルと整合することが含まれていました。[ 6 ] [ 4 ]
CMake は、複数の現代的なツールから着想を得ています。pcmaker は、Visualization Toolkit (VTK) の ビルドをサポートするために Ken Martin らが開発したもので、 Unix Make ファイルを Windows 上でビルドするための NMake ファイルに変換します。[ 4 ] gmake は Unix と Windows のコンパイラをサポートしていましたが、その設計により解決が難しい問題が生じました。どちらのツールも、Unix と Windows の両方をサポートするビルド ツールの実例でしたが、重大な欠陥がありました。それは、多くの Windows 開発者が Visual Studio などの統合開発環境 (IDE) を使用することを好むにもかかわらず、コマンドラインを使用する必要があったことです。
CMakeは、同様のクロスプラットフォームサポートを提供すると同時に、各プラットフォームの開発者の好みをより良く満たすことを目的としていました。
最初のバージョンの設計目標には以下が含まれていました。[ 4 ]
さまざまな理由から、CMake の開発者は、当時ビルドによく使われていたTcl ではなく、 CMake 用のスクリプト言語を開発することを選択しました。Tcl を使用すると、コンパイラ以外の依存関係を持たないという目標に反して、ホスト マシンへの依存関係が追加されてしまいます。また、初期開発当時、Tcl は Windows や一部の Unix システムでは十分にサポートされていませんでした。[ 4 ]
その後の開発と改善は、VXLプロジェクト、Brad Kingによって追加されたCABLE [ 7 ]機能、およびDART (3.7以降非推奨)をサポートするGEコーポレートR&Dなど、開発者自身のシステムへのCMakeの組み込みによって促進されました。[ 8 ] VTKがビルド環境とParaViewのサポートのためにCMakeに移行したときに、追加の機能が作成されました。
バージョン 3.0 は 2014 年 6 月にリリースされました。[ 9 ]これは「モダン CMake」の始まりとされています。[ 10 ]専門家は現在、変数の使用を避け、ターゲットとプロパティを使用することを推奨しています。[ 11 ] CMake 2 の中核であったコマンドadd_compile_options、、、は、include_directoriesターゲット固有のコマンドに置き換える必要があります。link_directorieslink_libraries
CMake開発者のブラッド・キング氏は、「CMakeの『C』は『クロスプラットフォーム』を意味する」と述べた。
CMake は、 Microsoft Visual Studio、Xcode、Eclipse CDTなどのIDE用のプロジェクト ファイルと、Windows 上の MSBuild または NMake 用のビルド スクリプト、Linux、macOS、Cygwinなどの Unix ライクなプラットフォーム上のUnix Make、およびプラットフォーム固有のビルド ツール用のジェネレータを指定することで、Windows と Unix ライクなプラットフォームの両方上のNinja 用のビルド スクリプトを生成できます。デフォルトでは、CMake は実行中のホスト環境のデフォルト ジェネレータを自動的に決定します。コマンドライン オプションを使用して、代替のジェネレータを指定できます。たとえば、 CMake にmake用のビルド スクリプトを作成するように強制します。[ 4 ]-G-G Unix Makefiles
CMakeは、CMakeの実装を変更しない限り、カスタムジェネレーターをサポートしていません。ただし、CMakeのソースコードを修正することで、カスタムジェネレーターを組み込むことは可能です。
CMake は、実行可能ファイル、ライブラリ (など)、オブジェクト ファイル ライブラリ、および擬似ターゲット (エイリアスを含む) のビルドをサポートしていますlibxyz。CMakexyz.dllは、動的 (実行時) リンクを回避し、代わりに静的 (コンパイル時) リンクを使用して、実行可能バイナリ/ライブラリからリンクできるオブジェクト ファイルを作成できます。これにより、さまざまな最適化の設定に柔軟性が生まれます。[ 12 ]
ターゲット生成は、ターゲットプロパティを介して構成できます。以前のバージョンでは、これはCMAKE_プレフィックス付きグローバル変数を介して行われていましたが、この方法は非推奨です。[ 11 ] [ 13 ]
CMake 設定ファイルは、ソースコードの階層構造、つまりソースツリーに従って構成できます。CMakeLists.txtルートソースディレクトリ内の が構成のルートとして機能します。 には、それぞれ を含むサブディレクトリが含まれる場合がありますCMakeLists.txt。これを繰り返すと、ソースコードの構造に従った階層的な構成構造ができます。[ 11 ] [ 13 ]
CMake は、生成されたファイル (CMake とネイティブのビルドツールの両方によって生成されたファイル) を、ソースツリーとは別のディレクトリツリーに保存できます。 [ 4 ]
これにより、各ビルドのファイルシステム領域が重複しないため、同じソースツリーから複数のビルドが可能になります。この特性を活用すれば、異なるプラットフォーム向けなど、異なる構成や互換性のない構成を構築できます。
これにより、ソースツリー全体から複数のファイルやディレクトリを削除する代わりに、単一のディレクトリツリーを削除するだけで生成されたファイルを削除できるため、ファイル管理が簡素化されます。これは、ソースファイルを誤って削除したり、生成されたファイルを誤ってソース管理に追加したりするのを防ぐのに役立ちます。
CMakeは、ソースコードが変更またはビルドされたときに、下流のコンポーネントが再ビルドされることを保証します。[ 4 ]
CMakeは、システム全体およびユーザーが指定した実行可能ファイル、ライブラリを検索できます。これらの場所はキャッシュに保存され、ターゲットビルドファイルを生成する前にカスタマイズできます。キャッシュは、CMakeに付属のグラフィカルエディタで編集できます。
CMake は、複雑なディレクトリ階層や複数のライブラリに依存するアプリケーションを十分にサポートしています。たとえば、CMake は、複数のツールキットや、それぞれが複数のディレクトリを持つライブラリを含むプロジェクトに対応できます。さらに、CMake は、最終アプリケーション用にコンパイルするコードを生成する前に実行可能ファイルを作成する必要があるプロジェクトにも対応できます。オープンソースで拡張可能な設計により、CMake は特定のプロジェクトに合わせて必要に応じて適応できます。[ 14 ]
CMakeでは、ターゲットプログラムやライブラリをコンパイルするためにコンパイラがサポートする必要のある機能を指定できます。[ 15 ]
CMakeは、Apple Clang、Clang、GNU GCC、MSVC、Oracle Developer Studio、Intel C++ Compilerなど、多くのコンパイラをサポートしています。[ 16 ]
CMake は、エンド ユーザーとサードパーティの CMake ベースのプロジェクトの両方で使用できるパッケージを生成できます。CPack を介して、ビルドされたファイルは、ターゲット システムのパッケージ マネージャー ( dpkgなど) またはターゲット プラットフォームでサポートされているインストーラ用のアーカイブ ファイルにパックできます。 [ 17 ] : 132、142 [ 18 ] [ 19 ] CMake は、ビルド プロセスの一部として使用できる、または以前にインストールされた cmake パッケージをリンクできる、リモート サーバーからパッケージをプルする機能を提供します。[ 19 ]
CMake は、コマンドライン インターフェースを介してプロジェクトを構成するために使用できるncursesプログラムを使用して実行できます。ccmake
バージョン3.6以降、CMakeを使用してプリコンパイル済みヘッダーを生成することが可能です。[ 20 ]バージョン3.28以降、CMakeはモジュールのコンパイルも可能になりました。ヘッダーユニットの実験的なサポートも存在します。[ 21 ]
CMakeはJSONデータ文字列から変数に値を抽出する機能をサポートしています(バージョン3.19以降)。[ 22 ]
CMakeには、変数、文字列操作、配列、関数およびマクロの宣言、モジュールのインクルード(インポート)をサポートする、比較的シンプルでカスタムな命令型スクリプト言語のインタープリタが含まれています。
インタープリタは、CMakeLists.txtソースファイルとビルド設定を指定する名前のファイルから CMake 言語コマンドを読み取ります。CMake はこの情報を使用してネイティブツール構成ファイルを生成します。さらに、サフィックスの付いたファイルは.cmake追加のスクリプトを格納するために使用できます。[ 23 ]
CMake言語のコマンドは次のようにフォーマットされます。
名前(引数...)
引数は空白で区切られ 、引数のグループを区切るキーワードを含めることができます。たとえば、次のコマンドでは、キーワードがCOMPILE_FLAGSソースファイルのリストとコンパイラフラグを区切っています。[ 24 ]
set_source_file_properties( filename ... COMPILE_FLAGS compile_flag ...)
CMakeスクリプト言語は、YaccおよびLexジェネレーターを介して実装されています。
実行可能プログラムであるCMake、CPack、およびCTestはC++で記述されています。
CMakeの機能の多くは、CMake言語で書かれたモジュールで実装されています。[ 25 ]
CMakeのドキュメント(バージョン3.0以降)はreStructuredTextマークアップを使用しています。HTMLページとマニュアルページはSphinxドキュメントジェネレーターによって生成されます。
CMake には.cmake、依存関係 (組み込みおよび外部、たとえばFindXYZモジュール) の検索、ツールチェーン環境と実行可能ファイルのテスト、リリースのパッケージ化 (CPack)、外部プロジェクトの依存関係の管理 (モジュール) などのタスクを容易にする多数のスクリプト ファイルとExternalProject開発ツールが付属しています。追加の開発ツールには、次のものがあります。[ 26 ] [ 27 ]
CMake は商用、オープンソース、学術ソフトウェア プロジェクトで広く採用されています。注目すべきユーザーには、 Android NDK、Netflix、Inria、 MySQL、Boost (C++ ライブラリ)、KeePassXC、KDE、KiCAD、FreeCAD、Webkit、Blender、[ 30 ] Biicode 、 ReactOS 、 Apache Qpid、ATLAS 実験、[ 31 ]およびSecond Life [ 32 ]などがあります。
CMake によるビルドには 2 つの主要な段階があります。[ 4 ]まず、 CMake スクリプト言語で記述された CMake 構成ファイルからネイティブ ビルド ツール構成ファイルが生成されます。コマンドライン構文は、<dir> がファイルを含むディレクトリであるときです。次にcmake <dir>、CMakeLists.txtネイティブ ビルド ツールは CMake ( ) またはネイティブ ツールのインターフェースを介して直接呼び出されますcmake --build <dir>。ネイティブ ビルド ツールは生成されたファイルを使用します。[ 14 ] [ 33 ]
以下では、C++で記述された「ハローワールド」プログラムをビルドするようにCMakeを設定する方法と、CMakeを使用してそのプログラムをビルドする方法を示します。
hello.cpp :
#include <print>int main () { std :: println ( "Hello, world!" ); return 0 ; }CMakeLists.txt :
cmake_minimum_required ( VERSION 3.22 ) project ( HelloWorld CXX ) add_executable ( hello hello.cpp )CMake を使ってビルドするには、まず上記の 2 つのファイルを含むディレクトリに移動します。次に、クロスプラットフォームの CMake コマンドを使用してネイティブビルド構成ファイルを生成します。
cmake -B out . 生成されたすべてのファイルは、で指定されたディレクトリout-B outの下にあります。
次に、CMakeでサポートされているネイティブビルドツールを使用してビルドします。
cmake --build out これでプログラムを実行できるようになります。Bash では、コマンドは次のようになります./out/hello。Windows では、出力ファイルはで終わります.exe。
この例では、プリプロセッサのインクルードパスを設定する方法を示します。
hello.cpp :
#include <print>#include "hello.hpp"int main () { for ( int i = 0 ; i < TIMES ; ++ i ) { std :: println ( "Hello, world!" ); } return 0 ; }hello.hpp :
#pragma onceconstexpr int TIMES = 10 ;CMakeLists.txt :
cmake_minimum_required ( VERSION 3.22 ) project ( HelloWorld CXX ) add_executable ( hello hello.cpp ) target_include_directories ( hello PRIVATE ${ PROJECT_SOURCE_DIR } )