Pandan devlopman, mwen renmen chanje konpilateur, bati mòd, vèsyon depandans, fè analiz estatik, mezire pèfòmans, kolekte pwoteksyon, jenere dokiman, elatriye. E mwen vrèman renmen CMake paske li pèmèt mwen fè tout sa mwen vle.
Anpil moun kritike CMake, e souvan merite sa, men si w gade li, se pa tout bagay ki tèlman mal, epi dènyèman. pa mal ditou, ak direksyon devlopman se byen pozitif.
Nan nòt sa a, mwen vle di ou ki jan yo tou senpleman òganize yon bibliyotèk header nan C ++ nan sistèm nan CMake pou jwenn fonksyonalite sa a:
Asanble;
Tès Autorun;
Mezi kouvèti kòd;
Enstalasyon;
Oto-dokimantasyon;
Jenerasyon sandbox sou entènèt;
Analiz estatik.
Nenpòt moun ki deja konprann avantaj yo ak C-fè kapab tou senpleman telechaje modèl pwojè a epi kòmanse sèvi ak li.
Nou pral sitou pale sou ki jan yo òganize scripts CMake, kidonk yo pral diskite an detay. Nenpòt moun ka wè rès fichye yo dirèkteman sou paj pwojè modèl la.
Premye a tout, ou bezwen mande vèsyon ki nesesè nan sistèm CMake la. CMake ap evolye, siyati kòmand ak konpòtman nan diferan kondisyon yo ap chanje. Nan lòd pou CMake imedyatman konprann sa nou vle soti nan li, nou bezwen imedyatman anrejistre kondisyon nou yo pou li.
cmake_minimum_required(VERSION 3.13)
Lè sa a, nou pral deziyen pwojè nou an, non li, vèsyon, lang yo itilize, elatriye (gade. команду project).
Nan ka sa a nou endike lang lan CXX (e sa vle di C++) pou CMake pa souch epi chèche yon du lang C (pa default, CMake gen ladann de lang: C ak C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
Isit la ou ka imedyatman tcheke si pwojè nou an enkli nan yon lòt pwojè kòm yon sou-pwojè. Sa a pral ede anpil nan tan kap vini an.
Premye opsyon a se MYLIB_TESTING — pou enfim tès inite yo. Sa a ka nesesè si nou sèten ke tout bagay an lòd ak tès yo, men nou sèlman vle, pou egzanp, enstale oswa pake pwojè nou an. Oswa pwojè nou an enkli kòm yon subproject - nan ka sa a, itilizatè a nan pwojè nou an pa enterese nan kouri tès nou yo. Ou pa teste depandans ou itilize yo, pa vre?
Anplis de sa, nou pral fè yon opsyon separe MYLIB_COVERAGE pou mezire kouvèti kòd pa tès yo, men li pral mande pou zouti adisyonèl, kidonk li pral bezwen aktive klèman.
Bibliyotèk nou an konsiste sèlman de dosye header, ki vle di nou pa gen okenn echapman sou fòm bibliyotèk estatik oswa dinamik. Nan lòt men an, yo nan lòd yo sèvi ak bibliyotèk nou an deyò, li bezwen yo dwe enstale, li bezwen yo dwe detekte nan sistèm nan ak konekte ak pwojè ou a, ak an menm tan an menm en-tête sa yo, osi byen ke pètèt kèk lòt adisyonèl, yo tache ak li pwopriyete.
Pou rezon sa a, nou kreye yon bibliyotèk koòdone.
add_library(mylib INTERFACE)
Nou mare headers nan bibliyotèk koòdone nou an.
Modèn, alamòd, itilizasyon jèn nan CMake implique ke headers, pwopriyete, elatriye. transmèt atravè yon sèl sib. Se konsa, li sifi pou di target_link_libraries(target PRIVATE dependency), ak tout headers ki asosye ak sib la dependency, yo pral disponib pou sous ki fè pati sib la target. Epi ou pa bezwen okenn [target_]include_directories. Sa a pral demontre anba a nan analiz la CMake script pou tès inite yo.
Kòmandman sa a asosye tèt nou bezwen yo ak bibliyotèk koòdone nou an, epi si bibliyotèk nou an konekte ak nenpòt sib ki nan menm yerachi CMake la, Lè sa a, tèt yo ki soti nan anyè a pral asosye avèk li. ${CMAKE_CURRENT_SOURCE_DIR}/include, epi si bibliyotèk nou an enstale sou sistèm nan epi konekte ak yon lòt pwojè lè l sèvi avèk lòd la find_package, Lè sa a, headers soti nan anyè a pral asosye ak li include parapò ak anyè enstalasyon an.
Ann mete yon estanda lang. Natirèlman, yon sèl la trè dènye. An menm tan an, nou pa sèlman enkli estanda a, men tou, pwolonje li bay moun ki pral sèvi ak bibliyotèk nou an. Sa a se reyalize akòz lefèt ke pwopriyete a mete gen yon kategori INTERFACE (cm. target_compile_features kòmand).
Ann kreye yon alyas pou bibliyotèk nou an. Anplis, pou bote, li pral nan yon espesyal "namespace". Sa a pral itil lè diferan modil parèt nan bibliyotèk nou an, epi nou ale nan konekte yo poukont youn ak lòt. Tankou nan Busta, pou egzanp.
Enstale headers nou yo nan sistèm lan. Tout bagay se senp isit la. Nou di ke katab la ak tout tèt yo ta dwe ale nan anyè a include parapò ak kote enstalasyon an.
Pwochen eple a ta dwe konprann fason sa a. Lè nan yon pwojè twazyèm pati nou rele lòd la find_package(Mylib 1.2.3 REQUIRED), ak vèsyon reyèl la nan bibliyotèk la enstale yo pral enkonpatib ak vèsyon an 1.2.3CMake pral otomatikman jenere yon erè. Sa vle di, ou pa pral bezwen swiv vèsyon manyèlman.
Si tès yo enfim klèman lè l sèvi avèk opsyon ki koresponn lan oswa pwojè nou an se yon sou-pwojè, se sa ki, li konekte ak yon lòt pwojè CMake lè l sèvi avèk lòd la add_subdirectory, nou pa avanse pi lwen sou yerachi a, ak script la, ki dekri kòmandman yo pou jenere ak kouri tès, tou senpleman pa kouri.
if(NOT MYLIB_TESTING)
message(STATUS "Тестирование проекта Mylib выключено")
elseif(IS_SUBPROJECT)
message(STATUS "Mylib не тестируется в режиме подмодуля")
else()
add_subdirectory(test)
endif()
Nou konekte depandans. Tanpri sonje ke nou lye sèlman sib CMake nou te bezwen nan binè nou an epi yo pa t rele kòmandman an target_include_directories. Tit ki soti nan kad tès la ak nan pa nou an Mylib::mylib, osi byen ke bati paramèt (nan ka nou an, sa a se estanda lang C++) te vini ansanm ak objektif sa yo.
Finalman, nou kreye yon sib enbesil, "konstriksyon an" ki ekivalan a kouri tès yo, epi ajoute sib sa a nan bati default la (atribi a responsab pou sa a. ALL). Sa vle di ke konstriksyon default la deklannche tès yo kouri, sa vle di nou p'ap janm bliye kouri yo.
add_custom_target(check ALL COMMAND mylib-unit-tests)
Apre sa, nou pèmèt mezi kouvèti kòd si opsyon ki apwopriye a espesifye. Mwen pa pral antre nan detay, paske yo gen rapò plis ak yon zouti pou mezire pwoteksyon pase CMake. Li enpòtan sèlman sonje ke baze sou rezilta yo pral kreye yon objektif coverage, ak ki li se pratik yo kòmanse mezire pwoteksyon.
find_program(GCOVR_EXECUTABLE gcovr)
if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE)
message(STATUS "Измерение покрытия кода тестами включено")
target_compile_options(mylib-unit-tests PRIVATE --coverage)
target_link_libraries(mylib-unit-tests PRIVATE gcov)
add_custom_target(coverage
COMMAND
${GCOVR_EXECUTABLE}
--root=${PROJECT_SOURCE_DIR}/include/
--object-directory=${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
check
)
elseif(MYLIB_COVERAGE AND NOT GCOVR_EXECUTABLE)
set(MYLIB_COVERAGE OFF)
message(WARNING "Для замеров покрытия кода тестами требуется программа gcovr")
endif()
Apre sa, nou tcheke si itilizatè a te mete varyab lang nan. Si wi, Lè sa a, nou pa manyen li, si se pa, Lè sa a, nou pran Ris. Lè sa a, nou konfigirasyon dosye sistèm Doxygen yo. Tout varyab ki nesesè yo, ki gen ladan lang lan, ale la pandan pwosesis konfigirasyon an (gade. команду configure_file).
Lè sa a, nou kreye yon objektif doc, ki pral kòmanse jenere dokiman. Piske jenere dokiman se pa pi gwo bezwen nan pwosesis devlopman an, sib la pa pral aktive pa default; li pral oblije lanse klèman.
if (Doxygen_FOUND)
if (NOT MYLIB_DOXYGEN_LANGUAGE)
set(MYLIB_DOXYGEN_LANGUAGE Russian)
endif()
message(STATUS "Doxygen documentation will be generated in ${MYLIB_DOXYGEN_LANGUAGE}")
configure_file(Doxyfile.in Doxyfile)
add_custom_target(doc COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
endif ()
Isit la nou jwenn twazyèm Python la epi kreye yon sib wandbox, ki jenere yon demann ki koresponn ak API sèvis la Wandbox, epi li voye l ale. Repons lan vini ak yon lyen ki mennen nan bwat sab la fini.
find_program(PYTHON3_EXECUTABLE python3)
if(PYTHON3_EXECUTABLE)
set(WANDBOX_URL "https://wandbox.org/api/compile.json")
add_custom_target(wandbox
COMMAND
${PYTHON3_EXECUTABLE} wandbox.py mylib-example.cpp "${PROJECT_SOURCE_DIR}" include |
curl -H "Content-type: application/json" -d @- ${WANDBOX_URL}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS
mylib-unit-tests
)
else()
message(WARNING "Для создания онлайн-песочницы требуется интерпретатор ЯП python 3-й версии")
endif()
An reyalite, vèsyon 3.13 CMake sèlman oblije kouri kèk nan kòmandman konsole ki dekri nan èd sa a. Soti nan pwen de vi nan sentaks la nan scripts CMake, vèsyon 3.8 se ase si jenerasyon yo rele nan lòt fason.
CMake se yon sistèm trè pwisan ak fleksib ki pèmèt ou aplike fonksyonalite pou chak gou ak koulè. Epi, byenke sentaks la pafwa kite anpil yo dwe vle, dyab la toujou pa terib tankou li pentire. Sèvi ak sistèm CMake build la pou benefis sosyete a ak sante.