Mulle meeldib arenduse käigus vahetada kompilaatoreid, koostada režiime, sõltuvusversioone, teha staatilist analüüsi, mõõta jõudlust, koguda katvust, genereerida dokumentatsiooni jne. Ja ma armastan CMake'i väga, sest see võimaldab mul teha kõike, mida tahan.
Paljud kiruvad CMake'i ja sageli ka teenitult, aga kui vaadata, siis pole see nii hull, aga viimasel ajal pole üldse paha, ja arengusuund on üsna positiivne.
Selles märkuses tahan teile öelda, kui lihtne on korraldada C++ päiseteegi CMake süsteemis, et saada järgmised funktsioonid:
See keskendub peamiselt CMake skriptide korraldamisele, nii et neid analüüsitakse üksikasjalikult. Ülejäänud faile saab igaüks otse vaadata. malliprojekti lehel.
Kõigepealt peate taotlema CMake süsteemi soovitud versiooni. CMake areneb, käsusignatuurid muutuvad, käitumine erinevates tingimustes. Selleks, et CMake saaks kohe aru, mida me sellelt tahame, peame kohe oma nõuded sellele paika panema.
cmake_minimum_required(VERSION 3.13)
Seejärel tähistame oma projekti, selle nime, versiooni, kasutatavaid keeli jne. команду project).
Sel juhul määrake keel CXX (mis tähendab C++), et CMake ei viitsiks C-kompilaatorit otsida (vaikimisi on CMake'is kaks keelt: C ja C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
Siin saate koheselt kontrollida, kas meie projekt on alamprojektina kaasatud mõnda teise projekti. Sellest on tulevikus palju abi.
Esimene variant on MYLIB_TESTING - ühikutestide keelamiseks. Seda võib vaja minna, kui oleme kindlad, et testidega on kõik korras ja tahame näiteks oma projekti ainult installida või pakkida. Või on meie projekt kaasatud alamprojektina – sellisel juhul pole meie projekti kasutaja meie testide läbiviimisest huvitatud. Sa ei testi kasutatavaid sõltuvusi, eks?
Lisaks teeme eraldi valiku MYLIB_COVERAGE koodi katvuse mõõtmiseks testidega, kuid see nõuab täiendavaid tööriistu, seega peate selle selgesõnaliselt lubama.
Muidugi oleme lahedad positiivsed programmeerijad, seega tahame kompilaatorilt maksimaalset kompileerimisaegset diagnostikat. Ükski hiir ei pääse läbi.
Meie teek koosneb ainult päisefailidest, mis tähendab, et meil pole staatiliste või dünaamiliste teekide kujul väljundit. Teisest küljest, et kasutada meie teeki väljastpoolt, peate selle installima, leidma selle süsteemist ja ühendama selle oma projektiga ning samal ajal ka need päised, kui võimalik, et mõned lisaomadused.
Selleks loome liidese raamatukogu.
add_library(mylib INTERFACE)
Seome päised oma liidese teegiga.
Kaasaegne, trendikas, nooruslik CMake kasutamine tähendab, et päised, omadused jne. edastatakse ühe sihtmärgi kaudu. Nii et piisab, kui öelda target_link_libraries(target PRIVATE dependency)ja kõik päised, mis on sihtmärgiga seotud dependency, on sihtmärgile kuuluvate allikate jaoks saadaval target. Ja sa ei vaja ühtegi [target_]include_directories. Seda näidatakse allpool sõelumisel CMake skript ühikutestide jaoks.
See käsk seob meile vajalikud päised meie liidese teegiga ja kui meie teek on ühendatud mis tahes sihtmärgiga samas CMake'i hierarhias, seostatakse kataloogi päised sellega ${CMAKE_CURRENT_SOURCE_DIR}/include, ja kui meie teek on süsteemi installitud ja ühendatud teise projektiga käsu abil find_package, siis seostatakse sellega kataloogi päised include installikataloogi suhtes.
Määrake keelestandard. Muidugi kõige uuem. Samal ajal me mitte ainult ei lisa standardit, vaid levitame seda ka neile, kes meie raamatukogu kasutama hakkavad. See saavutatakse, kui seatud atribuudil on kategooria INTERFACE (cm. target_compile_features käsk).
Saame oma raamatukogule varjunime. Ja ilu jaoks on see spetsiaalses "nimeruumis". See on kasulik, kui meie teeki ilmuvad erinevad moodulid ja me hakkame neid üksteisest sõltumatult ühendama. Nagu näiteks Bustal.
Järgmist loitsu tuleb mõista nii. Kui kõrvalprojektis kutsume käsku find_package(Mylib 1.2.3 REQUIRED), ja samal ajal ei ühildu installitud teegi tegelik versioon versiooniga 1.2.3, CMake genereerib automaatselt vea. See tähendab, et te ei pea versioone käsitsi jälgima.
Kui testid on selgesõnaliselt keelatud vastav variant või meie projekt on alamprojekt, see tähendab, et see on käsu abil ühendatud teise CMake projektiga add_subdirectory, me ei lähe hierarhias allapoole ja skript, mis kirjeldab testide genereerimise ja käitamise käske, lihtsalt ei käivitu.
if(NOT MYLIB_TESTING)
message(STATUS "Тестирование проекта Mylib выключено")
elseif(IS_SUBPROJECT)
message(STATUS "Mylib не тестируется в режиме подмодуля")
else()
add_subdirectory(test)
endif()
Me ühendame sõltuvused. Pange tähele, et lisasime oma binaarfailile ainult vajalikud CMake'i sihtmärgid ega kutsunud käsku target_include_directories. Testraamistiku ja meie päised Mylib::mylib, aga ka koostamise valikud (meie puhul C++ keelestandard) roomasid koos nende sihtmärkidega.
Lõpuks loome näiva sihtmärgi, mille ehitamine on samaväärne testide käitamisega ja lisame selle sihtmärgi vaikeehitusele (selle eest vastutab atribuut ALL). See tähendab, et vaikejärg käivitab testid, mis tähendab, et me ei unusta kunagi neid käivitada.
add_custom_target(check ALL COMMAND mylib-unit-tests)
Järgmiseks lülitage sisse koodi katvuse mõõtmine, kui vastav valik on määratud. Ma ei hakka detailidesse laskuma, sest need on rohkem seotud katvuse mõõtmise tööriistaga kui CMake'iga. Oluline on ainult märkida, et tulemused loovad eesmärgi coverage, millega on mugav alustada katvuse mõõtmist.
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()
Järgmisena kontrollime, kas keelega muutuja on kasutaja poolt määratud. Kui jah, siis me seda ei puuduta, kui ei, siis võtame vene keele. Seejärel konfigureerime Doxygeni süsteemifailid. Kõik vajalikud muutujad, sealhulgas keel, jõuavad sinna konfiguratsiooniprotsessi käigus (vt. команду configure_file).
Seejärel loome eesmärgi doc, mis hakkab dokumentatsiooni looma. Kuna dokumentatsiooni genereerimine pole arendusprotsessis kõige suurem vajadus, siis sihtmärki vaikimisi ei kaasata, see tuleb eksplitsiitselt käivitada.
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 ()
Siit leiame kolmanda Pythoni ja loome sihtmärgi wandbox, mis genereerib teenuse API-le vastava päringu Wandboxja saadab selle. Vastuseks tuleb link valmis liivakastile.
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()
Pakub võimalust üksuse testi koostamine ja sihtimine välja lülitada check. Selle tulemusena lülitatakse koodi katvuse mõõtmine testidega välja (vt MYLIB_COVERAGE).
Samuti keelatakse testimine automaatselt, kui projekt on käsu abil alamprojektina ühendatud teise projektiga add_subdirectory.
Tegelikult on CMake'i versioon 3.13 vajalik vaid mõne selles spikris kirjeldatud konsoolikäskude käitamiseks. CMake skriptide süntaksi seisukohalt piisab versioonist 3.8, kui genereerimist kutsutakse välja muul viisil.
CMake on väga võimas ja paindlik süsteem, mis võimaldab rakendada funktsionaalsust igale maitsele ja värvile. Ja kuigi süntaks jätab mõnikord soovida, pole kurat ikkagi nii kohutav, kui teda maalitakse. Kasutage CMake ehitussüsteemi ühiskonna ja tervise huvides.