Makefile
s ( make
) とCMakeLists.txt
( ) の両方が同じことを行うサンプル コードがあるかどうか疑問に思ってcmake
いました (唯一の違いは、一方が に記述されmake
、もう一方が に記述されていることですcmake
)。
「cmake vs make」を探してみましたが、コードの比較は見つかりませんでした。たとえ単純なケースであっても、違いを理解することは本当に役に立ちます。
次の Makefile はprog
、ソースから
指定された実行可能ファイルをビルドしますprog1.c, prog2.c, prog3.c and main.c
。prog
に対してリンクされてlibmystatlib.a
おりlibmydynlib.so
、どちらもソースからビルドされています。さらに、prog
ではライブラリlibstuff.a
を使用し、 ではstuff/lib
そのヘッダーを使用しstuff/include
ます。Makefile はデフォルトでリリース ターゲットをビルドしますが、デバッグ ターゲットも提供します。
#Makefile
CC = gcc
CPP = g++
RANLIB = ar rcs
RELEASE = -c -O3
DEBUG = -c -g -D_DEBUG
INCDIR = -I./stuff/include
LIBDIR = -L./stuff/lib -L.
LIBS = -lstuff -lmystatlib -lmydynlib
CFLAGS = $(RELEASE)
PROGOBJS = prog1.o prog2.o prog3.o
prog: main.o $(PROGOBJS) mystatlib mydynlib
$(CC) main.o $(PROGOBJS) $(LIBDIR) $(LIBS) -o prog
debug: CFLAGS=$(DEBUG)
debug: prog
mystatlib: mystatlib.o
$(RANLIB) libmystatlib.a mystatlib.o
mydynlib: mydynlib.o
$(CPP) -shared mydynlib.o -o libmydynlib.so
%.o: %.c
$(CC) $(CFLAGS) $(INCDIR) $< -o $@
%.o: %.cpp
$(CPP) $(CFLAGS) $(INCDIR) -fPIC $< -o $@
CMakeLists.txt
Makefile との類似点を強調するコメントを付けて (ほぼ) まったく同じことを行う を次に示します。
#CMakeLists.txt
cmake_minimum_required(VERSION 2.8) # stuff not directly
project(example) # related to building
include_directories(${CMAKE_SOURCE_DIR}/stuff/include) # -I flags for compiler
link_directories(${CMAKE_SOURCE_DIR}/stuff/lib) # -L flags for linker
set(PROGSRC prog1.c prog2.c prog3.c) # define variable
add_executable(prog main.c ${PROGSRC}) # define executable target prog, specify sources
target_link_libraries(prog mystatlib mydynlib stuff) # -l flags for linking prog target
add_library(mystatlib STATIC mystatlib.c) # define static library target mystatlib, specify sources
add_library(mydynlib SHARED mydynlib.cpp) # define shared library target mydynlib, specify sources
#extra flags for linking mydynlib
set_target_properties(mydynlib PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
#alternatively:
#set_target_properties(mydynlib PROPERTIES COMPILE_FLAGS "-fPIC")
この単純な例では、最も重要な違いは次のとおりです。
CMake は、どの種類のソースにどのコンパイラを使用するかを認識します。また、ターゲットのタイプごとに適切なコマンド シーケンスを呼び出します。$(CC) ...
したがって、などのコマンドの明示的な指定はありません$(RANLIB) ...
。
ヘッダー ファイル、ライブラリなどのインクルードを処理するすべての通常のコンパイラ/リンカー フラグは、プラットフォームに依存しない/ビルド システムに依存しないコマンドに置き換えられます。
デバッグ フラグは、変数CMAKE_BUILD_TYPE
を「Debug」に設定するか、プログラムの呼び出し時に CMake に渡すことによって含められますcmake -DCMAKE_BUILD_TYPE:STRING=Debug
。
CMake は、プラットフォームに依存しない「-fPIC」フラグ (POSITION_INDEPENDENT_CODE
プロパティ経由) やその他の多くのインクルードも提供します。それでも、CMake や Makefile で (COMPILE_FLAGS
および類似のプロパティを使用して) よりあいまいな設定を手動で実装できます。もちろん、CMake は、サードパーティのライブラリ (OpenGL など) が移植可能な方法で組み込まれると、真に輝き始めます。
make
Makefile を使用する場合、ビルド プロセスには、コマンド ラインで入力する 1 つのステップがあります。CMake の場合、2 つの手順があります。最初に、ビルド環境をセットアップする必要があります (cmake <source_dir>
ビルド ディレクトリに入力するか、GUI クライアントを実行します)。これにより、選択したビルド システムに応じて、Makefile または同等のものが作成されます (例: Unix または VC++ では make、Windows では MinGW + Msys)。ビルド システムはパラメーターとして CMake に渡すことができます。ただし、CMake は、システム構成に応じて適切なデフォルトの選択を行います。次に、選択したビルド システムで実際のビルドを実行します。
ソースとビルド手順は、https://github.com/rhoelzel/make_cmakeで入手できます。
ビルドシステムとして CMake を使用するソフトウェアをいくつか入手してください (例として選択できるオープンソース プロジェクトはたくさんあります)。ソース コードを取得し、CMake を使用して構成します。結果のmakefileを読んで楽しんでください。
これらのツールは 1 対 1 でマッピングされないことに注意してください。最も明白な違いは、CMake は異なるファイル (C ヘッダーとソース ファイルなど) 間の依存関係をスキャンするのに対し、make はそれを makefile の作成者に任せていることです。