yleiskatsaus
opetus: 10 min
harjoitukset: 15 minkysymykset
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 MODULE
jos 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 PUBLIC
PRIVATE
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
, valmistettumy_lib.hpp
jamy_lib.cpp
. Kääntäminen vaatii vähintään C++14: n. Jos sitten lisätäänmy_exe
, ja se tarvitseemy_lib
, pitäisikö sen pakottaamy_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ä onPRIVATE
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.
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, likecxx_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:
IMPORTED
kohteita ei voi viedä. Jos tallennat kohteesi, et voi tallentaa tuotuja-ne täytyy luoda uudelleen (tai löytää uudelleen).IMPORTED
header include-hakemistot merkitään ainaSYSTEM
.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.