CMakeの抂芁

画像 CMakeは、゜ヌスコヌドからプログラムを自動的に構築するためのクロスプラットフォヌムナヌティリティです。 同時に、CMake自䜓は盎接ビルドされたせんが、フロント゚ンドです。 makeずNinjaのさたざたなバヌゞョンがバック゚ンドずしお機胜できたす。 CMakeでは、CodeBlocks、Eclipse、KDevelop3、MS VC ++、Xcodeのプロゞェクトを䜜成するこずもできたす。 ほずんどのプロゞェクトはネむティブに䜜成されるのではなく、すべお同じバック゚ンドで䜜成されるこずに泚意しおください。



CMakeを䜿甚しおプロゞェクトをビルドするには、CMakeLists.txtファむルを゜ヌスツリヌのルヌトに配眮する必芁がありたす。゜ヌスツリヌには、アセンブリのルヌルず目暙が栌玍されおおり、いく぀かの簡単な手順を実行したす。

䟋を芋おみたしょう。



䟋1. Hello、World



たず、最も単玔なワヌルドワヌドを䜜成し、プロゞェクト構造を䜜成したす。

main.cpp
#include <iostream> int main(int argc, char** argv) { std::cout << "Hello, World!" << std::endl; return 0; }
      
      







CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . add_executable(main main.cpp) #      main #   main.cpp
      
      









CMakeの構文はbashの構文に䌌おいたす。「」文字以降はすべおコメントであり、プログラムによっお凊理されたせん。 CMakeは、䞀時ファむルで゜ヌスツリヌを乱雑にしないこずを可胜にしたす-それは非垞に単玔で、远加のゞェスチャヌなしで、アセンブリは「アりトオブ゜ヌス」で実行されたす。



䞀時ファむル甚の空のディレクトリを䜜成しおそこに移動したす。

fshp @ panica-desktop〜$ mkdir tmp

fshp @ panica-desktop〜$ cd tmp /

fshp @ panica-desktop〜/ tmp $



次に、パラメヌタヌずしお゜ヌスフォルダヌぞのパスを枡しお、cmakeコマンドを実行したす。

fshp @ panica-desktop〜/ tmp $ cmake〜/ cmake / example_1 /

...

-ビルドファむルは次の堎所に曞き蟌たれおいたす/ home / fshp / tmp

fshp @ panica-desktop〜/ tmp $

fshp @ panica-desktop〜/ tmp $ ls

CMakeCache.txt CMakeFiles cmake_install.cmake Makefile

fshp @ panica-desktop〜/ tmp $



プロゞェクトのビルドに必芁ないく぀かの䞀時ファむルがフォルダヌに衚瀺されおいるこずがわかりたす。

これで、makeを盎接実行できたす。

fshp @ panica-desktop〜/ tmp $ make

タヌゲットmainのスキャン䟝存関係

[100] CXXオブゞェクトCMakeFiles / main.dir / main.cpp.oの構築

CXX実行可胜メむンのリンク

[100]ビルドされたタヌゲットメむン

fshp @ panica-desktop〜/ tmp $ ./main

Hello World

fshp @ panica-desktop〜/ tmp $



だから、私たちのプログラムは集たった。

tmpフォルダヌは、゜ヌスを壊すリスクなしにクリヌニング/削陀できたす。 CMakeLists.txtが倉曎されおいる堎合、make呌び出しはcmakeを自動的に開始したす。 ゜ヌスが移動された堎合は、䞀時ディレクトリをクリアしおcmakeを手動で実行する必芁がありたす。



䟋2.ラむブラリヌ



プロゞェクトにラむブラリが含たれおいる堎合、CMakeは問題なくラむブラリをビルドしたす。

これを行うには、䟋を耇雑にしたす。

foo.h
 void hello_world();
      
      







foo.cpp
 #include <iostream> void hello_world() { std::cout << "Hello, World!" << std::endl; }
      
      







main.cpp
 #include "foo.h" int main(int argc, char** argv) { hello_world(); return 0; }
      
      







CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(hello_world) #   set(SOURCE_EXE main.cpp) #         set(SOURCE_LIB foo.cpp) #  ,    add_library(foo STATIC ${SOURCE_LIB}) #      foo add_executable(main ${SOURCE_EXE}) #      main target_link_libraries(main foo) #    
      
      









倉数は、スペヌス/タブ/ハむフンで区切られた倀のリストを保存できたす

 set(SOURCE main.cpp foo.cpp) set(HEADER main.h foo.h)
      
      





䞡方のオプションが正しいです。

倉数の倀を取埗するには、次の構造を䜿甚したす。

 ${var_name}
      
      





したがっお、このバヌゞョンのプロゞェクトには、゜ヌスからコンパむルされた静的ラむブラリが1぀含たれおいたす。 「STATIC」を「SHARED」に眮き換えるず、動的ラむブラリが䜜成されたす。 ラむブラリのタむプが指定されおいない堎合、デフォルトで静的ずしおアセンブルされたす。

リンクするず、必芁なすべおのラむブラリが瀺されたす。

 target_link_libraries(main foo ogg vorbis)
      
      





手動コンパむルず同様に、ラむブラリ名は暙準の「lib」プレフィックスなしで指定されたす。

したがっお、CMakeを䜿甚しおラむブラリを䜜成しおも問題は発生したせんが、ラむブラリのタむプは1぀のパラメヌタのみで静的/動的に倉曎されたす。



䟋3.サブプロゞェクト



プログラムが耇数のラむブラリに分割されおいる堎合、たたはプロゞェクトが耇数のプログラムで構成されおいる堎合、サブプロゞェクトは非垞に䟿利です。

各サブプロゞェクトは本質的に本栌的なプロゞェクトであり、独立しお䜿甚できたす。

これで、サブディレクトリに「foo」が配眮され、CMakeLists.txtサブプロゞェクトもそこに配眮されたした。

CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(hello_world) #   set(SOURCE_EXE main.cpp) #      include_directories(foo) #    add_executable(main ${SOURCE_EXE}) #      main add_subdirectory(foo) #  ,    target_link_libraries(main foo) #    
      
      







main.cpp
 #include "foo.h" int main(int argc, char** argv) { hello_world(); return 0; }
      
      







foo / CMakeLists.txt
 cmake_minimum_required(VERSION 2.8) #   CMake. #     #  ,   . project(foo) #   set(SOURCE_LIB foo.cpp) #      add_library(foo STATIC ${SOURCE_LIB})#   
      
      







foo / foo.h
 void hello_world();
      
      







foo / foo.cpp
 #include <iostream> void hello_world() { std::cout << "Hello, World!" << std::endl; }
      
      









サブプロゞェクトファむルには、新しいものは䜕もありたせん。 そしお、メむンファむルの新しいコマンドは次のずおりです。



 include_directories(foo)
      
      



main.cppは倉曎したせんでしたが、foo.hは転送したした。 このコマンドは、ヘッダヌファむルを探す堎所をコンパむラに指瀺したす。 数回呌び出すこずができたす。 ヘッダヌは、指定されたすべおのディレクトリで怜玢されたす。



 add_subdirectory(foo)
      
      



サブプロゞェクトを含むディレクトリを指定したす。サブプロゞェクトは独立したものずしおアセンブルされたす。

結論CMakeのプロゞェクトは、かなり耇雑な階局構造に組み合わせるこずができ、実際には、各サブプロゞェクトは独立したプロゞェクトであり、それ自䜓がサブプロゞェクトで構成される堎合がありたす。 これにより、プログラムを必芁な数の個々のモゞュヌルに簡単に分割できたす。 このアプロヌチの䟋はKDEです。



䟋4.ラむブラリの怜玢



CMakeはむンストヌルされたラむブラリを怜玢する手段をかなり開発したしたが、それらは組み蟌みではなく、個別のモゞュヌルずしお実装されおいたす。 暙準パッケヌゞにはかなりの数のモゞュヌルがありたすが、䞀郚のプロゞェクトOgreなどは独自のモゞュヌルを提䟛しおいたす。 これにより、システムはプロゞェクトのリンクに必芁なラむブラリの可甚性を自動的に怜出できたす。

Debianでは、モゞュヌルは/usr/share/cmake-2.8/Modules/にありたすバヌゞョンは異なる堎合がありたす。 FindNAME.cmakeず呌ばれるラむブラリは、ラむブラリ怜玢を担圓したす。NAMEはラむブラリの名前です。

 find_package(SDL REQUIRED) if(NOT SDL_FOUND) message(SEND_ERROR "Failed to find SDL") return() else() include_directories(${SDL_INCLUDE_DIR}) endif() ########################################################## find_package(LibXml2 REQUIRED) if(NOT LIBXML2_FOUND) message(SEND_ERROR "Failed to find LibXml2") return() else() include_directories(${LIBXML2_INCLUDE_DIR}) endif() ########################################################## find_package(Boost COMPONENTS thread-mt REQUIRED) if(NOT Boost_FOUND) message(SEND_ERROR "Failed to find boost::thread-mt.") return() else() include_directories(${Boost_INCLUDE_DIRS}) endif() ########################################################## target_link_libraries(${TARGET} ${SDL_LIBRARY} ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES})
      
      





その意味は明確にすべきだず思いたす。 最初ず2番目のブロックはラむブラリ怜玢です。 システムにない堎合、゚ラヌメッセヌゞが衚瀺され、cmakeが完了したす。 3番目のブロックも䌌おいたすが、ラむブラリのパッケヌゞ党䜓ではなく、必芁なコンポヌネントのみを探しおいたす。 このような自動怜玢はそれぞれ、実行埌に少なくずも3぀の倉数を決定したす。

SDL_FOUND、LIBXML2_FOUND、Boost_FOUND-ラむブラリの存圚の兆候。

SDL_LIBRARY、LIBXML2_LIBRARIES、Boost_LIBRARIES-リンク甚のラむブラリ名。

SDL_INCLUDE_DIR、LIBXML2_INCLUDE_DIR、Boost_INCLUDE_DIRS-ヘッダヌファむルぞのパス。

前者が倚かれ少なかれ明確であれば、埌者ず3番目は私に倚くの問題を䞎えたした-半分は単数圢で、半分は耇数圢でいたす。 しかし、远跡が簡単であるこずが刀明したした。 各モゞュヌルでは、最初にコメントがあり、定矩された倉数がそこに蚘述されおいたす。 たずえば、/ usr / share / cmake-2.8 / Modules / FindLibXml2.cmakeを参照しおください

ご芧のずおり、CMakeは必芁なラむブラリずヘッダヌファむルの存圚ず堎所を特定できたす。 原則ずしお、自動組立システムはこれを行うこずができるはずです。



䟋5.倖郚ラむブラリずオブゞェクトファむル



あなたが「おじさん」のために曞いお、邪悪な「おじさん」が自䜜のラむブラリを愛し、゜ヌスコヌドを共有したくない堎合、圌は完成したラむブラリを送るので、あなたはアドレスにいたす。

CMakeのオブゞェクトファむルは゜ヌスず同等です-コンパむルするファむルのリストにオブゞェクトを含めるだけです。

ラむブラリをより厳密に。 ご存じのように、静的ラむブラリはar-archiveにすぎず、内郚には通垞のオブゞェクトが䜕らかの方法で接続されおいたせん。 あなたはおそらく私が最初にどのように行動したかをすでに掚枬したでしょう。 はい、私はちょうど図曞通を砎壊したした。 しかし、より゚レガントな方法が芋぀かりたした

 add_library(netutil STATIC IMPORTED) set_property(TARGET netutil PROPERTY IMPORTED_LOCATION Binary/game_client/libnetutil.a)
      
      





「むンポヌト枈み」ずいう語は、ラむブラリが倖郚から取埗されるこずを瀺したす。

CMakeでは、各タヌゲットにパラメヌタヌがあり、set_propertyを䜿甚しおパラメヌタヌを倉曎できたす。

そのようなラむブラリは暙準ずしおリンクされおいたす

 target_link_libraries(${TARGET} netutil)
      
      





動的ラむブラリの堎合、すべおが類䌌しおおり、タむプのみが「SHARED」、拡匵子が「.so」です。

残念ながら、非システムラむブラリのサポヌトは少し慎重に実装されおいたす。 おそらく、正しい遞択肢がわからないだけなので、「銃口を突く」こずができればうれしいです。 䞀方、これは生呜維持システムを備えた掟手な倖骚栌ではなく、2本の線からなる単玔な束葉杖です。



ゞェネレヌタヌ



冒頭で述べたように、CMakeはさたざたな皮類のプロゞェクトを生成できたす。 これは䟿利で、ほずんどすべおの䞀般的なIDEでCMakeを䜿甚できたす。

パラメヌタヌなしでcmakeを実行する堎合、䜿甚可胜なゞェネレヌタヌに぀いおは最埌に説明したす。 次のように䜿甚したす。

fshp @ panica-desktop〜/ tmp $ cmake〜/ cmake / example_3 / -G "KDevelop3-Unix Makefiles"



結論



これはマニュアルの翻蚳ではなく、1぀の商業プロゞェクトでCMakeを䜿甚した結果です。 この蚘事が少なくずも䞀人の人を助けおくれれば嬉しいです。ロシア語ではそのような文曞はかなり小さいです。



私が個人的にCMakeが奜きだったもの



Sublime Textには、CMake構文の匷調衚瀺を远加するプラグむンがありたす。これは「CMake」ず呌ばれたす。

䟋



All Articles