CMake target_include_directories znaczenie zakresu

104

Jakie jest znaczenie słowa kluczowego PUBLIC, PRIVATEi INTERFACEzwiązane z CUpewnij użytkownika target_include_directories?

Sirish
źródło
Ściśle powiązane: stackoverflow.com/q/26037954/3425536
emlai

Odpowiedzi:

125

Te słowa kluczowe są używane do określenia, kiedy lista katalogów włączeń, które przekazujesz do celu, jest potrzebna. Do kiedy , to znaczy, czy te zawierają katalogi są potrzebne:

  • Aby skompilować sam cel.
  • Aby skompilować inne cele, które zależą od tego celu (na przykład przy użyciu jego publicznych nagłówków).
  • W obu powyższych sytuacjach.

Kiedy CUpewnij kompiluje cel, wykorzystuje cele INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSoraz COMPILE_OPTIONSwłaściwości. Używając PRIVATEsłowa kluczowego in target_include_directories()i podobnie, mówisz CMake, aby wypełnił te właściwości docelowe.

Gdy CMake wykryje zależność między celem A a innym celem B (na przykład podczas korzystania z target_link_libraries(A B)polecenia), przechodnie propaguje B wymagania użycia do Acelu. Te wymagania dotyczące użycia docelowego to katalogi include, definicje kompilacji itp., Które każdy cel, od którego zależy, Bmusi spełniać. Są one określane przez INTERFACE_*wersję właściwości wymienionych powyżej (np. INTERFACE_INCLUDE_DIRECTORIES) I są zapełniane przy użyciu INTERFACEsłowa kluczowego podczas wywoływania target_*()poleceń.

Słowo PUBLICkluczowe oznacza z grubsza PRIVATE + INTERFACE.

Dlatego załóżmy, że tworzysz bibliotekę, Aktóra używa niektórych nagłówków Boost. Ty byś zrobił:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})jeśli używasz tylko tych nagłówków Boost w swoich plikach źródłowych ( .cpp) lub prywatnych plikach nagłówkowych ( .h).
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})jeśli nie używasz tych nagłówków Boost w swoich plikach źródłowych (dlatego nie potrzebujesz ich do kompilacji A). Nie mogę wymyślić na to przykładu z prawdziwego świata.
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})jeśli używasz tych nagłówków Boost w swoich publicznych plikach nagłówkowych, które są zawarte ZARÓWNO w niektórych Aplikach źródłowych, a także mogą być zawarte w każdym innym kliencie twojej Abiblioteki.

Dokumentacja CMake 3.0 zawiera więcej szczegółów na temat tej specyfikacji kompilacji i właściwości wymagań użycia .

TManhente
źródło
18
W odniesieniu do rzeczywistego przykładu INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Oznacza to, że w swojej bibliotece możesz dołączać pliki bezpośrednio, ale jako użytkownik biblioteki musisz libname/najpierw wstawić .
KaareZ
2
Ta odpowiedź ma dla mnie sens przy tworzeniu bibliotek. Ale co powiesz na wywołanie target_include_directories dla celu, który jest plikiem wykonywalnym?
Norman Pellet
1
@NormanPellet: Możesz wywołać target_include_directories()wykonywalny cel, jeśli chcesz ustawić włączane katalogi, w których mają być znalezione pliki nagłówkowe używane przez te pliki wykonywalne (na przykład: Boost :: Program_options, jeśli używasz go do analizowania argumentów w swojej main()funkcji) . W PRIVATEtym przypadku prawdopodobnie użyłbyś słowa kluczowego, ponieważ te pliki są potrzebne do skompilowania samego pliku wykonywalnego. Nie wiem jednak, czy jest pożytek z pliku wykonywalnego INTERFACElub PUBLICna nim.
TManhente
13

Słowa kluczowe INTERFACE, PUBLIC i PRIVATE są wymagane do określenia zakresu następujących argumentów. Elementy PRIVATE i PUBLIC wypełnią właściwość INCLUDE_DIRECTORIES o wartości <target>. Elementy PUBLIC i INTERFACE wypełnią właściwość INTERFACE_INCLUDE_DIRECTORIES <target>. Poniższe argumenty określają, że zawierają katalogi.

Z dokumentacji: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

Aby przeformułować dokumentację własnymi słowami:

  • chcesz dodać katalog do listy zawierającej katalog docelowy
  • z PRIVATE katalog jest dodawany do docelowych katalogów dołączanych
  • z INTERFEJSem cel nie jest modyfikowany, ale INTERFACE_INCLUDE_DIRECTORIES jest rozszerzany o katalog. Zmienna jest listą publicznych katalogów dołączania dla biblioteki.
  • z PUBLICZNYM wykonywane są obie akcje z PRYWATNE i INTERFEJSU.
usr1234567
źródło
5
Przejrzałem dokumentację CMAKE, ale nadal nie udało mi się zrozumieć, co tak naprawdę oznaczają iw jakim kontekście (tworzyć pliki lub jak je kompilować)?
Sirish
@Sirish: Próbowałem przeformułować dokumentację, mam nadzieję, że to pomoże.
usr1234567