lucrul cu obiective

Prezentare generală

predare: 10 Min
exerciții: 15 min
întrebări

  • cum funcționează obiectivele?

obiective

  • știți cum să configurați ținte

  • înțelegeți proprietățile de legătură și interfață

  • Faceți ținte de interfață

acum știți cum să compilați un singur fișier folosind trei linii de cmake. Dar ce se întâmplă dacă avețimai mult de un fișier cu dependențe? Trebuie să puteți spune CMake despre structura dvs. proiect și vă va ajuta să îl construiți. Pentru a face acest lucru, veți avea nevoie de ținte.

ați văzut deja o țintă:

add_executable(myexample simple.cpp)

aceasta creează o țintă „executabilă” cu numelemyexample. Numele țintă trebuie să fie unic (și existăeste o modalitate de a seta numele executabil la altceva decât numele țintă, dacă doriți cu adevărat).

țintele seamănă mult cu „obiectele” în alte limbi; ei au proprietăți (variabile membre) carețineți informații. ProprietateaSOURCES, de exemplu, va aveasimple.cpp în ea.

un alt tip de țintă este o bibliotecă:

add_library(mylibrary simplelib.cpp)

puteți adăuga cuvintele cheie STATICSHARED sau MODULE dacă știți ce fel de bibliotecă doriți să faceți; implicit este un fel de bibliotecă „auto” care poate fi selectată de utilizator cu BUILD_SHARED_LIBS.

puteți face biblioteci non-construite prea. Mai multe despre asta mai târziu, odată ce vom vedea ce putem face cu țintele.

legarea

odată ce aveți mai multe obiective, puteți descrie relația dintre ele cutarget_link_libraries și un cuvânt cheie; unul dintrePUBLICPRIVATE șiINTERFACE. Nu uitați acest cuvânt cheie atunci când creați o bibliotecă! CMake intră într-un mod vechi de compatibilitate pentru această țintă careîn general rupe lucrurile.

întrebare

aveți o bibliotecă,my_lib, făcută dinmy_lib.hpp șimy_lib.cpp. Este nevoie de cel puțin C++14pentru a compila. Dacă apoi adăugați my_exe și are nevoie de my_lib, ar trebui ca forța my_exe să compilezecu C++14 sau mai bine?

răspuns

aceasta depinde de antet. Dacă antetul conține C++14, Aceasta este o cerință publică – ambelebiblioteca și utilizatorii săi au nevoie de ea. Cu toate acestea, dacă antetul este valabil în toate versiunile C++ șinumai implementările din my_lib.cpp necesită C++14, atunci acesta este un PRIVATE cerință

  • utilizatorii nu trebuie să fie forțați în modul C++14.

poate aveți nevoie de utilizatori au C++14, dar biblioteca poate compila cu orice versiune de c++.Aceasta ar fi o cerință INTERFACE.

exemplu de moștenire publică și privată

Figura 1: Exemplu de PUBLIC, privat și interfață. myprogram va construi cele trei biblioteci itsees prin mylibrary; biblioteca privată nu o va afecta.

există două colecții de proprietăți pe fiecare țintă care pot fi umplute cu valori; proprietățile”private” controlează ce se întâmplă atunci când construiți acea țintă, iar proprietățile „interfață” spun țintelor legate de aceasta ce trebuie făcut atunci când construiți. PUBLIC cuvinte cheie umple ambele propertyfields în același timp.

Exemplul 1: Includeți directoarele

când executați , proprietateaINCLUDE_DIRECTORIES aTargetA aremydir anexată. Dacă utilizați cuvântul cheie INTERFACE în schimb, atunci INTERFACE_INCLUDE_DIRECTORIES este adăugat la, în schimb. Dacă utilizați PUBLIC, atunci ambele proprietăți sunt atașate în același timp.

Exemplul 2: C++ standard

există o proprietate c++ standard – CXX_STANDARD. Puteți seta această proprietate, și ca manyproperties în CMake,ea devine valoarea implicită de la un CMAKE_CXX_STANDARD variabilă în cazul în care este setat, dar nu există nici o versiune de interfață – nu puteți forța un CXX_STANDARD printr-o țintă. Ce ai face dacă ai avea o țintă de interfață C++11 și o țintă de interfață C++14 și legată de ambele?apropo, există o modalitate de a gestiona acest lucru – puteți specifica caracteristicile minime de compilare de care aveți nevoiepentru a compila o țintă; cxx_std_11și meta-caracteristici similare sunt perfecte pentru acest lucru – targetwill compila cu cel puțin cel mai înalt nivel specificat, cu excepția cazului înCXX_STANDARDeste setat (și that ‘ o eroare frumos, clar dacă setațiCXX_STANDARD prea mic). target_compile_features poate umpleCOMPILE_FEATURES șiINTERFACE_COMPILE_FEATURES, la fel ca directoarele din exemplul 1.

încercați

obțineți acest depozit și mergeți la exemplu. Încercați să scrieți un CMakeLists care va construi corect.

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

fișierele de aici sunt:

  • simple_lib.cpp: trebuie compilat cuMYLIB_PRIVATE șiMYLIB_PUBLIC definit.
  • simple_example.cpp: trebuie compilat cuMYLIB_PUBLIC definit, dar nuMYLIB_PRIVATE

utilizați pentru a seta definițiile pesimple_lib.

lucruri pe care le puteți seta pe obiective

  • target_link_libraries: alte obiective; poate trece, de asemenea, nume de bibliotecă direct
  • 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.

alte tipuri de ținte

s-ar putea să fiți cu adevărat ieșiți de ținte și deja planificați cum puteți descrie programele dvs. în termeni de ținte. E grozav! Cu toate acestea, veți întâlni rapid încă două situațiiîn care limba țintă este utilă, dar aveți nevoie de o flexibilitate suplimentară față de ceea ce am acoperit.

În primul rând, este posibil să aveți o bibliotecă care conceptual ar trebui să fie o țintă, dar nu are de fapt componente anybuilt – o bibliotecă „numai antet”. Acestea se numesc biblioteci de interfață în CMake și youwould scrie:

add_library(some_header_only_lib INTERFACE)

observați că nu a fost nevoie să adăugați fișiere sursă. Acum Puteți setaINTERFACE proprietăți numai pe aceasta(deoarece nu există o componentă construită).

a doua situație este dacă aveți o bibliotecă pre-construită pe care doriți să o utilizați. Aceasta se numește biblioteca animported în CMake și folosește cuvântul cheie IMPORTED. Bibliotecile importate pot fi, de asemenea,INTERFACE biblioteci, pot fi construite și modificate folosind aceeași sintaxă ca și alte biblioteci(începând cu CMake 3.11), și pot avea :: în numele lor. (ALIAS bibliotecile, care pur și simplu denumesc o altă bibliotecă, au, de asemenea, permisiunea de a avea::). De cele mai multe ori veți fi importațibibliotecile din alte locuri și nu vă vor face propriile.

interfață IMPORETED

Ce zici deINTERFACE IMPORTED?Diferența se reduce la două lucruri:

  1. IMPORTED țintele nu sunt exportabile. Dacă vă salvați țintele, nu le puteți salva pe cele importate-acestea trebuie recreate (sau găsite din nou).
  2. IMPORTED antet includ directoare vor fi întotdeauna marcate caSYSTEM.

prin urmare, oIMPORTED țintă ar trebui să reprezinte ceva care nu face parte direct din pachetul dvs.

mai multe lecturi

  • bazat pe elementele de bază Moderne CMake
  • vezi și documentele CMake

puncte cheie

  • bibliotecile și executabilele sunt ținte.

  • țintele au o mulțime de proprietăți utile.

  • țintele pot fi legate de alte ținte.

  • puteți controla ce părți ale unei ținte sunt moștenite atunci când se leagă.

  • puteți face ținte de interfață în loc să faceți variabile.

Lasă un răspuns

Adresa ta de email nu va fi publicată.