128

Makefiles ( make) とCMakeLists.txt( ) の両方が同じことを行うサンプル コードがあるかどうか疑問に思ってcmakeいました (唯一の違いは、一方が に記述されmake、もう一方が に記述されていることですcmake)。

「cmake vs make」を探してみましたが、コードの比較は見つかりませんでした。たとえ単純なケースであっても、違いを理解することは本当に役に立ちます。

4

3 に答える 3

128

次の Makefile はprog、ソースから 指定された実行可能ファイルをビルドしますprog1.c, prog2.c, prog3.c and main.cprogに対してリンクされて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.txtMakefile との類似点を強調するコメントを付けて (ほぼ) まったく同じことを行う を次に示します。

#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 など) が移植可能な方法で組み込まれると、真に輝き始めます。

  • makeMakefile を使用する場合、ビルド プロセスには、コマンド ラインで入力する 1 つのステップがあります。CMake の場合、2 つの手順があります。最初に、ビルド環境をセットアップする必要があります (cmake <source_dir>ビルド ディレクトリに入力するか、GUI クライアントを実行します)。これにより、選択したビルド システムに応じて、Makefile または同等のものが作成されます (例: Unix または VC++ では make、Windows では MinGW + Msys)。ビルド システムはパラメーターとして CMake に渡すことができます。ただし、CMake は、システム構成に応じて適切なデフォルトの選択を行います。次に、選択したビルド システムで実際のビルドを実行します。

ソースとビルド手順は、https://github.com/rhoelzel/make_cmakeで入手できます。

于 2013-10-09T08:06:30.630 に答える
7

ビルドシステムとして CMake を使用するソフトウェアをいくつか入手してください (例として選択できるオープンソース プロジェクトはたくさんあります)。ソース コードを取得し、CMake を使用して構成します。結果のmakefileを読んで楽しんでください。

これらのツールは 1 対 1 でマッピングされないことに注意してください。最も明白な違いは、CMake は異なるファイル (C ヘッダーとソース ファイルなど) 間の依存関係をスキャンするのに対し、make はそれを makefile の作成者に任せていることです。

于 2012-06-11T17:53:11.430 に答える