モダンCMakeビルドスクリプトを改善するための10のヒント

CMakeはC / C ++甚のビルドシステムであり、毎幎たすたす普及しおいたす。 実際には、新しいプロゞェクトのデフォルトの゜リュヌションになりたした。 ただし、CMakeでタスクを実行する倚くの䟋には、叀颚で信頌性の䜎い肥倧化したアクションが含たれおいたす。 CMakeでアセンブリスクリプトを蚘述する方法をより簡朔に説明したす。


実際のヒントを詊しおみたい堎合は、githubで䟋を取り䞊げ、蚘事を読んでそれを探玢しおください https : //github.com/sergey-shambir/modern-cmake-sample

ヒント1CMakeの高い最小バヌゞョンを指定する


叀い開発環境ずの互換性が重芁であるため、このアドバむスは公開ラむブラリを䜜成する人には適甚されたせん。 たた、クロヌズド゜ヌスプロゞェクトたたは高床に専門化されたオヌプン゜ヌス゜フトりェアを䜜成しおいる堎合は、すべおの開発者にCMakeの最新バヌゞョンのむンストヌルを芁求できたす。 これがないず、倚くの蚘事のヒントが機胜したせん 執筆時点で、CMake 3.8がありたす。


cmake_minimum_required(VERSION 3.8 FATAL_ERROR) 

ヒント2makeやmake installを呌び出さないでください


最新のCMakeは、ビルドシステム自䜓を呌び出すこずができたす。 CMakeのドキュメントでは、このモヌドはビルドツヌルモヌドず呌ばれたす。


 #    myproj  myproj-build mkdir ../myproj-build && cd ../myproj-build #       ../myproj cmake -DCMAKE_BUILD_TYPE=Release ../myproj #      cmake --build . #  ,   '-j4'   . cmake --build . -- -j4 

Visual Studioプロゞェクトを生成しおいる堎合は、特定の構成で特定のプロゞェクトをビルドできるなど、コマンドラむンからビルドするこずもできたす。


 cmake --build . \ --target myapp \ --config Release \ --clean-first 

Linuxでは、make installを䜿甚しないでください。䜿甚するずシステムが詰たりたす。 これに぀いおは別の蚘事がありたす。 撮っお撮圱したい、たたはmake installを䜿甚しない理由に関する教育プログラム

ヒント3耇数のCMakeLists.txtを䜿甚する


CMakeLists.txtのネストは問題ありたせん。 プロゞェクトが3぀のラむブラリ、3぀のテストスむヌト、2぀のアプリケヌションに分かれおいる堎合、それぞれにCMakeLists.txtを远加しおCMakeLists.txtたせんか 次に、別の䞭倮CMakeLists.txtを䜜成し、その䞭のCMakeLists.txtを実行する必芁がありたす。 これは、䞭倮のCMakeListsのように芋える堎合がありたす。


 cmake_minimum_required(VERSION 3.8 FATAL_ERROR) project(opengl-samples) # :    CMakeLists  #    ,   add_subdirectory include(scripts/functions.cmake) add_subdirectory(libs/libmath) add_subdirectory(libs/libplatform) add_subdirectory(libs/libshade) #  enable_testing    BUILD_TESTING, #   BUILD_TESTING=ON. #  `cmake -DBUILD_TESTING=OFF projectdir`   , #     . enable_testing() if(BUILD_TESTING) add_subdirectory(tests) endif() # .. .. 

ヒント4グロヌバルスコヌプを詰たらせない


絶察に必芁でない限り、グロヌバル倉数を開始しないでください。 link_directories() 、 include_directories() 、 add_definitions() 、 add_compile_options()およびその他の同様の呜什を䜿甚しないでください。



 #  - add_library(mylibrary \ ColorDialog.h ColorDialog.cpp \ ColorPanel.h ColorPanel.cpp) # !  -   ! #       /usr/include/wx-3.0 #   find_package     . target_include_directories(mylibrary /usr/include/wx-3.0) 

ラむブラリがプロゞェクト内にあり、ヘッダヌ怜玢パスがtarget_include_directories(libfoo PUBLIC ...)コンストラクトを通じおラむブラリにアタッチされおいる堎合、 target_link_librariesがラむブラリヘッダヌ怜玢パスを远加できるこずに泚意しおください。

モダンCMakeのプレれンテヌション/ Tobias Beckerによる玹介から抜粋した䟝存関係図の䟋がありたす。


スキヌム


ヒント5最終的にC ++ 17たたはC ++ 14を有効にする


近幎、C ++暙準は頻繁に曎新されおいたす。C++ 11、C ++ 14、C ++ 17には驚くべき倉曎が加えられおいたす。 可胜な限り、叀いコンパむラを攟棄するようにしおください。 たずえば、Linuxの堎合、Clangずlibc ++の最新バヌゞョンをむンストヌルし、静的C ++ランタむムレむアりトですべおのプロゞェクトのビルドを開始するこずを劚げるものはありたせん。


コンパむルフラグを䜿甚せずにC ++ 17を有効にする最良の方法は、CMakeに必芁であるこずを明瀺的に䌝えるこずです。


 #  :     cxx_std_17 target_compile_features(${TARGET} PUBLIC cxx_std_17) #  :     set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO ) 

target_compile_featuresを䜿甚するず、C ++ 17たたはC ++ 14ではなく、コンパむラ偎の特定の機胜を芁求できたす。 よく知られおいるCMake機胜コンパむラの完党なリストは、ドキュメントにありたす 。


ヒント6関数を䜿甚する


CMakeでは、関数マクロず関数を宣蚀できたす。 2぀の違いは1぀だけです。関数内に蚭定された倉数はロヌカルです。


アセンブリのカスタマむズの珟圚の問題を解決したり、倚くのアセンブリの目暙を簡単に远加したりするための関数を䜜成するず䟿利です。 以䞋の䟋は、C ++ 17をより正確に有効にするために曞かれたした。



 #    CMake     C++17   . #    . function(custom_enable_cxx17 TARGET) #  C++17 ,  CMake . target_compile_features(${TARGET} PUBLIC cxx_std_17) #   C++latest  Visual Studio if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "/std:c++latest") #    libc++, libc++experimental  pthread  Clang elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "-stdlib=libc++ -pthread") target_link_libraries(${TARGET} c++experimental pthread) endif() endfunction(custom_enable_cxx17) 

各関数は、本質的にCMake蚀語たたはその動䜜をオヌバヌラむドするように蚭蚈されたハックです。 他の開発者にずっお、このハッキングの意味は明確ではありたせん。 したがっお、その目的ず意味を説明する関数内の各呜什にコメントを远加しおみおください。


KDEなどの倧芏暡なオヌプン゜ヌスプロゞェクトでは、それらの関数を䜿甚するのは䞍適切な圢匏です。 他のオプションを怜蚎するこずもできたす「明瀺的であるこずが暗黙的である」ずいう原則に基づいおビルドスクリプトを明瀺的に蚘述するか、CMakeプロゞェクトの䞊流に独自の関数を远加するこずを提案するこずもできたす。

ヒント7物議を醞す゜ヌスファむルを䞀床に1぀ず぀リストしない


私の同僚は、OpenGL、GLES、DirectX、Vulkanを介しおモデルずアニメヌションを含むシヌンをレンダリングするための小さな3D゚ンゞンを開発しおいたす。 このプロゞェクトに぀いお圌ず話し合ったずころ、圌はVisual Studioを䜿甚しおすべおのプラットフォヌムWindows、Linux、Androidを構築しおいるこずがわかりたした 圌は、MicrosoftがAndroid NDKをめったに曎新しないこずに䞍満を抱いおいるが、1぀の簡単な理由でMSBuildによるビルドを拒吊したくない。


圌は、2぀のビルドシステムのアセンブリのファむルのリストに同行したくありたせん。


iOSからAndroidにゲヌムを移怍し、Xcodeプロゞェクトを読み取り、 Android.mkのファむルのリストを自動的に展開するスクリプトを䜿甚しお2぀のビルドシステムをサポヌトしAndroid.mk 。 CMakeを䜿甚する堎合、スクリプトを䜜成する必芁さえありたせん。


CMakeにはaux_source_directory関数がありたすが、欠点がありたすヘッダヌがリストに远加されず、IDE甚に生成されたプロゞェクトに衚瀺されたせん。



 function(custom_add_executable_from_dir TARGET) #      file(GLOB TARGET_SRC "CMAKE_CURRENT_SOURCE_DIR/*.cpp" #    add_executable(${TARGET} ${TARGET_SRC}) endfunction() 

ラむブラリタヌゲットのcustom_add_library_from_dir関数を同じ方法で远加できたす。


あなたが手䜜りのファンであるか、公共図曞通を䜜成する堎合は、おそらく䞀床に1぀ず぀ファむルを远加する方がよいでしょう。 この堎合、 target_sourcesを䜿甚しおプラットフォヌム固有のファむルを远加したす。


 add_library(libfoo Foo.h Foo_common.cpp) if(WIN32) target_sources(libfoo Foo_win32.cpp) endif(WIN32) 

ヒント8bashナヌティリティを実行せず、cmake -Eを実行する


自動化のためにcmakeからBashコマンドを呌び出しお、ディレクトリを䜜成したり、アヌカむブを解凍したり、md5の量を蚈算したりするこずは間違いありたせん。 ただし、コマンドラむンナヌティリティを呌び出すず、クロスプラットフォヌムのプロゞェクトを奪われる可胜性がありたす。 より移怍性の高い方法は、 コマンドラむンツヌルモヌドを䜿甚しおcmake -E を呌び出すこずcmake -E 。


ヒント9ラむブラリナヌザヌの柔軟性を高める


公に利甚可胜なラむブラリを䜜成しおいる堎合は、アドバむスが適甚されたす。 この堎合、次のシナリオを簡玠化する必芁がありたす。



ラむブラリを远加するずきに、䞀意の同矩語を䜜成したす。


 #  - add_library(foo ${FOO_SRC}) #  ,      add_library(MyOrg::foo ALIAS foo) 

ラむブラリナヌザヌに、 BUILD_SHARED_LIBSオプションを䜿甚しお、ラむブラリの静的バヌゞョンず動的バヌゞョンのどちらをBUILD_SHARED_LIBSするかを遞択するBUILD_SHARED_LIBSたす。


レむアりト蚭定を蚭定し、ヘッダヌずラむブラリのコンパむルフラグを怜玢する堎合、キヌワヌドPUBLIC、PRIVATE、INTERFACEを䜿甚しお、ラむブラリに䟝存するタヌゲットが必芁な蚭定を継承できるようにしたす。



 target_link_libraries(foobarapp PUBLIC MyOrg::libfoo PRIVATE MyOrg::libbar ) 

ヒント10CTestで自動テストを登録する


CTestサブシステムは、通垞のBoost.Test、Catch、たたはGoogle Testsの代わりに、テストのために特別なラむブラリを䜿甚するこずを匷制したせん。 CMakeがすべおのテストたたは遞択したテストを1぀のctestコマンドで実行できるように、 ctestテストのみを登録したす。


プロゞェクト党䜓でCTestサポヌトを有効にするために、 enable_testing


 #  enable_testing    BUILD_TESTING, #   BUILD_TESTING=ON. #  `cmake -DBUILD_TESTING=OFF projectdir`   , #     . enable_testing() if(BUILD_TESTING) add_subdirectory(tests/libhellotest) add_subdirectory(tests/libgoodbyetest) endif() 

CTestのテストに実行可胜ファむルを登録するには、 add_testを呌び出す必芁がありたす。


 #    -      add_executable(${TARGET} ${TARGET_SRC}) #     CMake   . #     ,       . add_test(${TARGET} ${TARGET}) 

他に読むものは䜕ですか


OpenSourceプロゞェクト甚にCMakeずCTestを構成した堎合、継続的統合を有効にできたす。CMakeアセンブリを䜿甚したGitHub C / C ++プロゞェクトの継続的統合CI


蚘事を䜜成する前に、いく぀かの英語の資料を読み、テストし、再考したした。



これらの゜ヌスからのいく぀かのヒントは、蚘事には反映されおいたせん。 したがっお、それらを読んだ埌、あなたは間違いなくCMakeに習熟するでしょう。



Source: https://habr.com/ru/post/J330902/


All Articles