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 Bwymagania 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.
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.
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.
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.
Odpowiedzi:
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:
Kiedy CUpewnij kompiluje cel, wykorzystuje cele
INCLUDE_DIRECTORIES
,COMPILE_DEFINITIONS
orazCOMPILE_OPTIONS
właściwości. UżywającPRIVATE
słowa kluczowego intarget_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 propagujeB
wymagania użycia doA
celu. Te wymagania dotyczące użycia docelowego to katalogi include, definicje kompilacji itp., Które każdy cel, od którego zależy,B
musi spełniać. Są one określane przezINTERFACE_*
wersję właściwości wymienionych powyżej (np.INTERFACE_INCLUDE_DIRECTORIES
) I są zapełniane przy użyciuINTERFACE
słowa kluczowego podczas wywoływaniatarget_*()
poleceń.Słowo
PUBLIC
kluczowe oznacza z grubszaPRIVATE + INTERFACE
.Dlatego załóżmy, że tworzysz bibliotekę,
A
któ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 kompilacjiA
). 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órychA
plikach źródłowych, a także mogą być zawarte w każdym innym kliencie twojejA
biblioteki.Dokumentacja CMake 3.0 zawiera więcej szczegółów na temat tej specyfikacji kompilacji i właściwości wymagań użycia .
źródło
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 musiszlibname/
najpierw wstawić .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 swojejmain()
funkcji) . WPRIVATE
tym 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 wykonywalnegoINTERFACE
lubPUBLIC
na nim.Z dokumentacji: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Aby przeformułować dokumentację własnymi słowami:
źródło