Working with Targets

yleiskatsaus

opetus: 10 min
harjoitukset: 15 min
kysymykset

  • miten tavoitteet toimivat?

tavoitteet

  • osaa asettaa tavoitteet

  • ymmärtää linkitys-ja liitäntäominaisuudet

    tee RAJAPINTATAVOITTEET

nyt osaat koota yhden tiedoston kolmen cmake-rivin avulla. Mutta mitä tapahtuu, jos sinulla on enemmän kuin yksi tiedosto riippuvuuksia? Sinun täytyy pystyä kertomaan Cmakelle projektisi rakenteesta, ja se auttaa sinua rakentamaan sen. Siihen tarvitaan kohteita.

olet jo nähnyt kohteen:

add_executable(myexample simple.cpp)

Tämä luo ”suoritettavan” kohteen, jonka nimi onmyexample. Kohteiden nimien on oltava yksilöllisiä (ja suoritettavan nimen voi asettaa muuksi kuin kohteen nimeksi, jos todella haluat).

kohteet muistuttavat paljon muiden kielten ”olioita”; niillä on ominaisuuksia (jäsen muuttujat) thathold information. Esimerkiksi SOURCES ominaisuus on simple.cpp siinä.

toinen kohde on kirjasto:

add_library(mylibrary simplelib.cpp)

voit lisätä avainsanat SHARED tai MODULEjos tiedät minkälaisen kirjaston haluat tehdä; oletuksena on eräänlainen ”automaattinen” kirjasto, joka on käyttäjän valittavissa BUILD_SHARED_LIBS.

myös rakentamattomia kirjastoja voi tehdä. Lisää siitä myöhemmin, kun näemme, mitä voimme tehdä maaleilla.

linkittäminen

kun kohteita on useita, niiden välistä suhdetta voi kuvatatarget_link_libraries ja hakusanalla; yksi PUBLICPRIVATE ja INTERFACE. Älä unohda tätä avainsanaa tehdessäsi kirjastoa! CMake menee tämän kohteen vanhaan yhteensopivuustilaan, joka yleisesti rikkoo asioita.

kysymys

sinulla on kirjasto, my_lib, valmistettu my_lib.hpp ja my_lib.cpp. Kääntäminen vaatii vähintään C++14: n. Jos sitten lisätään my_exe, ja se tarvitsee my_lib, pitäisikö sen pakottaa my_exe compilewith c++14 tai parempi?

vastaus

Tämä riippuu otsikosta. Jos otsikko sisältää C++14, tämä on julkinen vaatimus-sekä kirjasto että sen käyttäjät tarvitsevat sitä. Jos otsikko on kuitenkin voimassa kaikissa C++: n versioissa, ja ainoastaan my_lib.cpp sisällä olevat toteutukset edellyttävät c++14: ää, niin tämä on PRIVATE vaatimus

  • käyttäjiä ei tarvitse pakottaa c++14-tilaan.

ehkä käyttäjiltä vaaditaan c++14: ää, mutta kirjastosi voi kääntää millä tahansa C++: n versiolla.Tämä olisi INTERFACE vaatimus.

esimerkki julkisesta ja yksityisestä perinnöstä

kuva 1: Esimerkki julkisesta, yksityisestä ja käyttöliittymästä. myprogram rakentaa kolme kirjastoaan mylibrary; yksityiskirjasto ei vaikuta siihen.

jokaisessa kohteessa on kaksi kokoelmaa ominaisuuksia, jotka voidaan täyttää arvoilla;”yksityiset” ominaisuudet ohjaavat mitä tapahtuu, kun rakennat kyseisen kohteen, ja ”rajapinta” propertiestell kohteet liittyvät tähän mitä rakennettaessa. PUBLIC avainsana täyttää molemmat ominaisuuskentät samanaikaisesti.

Esimerkki 1: Include directories

When you run , thenthe INCLUDE_DIRECTORIES property of TargetA has mydir appended. Jos sen sijaan käytetään hakusanaaINTERFACE, niin INTERFACE_INCLUDE_DIRECTORIES on sen sijaan liitetty. Jos käytätPUBLIC, molemmat ominaisuudet liitetään samaan aikaan.

Esimerkki 2: C++ – standardi

on olemassa C++ – standardin ominaisuus – CXX_STANDARD. Voit asettaa tämän ominaisuuden, ja kuten monet ominaisuudet Cmakessa, se saa oletusarvon CMAKE_CXX_STANDARD muuttuja,jos se on asetettu, mutta KÄYTTÖLIITTYMÄVERSIOTA ei ole – et voi pakottaa CXX_STANDARD kohteen kautta. Mitä tekisit, jos sinulla olisi c++11-käyttöliittymäkohde ja c++14-käyttöliittymäkohde ja ne yhdistettäisiin molempiin?

muuten, on olemassa tapa käsitellä tätä – voit määrittää vähimmäisominaisuudet, jotka tarvitset kohteen kääntämiseksi; cxx_std_11 ja vastaavat meta-ominaisuudet sopivat tähän täydellisesti – kohteesi kokoaa vähintään korkeimmalle määritetylle tasolle, ellei CXX_STANDARD ole asetettu (ja että ’ on mukava, selkeä virhe jos asetat CXX_STANDARD liian alhainen). target_compile_features voi täyttääCOMPILE_FEATURES ja INTERFACE_COMPILE_FEATURES, aivan kuten hakemistot esimerkissä 1.

kokeile sitä

Hanki tämä arkisto ja siirry esimerkkiin. Yritä kirjoittaa CMakeLists, joka rakentaa oikein.

git clone https://github.com/hsf-training/hsf-training-cmake-webpage.gitcd hsf-training-cmake-webpage/code/01-simple

tässä olevat tiedostot ovat:

  • simple_lib.cpp: on koottava MYLIB_PRIVATE ja määritelty.
  • simple_example.cpp: on koottava määritelty, mutta ei MYLIB_PRIVATE

käytetään määrittelyjen asettamiseen simple_lib.

asiat, jotka voit asettaa tavoitteille

  • target_link_libraries: muut tavoitteet; voi myös siirtää kirjaston nimiä suoraan
  • target_include_directories: Include directories
  • target_compile_features: The compiler features you need activated, like cxx_std_11
  • target_compile_definitions: Definitions
  • target_compile_options: More general compile flags
  • target_link_directories: Don’t use, give full paths instead (CMake 3.13+)
  • target_link_options: General link flags (CMake 3.13+)
  • target_sources: Add source files

See more commands here.

muunlaiset tavoitteet

saatat todella joutua tavoitteiden ulkopuolelle ja suunnittelet jo, miten voit kuvailla ohjelmiasi tavoitteina. Hienoa! Kuitenkin, törmäät nopeasti kahteen tilanteeseen, joissa kohdekieli on hyödyllinen, mutta tarvitset hieman ylimääräistä joustavuutta siihen, mitä olemme käsitelleet.

ensinnäkin sinulla saattaa olla kirjasto, jonka käsitteellisesti pitäisi olla kohde, mutta jossa ei todellisuudessa ole mitään sisäänrakennettuja komponentteja – ”vain header-kirjasto”. Näitä kutsutaan cmake-käyttöliittymäkirjastoiksi ja voit kirjoittaa:

add_library(some_header_only_lib INTERFACE)

huomaa, ettei lähdetiedostoja tarvinnut lisätä. Nyt voit asettaa INTERFACE ominaisuudet vain tälle(koska rakennettua komponenttia ei ole).

toinen tilanne on, jos on valmiiksi rakennettu kirjasto, jota haluaa käyttää. Tätä kutsutaan Cmakessa animported-kirjastoksi, ja se käyttää hakusanaa IMPORTED. Tuodut kirjastot voivat olla myösINTERFACE kirjastot, ne voidaan rakentaa ja muokata käyttäen samaa syntaksia kuin muutkin kirjastot(alkaen CMake 3: sta.11), ja niiden nimissä voi olla ::ALIAS kirjastot, joiden nimi on yksinkertaisesti jokin muu kirjasto, saavat myös olla ::). Suurimman osan ajasta saat tuotavakirjastot muista paikoista, ja ei tehdä omia.

rajapyykki ennakoitu

entä INTERFACE IMPORTED?Ero tulee kahdesta asiasta:

  1. IMPORTED kohteita ei voi viedä. Jos tallennat kohteesi, et voi tallentaa tuotuja-ne täytyy luoda uudelleen (tai löytää uudelleen).
  2. IMPORTED header include-hakemistot merkitään aina SYSTEM.

siksi IMPORTED kohteen pitäisi edustaa jotain, joka ei suoraan kuulu omaan pakettiin.

More reading

  • perustuu nykyaikaisiin Cmaken perusteisiin
  • Katso myös Cmaken dokumentit

avainkohdat

  • kirjastot ja suoritustiedostot ovat kohteita.

  • kohteilla on paljon hyödyllisiä ominaisuuksia.

  • tavoitteet voidaan yhdistää muuhun kohteeseen.

  • voit kontrolloida, mitkä kohteen osat periytyvät linkittäessä.

  • muuttujien tekemisen sijaan voi tehdä RAJAPINTATAVOITTEITA.

Vastaa

Sähköpostiosoitettasi ei julkaista.