Kehityksen aikana tykkään vaihtaa kääntäjiä, rakentaa tiloja, riippuvuusversioita, tehdä staattista analyysiä, mitata suorituskykyä, kerätä kattavuutta, luoda dokumentaatiota jne. Ja rakastan todella CMakea, koska sen avulla voin tehdä kaiken mitä haluan.
Monet ihmiset arvostelevat CMakea, ja usein ansaitusti, mutta jos katsot sitä, kaikki ei ole niin huonosti, ja viime aikoina ei huonommin, ja kehityksen suunta on varsin myönteinen.
Tässä huomautuksessa haluan kertoa sinulle, kuinka yksinkertaisesti järjestää otsikkokirjasto C++:ssa CMake-järjestelmässä saadaksesi seuraavat toiminnot:
Kokoonpano;
automaattisen käynnistystestit;
Koodipeittomittaus;
Asennus;
Automaattinen dokumentointi;
Online hiekkalaatikko sukupolvi;
Staattinen analyysi.
Jokainen, joka jo ymmärtää edut ja C-maken, voi yksinkertaisesti Lataa projektimalli ja alkaa käyttää sitä.
Puhumme pääasiassa CMake-skriptien järjestämisestä, joten niistä keskustellaan yksityiskohtaisesti. Kuka tahansa voi tarkastella loput tiedostot suoraan malliprojektisivulla.
Ensinnäkin sinun on pyydettävä vaadittu versio CMake-järjestelmästä. CMake kehittyy, komentojen allekirjoitukset ja käyttäytyminen eri olosuhteissa muuttuvat. Jotta CMake ymmärtäisi heti, mitä haluamme siltä, meidän on välittömästi tallennettava sitä koskevat vaatimukset.
cmake_minimum_required(VERSION 3.13)
Sitten määritämme projektimme, sen nimen, version, käytetyt kielet jne. (katso. команду project).
Tässä tapauksessa ilmoitamme kielen CXX (ja tämä tarkoittaa C++), jotta CMake ei rasita ja etsi C-kielen kääntäjää (oletusarvoisesti CMake sisältää kaksi kieltä: C ja C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
Täältä voit heti tarkistaa, onko projektimme mukana jossain muussa projektissa aliprojektina. Tämä auttaa paljon tulevaisuudessa.
Ensimmäinen vaihtoehto on MYLIB_TESTING — yksikkötestien poistaminen käytöstä. Tämä voi olla tarpeen, jos olemme varmoja, että kaikki on kunnossa testeissä, mutta haluamme vain esimerkiksi asentaa tai paketoida projektimme. Tai projektimme on mukana aliprojektina - tässä tapauksessa projektimme käyttäjä ei ole kiinnostunut suorittamaan testejämme. Ethän sinä testaa käyttämiäsi riippuvuuksia?
Lisäksi teemme erillisen vaihtoehdon MYLIB_COVERAGE koodin kattavuuden mittaamiseen testeillä, mutta se vaatii lisätyökaluja, joten se on otettava käyttöön erikseen.
Kirjastomme koostuu vain otsikkotiedostoista, mikä tarkoittaa, että meillä ei ole mitään tyhjennystä staattisten tai dynaamisten kirjastojen muodossa. Toisaalta, jotta voisimme käyttää kirjastoamme ulkoisesti, se on asennettava, sen on oltava järjestelmässä havaittavissa ja liitettävä projektiisi, ja samalla nämä samat otsikot sekä mahdollisesti joitain muita, on liitetty siihen ominaisuuksia.
Tätä tarkoitusta varten luomme käyttöliittymäkirjaston.
add_library(mylib INTERFACE)
Yhdistämme otsikot käyttöliittymäkirjastoomme.
Moderni, muodikas, nuorten CMaken käyttö tarkoittaa, että otsikot, ominaisuudet jne. lähetetään yhden kohteen kautta. Joten riittää sanottava target_link_libraries(target PRIVATE dependency)ja kaikki otsikot, jotka liittyvät kohteeseen dependency, ovat saatavilla kohteeseen kuuluville lähteille target. Etkä tarvitse yhtään [target_]include_directories. Tämä osoitetaan alla analyysissä CMake skripti yksikkötestejä varten.
Tämä komento yhdistää tarvitsemamme otsikot käyttöliittymäkirjastoomme, ja jos kirjastomme on yhdistetty mihin tahansa kohteeseen samassa CMake-hierarkiassa, hakemiston otsikot liitetään siihen. ${CMAKE_CURRENT_SOURCE_DIR}/include, ja jos kirjastomme on asennettu järjestelmään ja yhdistetty toiseen projektiin komennolla find_package, niin hakemiston otsikot liitetään siihen include suhteessa asennushakemistoon.
Asetetaan kielistandardi. Tietysti viimeinen. Samaan aikaan emme vain sisällytä standardia, vaan ulotamme sen myös kirjastomme käyttäjiin. Tämä saavutetaan, koska määritetyllä ominaisuudella on luokka INTERFACE (Ks. target_compile_features -komento).
Luodaan kirjastollemme alias. Lisäksi kauneuden vuoksi se on erityisessä "nimitilassa". Tästä on hyötyä, kun eri moduuleita ilmestyy kirjastoomme ja yhdistämme ne toisistaan riippumatta. Kuten esimerkiksi Bustassa.
Otsikoiden asentaminen järjestelmään. Täällä kaikki on yksinkertaista. Sanomme, että kansion, jossa on kaikki otsikot, pitäisi mennä hakemistoon include suhteessa asennuspaikkaan.
Seuraavaksi ilmoitamme rakennusjärjestelmälle, että haluamme pystyä kutsumaan komentoa kolmannen osapuolen projekteissa find_package(Mylib) ja saada maali Mylib::mylib.
Seuraava loitsu tulisi ymmärtää näin. Kolmannen osapuolen projektissa kutsumme komentoa find_package(Mylib 1.2.3 REQUIRED), ja asennetun kirjaston todellinen versio ei ole yhteensopiva version kanssa 1.2.3CMake luo automaattisesti virheen. Toisin sanoen sinun ei tarvitse seurata versioita manuaalisesti.
Jos testit on poistettu käytöstä eksplisiittisesti käyttämällä vastaava vaihtoehto tai projektimme on aliprojekti, eli se on yhdistetty toiseen CMake-projektiin komennolla add_subdirectory, emme liiku hierarkiassa pidemmälle, ja komentosarja, joka kuvaa komennot testien luomiseen ja suorittamiseen, ei yksinkertaisesti toimi.
if(NOT MYLIB_TESTING)
message(STATUS "Тестирование проекта Mylib выключено")
elseif(IS_SUBPROJECT)
message(STATUS "Mylib не тестируется в режиме подмодуля")
else()
add_subdirectory(test)
endif()
Yhdistämme riippuvuuksia. Huomaa, että linkitimme vain tarvitsemamme CMake-kohteet binaariimme, emmekä kutsuneet komentoa target_include_directories. Otsikot testikehyksestä ja meidän Mylib::mylib, sekä rakennusparametrit (meidän tapauksessamme tämä on C++-kielistandardi) onnistuivat näiden tavoitteiden myötä.
Lopuksi luomme valekohteen, jonka "koontiversio" vastaa testien suorittamista, ja lisäämme tämän kohteen oletuskoontiversioon (attribuutti vastaa tästä ALL). Tämä tarkoittaa, että oletusversio käynnistää testit, joten emme koskaan unohda suorittaa niitä.
add_custom_target(check ALL COMMAND mylib-unit-tests)
Seuraavaksi otamme käyttöön koodipeittomittauksen, jos sopiva vaihtoehto on määritetty. En mene yksityiskohtiin, koska ne liittyvät enemmän kattavuuden mittaustyökaluun kuin CMakeen. On vain tärkeää huomata, että tulosten perusteella luodaan tavoite coverage, jolla on kätevä aloittaa kattavuuden mittaaminen.
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()
Seuraavaksi tarkistamme, onko käyttäjä asettanut kielimuuttujan. Jos kyllä, emme koske siihen, jos ei, niin otamme venäjän. Sitten määritämme Doxygen-järjestelmätiedostot. Kaikki tarvittavat muuttujat, mukaan lukien kieli, menevät sinne määritysprosessin aikana (katso. команду configure_file).
Sitten luomme tavoitteen doc, joka alkaa luoda asiakirjoja. Koska dokumentaation tuottaminen ei ole kehitysprosessin suurin tarve, kohde ei ole oletusarvoisesti käytössä, vaan se on käynnistettävä eksplisiittisesti.
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 ()
Täältä löydämme kolmannen Pythonin ja luomme kohteen wandbox, joka luo palvelun API:ta vastaavan pyynnön Wandbox, ja lähettää hänet pois. Vastauksen mukana tulee linkki valmiiseen hiekkalaatikkoon.
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()
Tarjoaa mahdollisuuden poistaa käytöstä yksikön testikoon ja kohdistuksen check. Tämän seurauksena koodin peiton mittaus testeillä on kytketty pois päältä (katso. MYLIB_COVERAGE).
Testaus poistetaan myös automaattisesti käytöstä, jos projekti liitetään toiseen projektiin aliprojektina komennolla add_subdirectory.
Palvelua käytetään tähän tarkoitukseen Wandbox. En tiedä kuinka joustavia heidän palvelimensa ovat, mutta mielestäni tätä mahdollisuutta ei pidä käyttää väärin.
Itse asiassa CMake-versio 3.13 vaaditaan vain joidenkin tässä ohjeessa kuvattujen konsolikomentojen suorittamiseen. CMake-skriptien syntaksin kannalta versio 3.8 riittää, jos generointia kutsutaan muilla tavoilla.
Tämän jälkeen staattinen analyysi käynnistetään automaattisesti aina, kun lähde käännetään ja käännetään uudelleen. Mitään ylimääräistä ei tarvitse tehdä.
Kalahtaa
Upean työkalun avulla scan-build Voit myös suorittaa staattisen analyysin hetkessä:
CMake on erittäin tehokas ja joustava järjestelmä, jonka avulla voit toteuttaa toimintoja jokaiseen makuun ja väriin. Ja vaikka syntaksi jättää joskus paljon toivomisen varaa, paholainen ei silti ole niin kauhea kuin se on maalattu. Käytä CMake build -järjestelmää yhteiskunnan ja terveyden hyödyksi.