CMakeの目的は何ですか?
ウィキペディアによると:
CMakeは、コンパイラに依存しない方法を使用してソフトウェアのビルドプロセスを管理するための[...]ソフトウェアです。複数のライブラリに依存するディレクトリ階層とアプリケーションをサポートするように設計されています。make、AppleのXcode、Microsoft Visual Studioなどのネイティブビルド環境と組み合わせて使用されます。
CMakeを使用すると、コンパイラ/ビルド環境に固有の個別の設定を維持する必要がなくなります。あなたは持っている1つの構成を、そしてそのために働く多くの環境。
CMakeは、何も変更せずに同じファイルからMicrosoft Visual Studioソリューション、Eclipseプロジェクト、またはMakefile迷路を生成できます。
CMakeは、コードが含まれている多数のディレクトリがある場合、プロジェクトをコンパイルする前に、プロジェクトに必要なすべての依存関係、ビルド順序、その他のタスクを管理します。実際には何もコンパイルしません。CMakeを使用するには、(CMakeLists.txtと呼ばれる構成ファイルを使用して)コンパイルする必要がある実行可能ファイル、リンクするライブラリ、プロジェクト内のディレクトリとその中にあるもの、およびフラグなどの詳細を指示する必要がありますまたは必要な他のもの(CMakeは非常に強力です)。
これが正しく設定されている場合は、CMakeを使用して、選択した「ネイティブビルド環境」がその作業を行うために必要なすべてのファイルを作成します。Linuxでは、デフォルトでMakefileを意味します。したがって、CMakeを実行すると、独自に使用するためのファイルといくつかMakefile
のsのファイルが作成されます。その後、コードの編集が完了するたびに、ルートフォルダーからコンソールに「make」と入力するだけで、コンパイルおよびリンクされた実行可能ファイルが作成されます。
CMakeはどのように機能しますか?それは何をするためのものか?
以下は、私が全体的に使用するプロジェクトのセットアップ例です。
simple/
CMakeLists.txt
src/
tutorial.cxx
CMakeLists.txt
lib/
TestLib.cxx
TestLib.h
CMakeLists.txt
build/
各ファイルの内容を示し、後で説明します。
CMakeは、プロジェクトのルート に従ってプロジェクトをセットアップし、コンソールでCMakeLists.txt
実行cmake
したディレクトリにセットアップします。プロジェクトのルートではないフォルダーからこれを行うと、いわゆるアウトオブソースビルドが生成されます。つまり、コンパイル中に作成されたファイル(objファイル、libファイル、実行可能ファイルなど)は、そのフォルダーに配置されます、実際のコードとは別に保管します。これは混乱を減らすのに役立ち、他の理由からも推奨されます。
cmake
ルート以外で実行するとどうなるかわかりませんCMakeLists.txt
。
この例では、すべてをbuild/
フォルダー内に配置したいので、まずそこに移動してから、ルートがCMakeLists.txt
存在するディレクトリにCMakeを渡します。
cd build
cmake ..
デフォルトでは、これは私が言ったようにMakefileを使用してすべてを設定します。ビルドフォルダーは次のようになります。
simple/build/
CMakeCache.txt
cmake_install.cmake
Makefile
CMakeFiles/
(...)
src/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
lib/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
これらのファイルはすべて何ですか? 心配する必要があるのは、Makefileとプロジェクトフォルダだけです。
src/
とlib/
フォルダに注意してください。これらはsimple/CMakeLists.txt
、コマンドを使用してポイントするために作成されましたadd_subdirectory(<folder>)
。このコマンドは、CMakeに別のCMakeLists.txt
ファイルを探してそのフォルダーを調べ、そのスクリプトを実行するように指示します。そのため、この方法で追加されたすべてのサブディレクトリには、ファイルが含まれている必要がありCMakeLists.txt
ます。このプロジェクトでsimple/src/CMakeLists.txt
は、実際の実行可能ファイルsimple/lib/CMakeLists.txt
を構築する方法とライブラリを構築する方法について説明します。がCMakeLists.txt
記述するすべてのターゲットは、デフォルトでビルドツリー内のサブディレクトリに配置されます。だから、簡単に
make
から実行されるコンソールでbuild/
、いくつかのファイルが追加されます:
simple/build/
(...)
lib/
libTestLib.a
(...)
src/
Tutorial
(...)
プロジェクトがビルドされ、実行可能ファイルを実行する準備ができました。実行可能ファイルを特定のフォルダに入れたい場合はどうしますか? 適切なCMake変数を設定するか、特定のターゲットのプロパティを変更します。CMake変数については後で詳しく説明します。
CMakeにプロジェクトのビルド方法を伝えるにはどうすればよいですか?
以下に、ソースディレクトリ内の各ファイルの内容を説明します。
simple/CMakeLists.txt
:
cmake_minimum_required(VERSION 2.6)
project(Tutorial)
# Add all subdirectories in this project
add_subdirectory(lib)
add_subdirectory(src)
必要でない場合にCMakeがスローする警告に従って、最低限必要なバージョンを常に設定する必要があります。CMakeのバージョンが何であれ使用します。
プロジェクトの名前は後で使用でき、同じCMakeファイルから複数のプロジェクトを管理できるという事実へのヒントになります。ただし、詳しくは説明しません。
前述のように、add_subdirectory()
プロジェクトにフォルダを追加します。つまり、CMakeはそれがCMakeLists.txt
内部にあることを期待し、続行する前に実行されます。ちなみに、CMake関数が定義されている場合はCMakeLists.txt
、サブディレクトリの他のから使用できますが、使用する前に定義するadd_subdirectory()
必要があります。そうしないと、見つかりません。CMakeはライブラリについてはより賢いので、この種の問題に遭遇するのはおそらくこのときだけです。
simple/lib/CMakeLists.txt
:
add_library(TestLib TestLib.cxx)
独自のライブラリを作成するには、ライブラリに名前を付けて、それから作成されたすべてのファイルをリストします。簡単です。foo.cxx
コンパイルするために別のファイルが必要な場合は、代わりにを記述しadd_library(TestLib TestLib.cxx foo.cxx)
ます。これは、たとえば、他のディレクトリにあるファイルでも機能しますadd_library(TestLib TestLib.cxx ${CMAKE_SOURCE_DIR}/foo.cxx)
。後でCMAKE_SOURCE_DIR変数について詳しく説明します。
これで実行できるもう1つのことは、共有ライブラリが必要であることを指定することです。例:add_library(TestLib SHARED TestLib.cxx)
。恐れる必要はありません。ここでCMakeがあなたの人生を楽にし始めます。共有されているかどうかにかかわらず、この方法で作成されたライブラリを使用するために処理する必要があるのは、ここで指定した名前だけです。このライブラリの名前はTestLibになり、プロジェクトのどこからでも参照できます。CMakeはそれを見つけます。
依存関係をリストするより良い方法はありますか? 間違いなくはい。これについて詳しくは、以下をチェックしてください。
simple/lib/TestLib.cxx
:
#include <stdio.h>
void test() {
printf("testing...\n");
}
simple/lib/TestLib.h
:
#ifndef TestLib
#define TestLib
void test();
#endif
simple/src/CMakeLists.txt
:
# Name the executable and all resources it depends on directly
add_executable(Tutorial tutorial.cxx)
# Link to needed libraries
target_link_libraries(Tutorial TestLib)
# Tell CMake where to look for the .h files
target_include_directories(Tutorial PUBLIC ${CMAKE_SOURCE_DIR}/lib)
コマンドadd_executable()
はとまったく同じように機能しますが、add_library()
もちろん、代わりに実行可能ファイルが生成されます。この実行可能ファイルは、などのターゲットとして参照できるようになりましたtarget_link_libraries()
。tutorial.cxxはTestLibライブラリにあるコードを使用するので、次のようにCMakeを指すようにします。
同様に、ソースと同じディレクトリにないソースに含まれadd_executable()
ている.hファイルは、何らかの方法で追加する必要があります。コマンド用でない場合、チュートリアルのコンパイル時に見つかりません。そのため、#includesを検索するために、フォルダー全体がインクルードディレクトリに追加されます。すべての実行可能ファイルに対してグローバルに設定するため、ターゲットを指定する必要がないことを除いて、同様に機能するコマンドが表示される場合もあります。もう一度、CMAKE_SOURCE_DIRについては後で説明します。target_include_directories()
lib/TestLib.h
lib/
include_directories()
simple/src/tutorial.cxx
:
#include <stdio.h>
#include "TestLib.h"
int main (int argc, char *argv[])
{
test();
fprintf(stdout, "Main\n");
return 0;
}
「TestLib.h」ファイルがどのように含まれているのかに注意してください。完全なパスを含める必要はありません。CMakeは、のおかげですべてを裏で処理しtarget_include_directories()
ます。
技術的にはあなたがなしで行うことができ、このような単純なソースツリーに言えば、CMakeLists.txt
下のlib/
とsrc/
、ちょうどのようなもの追加することadd_executable(Tutorial src/tutorial.cxx)
にしsimple/CMakeLists.txt
。それはあなたとあなたのプロジェクトのニーズ次第です。
CMakeを適切に使用するために他に知っておくべきことはありますか?
(あなたの理解に関連するAKAトピック)
パッケージを見つけて使用する:この質問への答えは、私がこれまでにないほどよく説明しています。
変数と関数の宣言、制御フローの使用など:CMakeが提供する必要があるものの基本を説明するこのチュートリアルをチェックしてください。
CMake変数:たくさんありますので、正しい道に進むためのクラッシュコースを次に示します。CMake wikiは、変数や表面上は他のものについてのより詳細な情報を入手するのに適した場所です。
ビルドツリーを再構築せずに一部の変数を編集することができます。これにはccmakeを使用します(CMakeCache.txt
ファイルを編集します)。c
変更が完了したらonfigureを実行g
し、更新された構成でmakefile を列挙することを忘れないでください。
以前に参照したチュートリアルを読んで、変数の使用について学習しますが、簡単に言えば
set(<variable name> value)
、変数を変更または作成します。
${<variable name>}
それを使用する。
CMAKE_SOURCE_DIR
:ソースのルートディレクトリ。前の例では、これは常に/simple
CMAKE_BINARY_DIR
:ビルドのルートディレクトリ。前の例では、これはと同じですがsimple/build/
、cmake simple/
などのフォルダから実行した場合、そのビルドツリー内のfoo/bar/etc/
すべての参照CMAKE_BINARY_DIR
はになり/foo/bar/etc
ます。
CMAKE_CURRENT_SOURCE_DIR
:現在のディレクトリCMakeLists.txt
です。つまり、全体が変化します。これをsimple/CMakeLists.txt
yields /simple
から出力し、simple/src/CMakeLists.txt
yields から出力します/simple/src
。
CMAKE_CURRENT_BINARY_DIR
:あなたはアイデアを得ます。このパスは、ビルドがあるフォルダだけでなく、現在のCMakeLists.txt
スクリプトの場所にも依存します。
なぜこれらが重要なのですか?ソースファイルは明らかにビルドツリーにはありません。target_include_directories(Tutorial PUBLIC ../lib)
前の例のようなものを試した場合、そのパスはビルドツリーからの相対パスになります。つまり${CMAKE_BINARY_DIR}/lib
、のようになり、内部を調べますsimple/build/lib/
。そこには.hファイルがありません。多くてもあなたは見つけるでしょうlibTestLib.a
。${CMAKE_SOURCE_DIR}/lib
代わりにしたいです。
CMAKE_CXX_FLAGS
:コンパイラー(この場合はC ++コンパイラー)に渡すフラグ。注目に値するのはCMAKE_CXX_FLAGS_DEBUG
、がCMAKE_BUILD_TYPE
DEBUGに設定されている場合に代わりに使用されることです。これらのようなものがあります。CMake wikiをチェックしてください。
CMAKE_RUNTIME_OUTPUT_DIRECTORY
:ビルド時にすべての実行可能ファイルを配置する場所をCMakeに指示します。これはグローバル設定です。たとえば、これをに設定してbin/
、すべてをきちんと配置できます。EXECUTABLE_OUTPUT_PATH
似ていますが、つまずいた場合に備えて非推奨です。
CMAKE_LIBRARY_OUTPUT_DIRECTORY
:同様に、すべてのライブラリファイルを配置する場所をCMakeに指示するグローバル設定。
ターゲットのプロパティ:実行可能ファイルまたはライブラリ(またはアーカイブ...アイデアが得られます)の1つのターゲットのみに影響するプロパティを設定できます。これを使用する良い例を示します(set_target_properties()
。
ソースをターゲットに自動的に追加する簡単な方法はありますか? GLOBを使用して、特定のディレクトリ内のすべてを同じ変数の下にリストします。構文例はFILE(GLOB <variable name> <directory>/*.cxx)
です。
異なるビルドタイプを指定できますか?はい。ただし、これがどのように機能するか、またはこれの制限についてはわかりません。おそらくいくつかのif / then'ningが必要ですが、CMakeはCMAKE_CXX_FLAGS_DEBUG
、たとえばのデフォルトなど、何も設定せずに基本的なサポートを提供します。CMakeLists.txt
ファイル内からビルドタイプを設定したりset(CMAKE_BUILD_TYPE <type>)
、適切なフラグを使用してコンソールからCMakeを呼び出したりすることができますcmake -DCMAKE_BUILD_TYPE=Debug
。
CMakeを使用するプロジェクトの良い例はありますか?ウィキペディアには、CMakeを使用するオープンソースプロジェクトのリストがあります。これまでのところ、オンラインチュートリアルは私にとって失望に過ぎませんでしたが、このStack Overflowの質問には、かなりクールで理解しやすいCMakeの設定が含まれています。一見の価値があります。
コードでCMakeからの変数を使用する:これは、簡単で汚い例です(他のチュートリアルから適応)。
simple/CMakeLists.txt
:
project (Tutorial)
# Setting variables
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 1)
# Configure_file(<input> <output>)
# Copies a file <input> to file <output> and substitutes variable values referenced in the file content.
# So you can pass some CMake variables to the source code (in this case version numbers)
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_SOURCE_DIR}/src/TutorialConfig.h"
)
simple/TutorialConfig.h.in
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
CMakeによって生成された結果ファイルsimple/src/TutorialConfig.h
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 1
これらを上手に使用すると、ライブラリをオフにするなどのクールなことができます。遅かれ早かれ、大規模なプロジェクトで非常に役立つと思われる少し高度なものがいくつかあるので、このチュートリアルをご覧になることをお勧めします。
それ以外のものについては、Stack Overflowは特定の質問と簡潔な回答で溢れています。これは、初心者を除くすべての人にとって素晴らしいことです。