Diese Schlüsselwörter werden verwendet, um festzustellen, wann die Liste der Include-Verzeichnisse benötigt wird, die Sie an das Ziel übergeben. Bis wann bedeutet dies, ob diese Include-Verzeichnisse benötigt werden:
Um dieses Ziel selbst zu kompilieren.
Kompilieren anderer Ziele, die von diesem Ziel abhängen (z. B. Verwendung der öffentlichen Header).
In beiden oben genannten Situationen.
Wenn CMake ist ein Ziel der Zusammenstellung, verwendet er die Ziele INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSund COMPILE_OPTIONSEigenschaften. Wenn Sie das PRIVATESchlüsselwort in target_include_directories()und gleichermaßen verwenden, weisen Sie CMake an, diese Zieleigenschaften zu füllen.
Wenn CMake eine Abhängigkeit zwischen einem Ziel A und einem anderen Ziel B erkennt (wie bei Verwendung des target_link_libraries(A B)Befehls), werden die BVerwendungsanforderungen transitiv an das AZiel weitergegeben. Diese Zielverwendungsanforderungen sind die Include-Verzeichnisse, Kompilierungsdefinitionen usw., die jedes Ziel, von dem es abhängt, Berfüllen muss. Sie werden durch die INTERFACE_*Version der oben aufgeführten Eigenschaften (wie INTERFACE_INCLUDE_DIRECTORIES) angegeben und INTERFACEbeim Aufrufen der target_*()Befehle mit dem Schlüsselwort gefüllt.
Das PUBLICSchlüsselwort bedeutet ungefähr PRIVATE + INTERFACE.
Angenommen, Sie erstellen eine Bibliothek A, die einige Boost-Header verwendet. Du würdest:
target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})Wenn Sie nur diese Boost-Header in Ihren Quelldateien ( .cpp) oder privaten Header-Dateien ( .h) verwenden.
target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})Wenn Sie diese Boost-Header nicht in Ihren Quelldateien verwenden (sie müssen daher nicht kompiliert werden A). Ich kann mir dafür kein reales Beispiel vorstellen.
target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})Wenn Sie diese Boost-Header in Ihren öffentlichen Header-Dateien verwenden, die BEIDE in einigen AQuelldateien enthalten sind und möglicherweise auch in einem anderen Client Ihrer ABibliothek enthalten sind.
In Bezug auf ein reales Beispiel von INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Dies bedeutet, dass Sie Dateien direkt in Ihre Bibliothek aufnehmen können, aber als Benutzer der Bibliothek müssen Sie libname/zuerst einfügen .
KaareZ
2
Diese Antwort ist für mich sinnvoll, um Bibliotheken zu erstellen. Aber wie wäre es mit dem Aufruf von target_include_directories für ein Ziel, das eine ausführbare Datei ist?
Norman Pellet
1
@NormanPellet: Sie können target_include_directories()ein ausführbares Ziel anfordern, wenn Sie Include-Verzeichnisse festlegen müssen, in denen Header-Dateien gefunden werden sollen, die von diesen ausführbaren Dateien verwendet werden (z. B. Boost :: Program_options, wenn Sie damit Argumente in Ihrer main()Funktion analysieren ). . PRIVATEIn diesem Fall würden Sie wahrscheinlich das Schlüsselwort verwenden, da diese Dateien zum Kompilieren der ausführbaren Datei selbst benötigt werden. Ich weiß jedoch nicht, ob es eine Verwendung für INTERFACEoder PUBLICauf einer ausführbaren Datei gibt.
TManhente
13
Die Schlüsselwörter INTERFACE, PUBLIC und PRIVATE sind erforderlich, um den Umfang der folgenden Argumente anzugeben. PRIVATE- und PUBLIC-Elemente füllen die INCLUDE_DIRECTORIES-Eigenschaft von <ziel>. PUBLIC- und INTERFACE-Elemente füllen die INTERFACE_INCLUDE_DIRECTORIES-Eigenschaft von <ziel>. Die folgenden Argumente geben include-Verzeichnisse an.
Um die Dokumentation mit meinen eigenen Worten neu zu formulieren:
Sie möchten der Liste der Include-Verzeichnisse für ein Ziel ein Verzeichnis hinzufügen
Mit PRIVATE wird das Verzeichnis zu den Include-Verzeichnissen des Ziels hinzugefügt
Mit INTERFACE wird das Ziel nicht geändert, aber INTERFACE_INCLUDE_DIRECTORIES wird um das Verzeichnis erweitert. Die Variable ist eine Liste öffentlicher Include-Verzeichnisse für eine Bibliothek.
Mit PUBLIC werden beide Aktionen von PRIVATE und INTERFACE ausgeführt.
Ich habe die CMAKE-Dokumentation durchgesehen, aber ich habe immer noch nicht verstanden, was sie tatsächlich bedeuten und in welchem Kontext (Dateien erstellen oder wie sie kompiliert werden).
Poorna
@ Sirish: Ich habe versucht, die Dokumentation neu zu formulieren, hoffe das hilft.
Antworten:
Diese Schlüsselwörter werden verwendet, um festzustellen, wann die Liste der Include-Verzeichnisse benötigt wird, die Sie an das Ziel übergeben. Bis wann bedeutet dies, ob diese Include-Verzeichnisse benötigt werden:
Wenn CMake ist ein Ziel der Zusammenstellung, verwendet er die Ziele
INCLUDE_DIRECTORIES
,COMPILE_DEFINITIONS
undCOMPILE_OPTIONS
Eigenschaften. Wenn Sie dasPRIVATE
Schlüsselwort intarget_include_directories()
und gleichermaßen verwenden, weisen Sie CMake an, diese Zieleigenschaften zu füllen.Wenn CMake eine Abhängigkeit zwischen einem Ziel A und einem anderen Ziel B erkennt (wie bei Verwendung des
target_link_libraries(A B)
Befehls), werden dieB
Verwendungsanforderungen transitiv an dasA
Ziel weitergegeben. Diese Zielverwendungsanforderungen sind die Include-Verzeichnisse, Kompilierungsdefinitionen usw., die jedes Ziel, von dem es abhängt,B
erfüllen muss. Sie werden durch dieINTERFACE_*
Version der oben aufgeführten Eigenschaften (wieINTERFACE_INCLUDE_DIRECTORIES
) angegeben undINTERFACE
beim Aufrufen dertarget_*()
Befehle mit dem Schlüsselwort gefüllt.Das
PUBLIC
Schlüsselwort bedeutet ungefährPRIVATE + INTERFACE
.Angenommen, Sie erstellen eine Bibliothek
A
, die einige Boost-Header verwendet. Du würdest:target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})
Wenn Sie nur diese Boost-Header in Ihren Quelldateien (.cpp
) oder privaten Header-Dateien (.h
) verwenden.target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})
Wenn Sie diese Boost-Header nicht in Ihren Quelldateien verwenden (sie müssen daher nicht kompiliert werdenA
). Ich kann mir dafür kein reales Beispiel vorstellen.target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})
Wenn Sie diese Boost-Header in Ihren öffentlichen Header-Dateien verwenden, die BEIDE in einigenA
Quelldateien enthalten sind und möglicherweise auch in einem anderen Client IhrerA
Bibliothek enthalten sind.In der CMake 3.0-Dokumentation finden Sie weitere Details zu diesen Eigenschaften der Buildspezifikation und den Verwendungsanforderungen .
quelle
INTERFACE
.target_include_directories(libname INTERFACE include PRIVATE include/libname)
. Dies bedeutet, dass Sie Dateien direkt in Ihre Bibliothek aufnehmen können, aber als Benutzer der Bibliothek müssen Sielibname/
zuerst einfügen .target_include_directories()
ein ausführbares Ziel anfordern, wenn Sie Include-Verzeichnisse festlegen müssen, in denen Header-Dateien gefunden werden sollen, die von diesen ausführbaren Dateien verwendet werden (z. B. Boost :: Program_options, wenn Sie damit Argumente in Ihrermain()
Funktion analysieren ). .PRIVATE
In diesem Fall würden Sie wahrscheinlich das Schlüsselwort verwenden, da diese Dateien zum Kompilieren der ausführbaren Datei selbst benötigt werden. Ich weiß jedoch nicht, ob es eine Verwendung fürINTERFACE
oderPUBLIC
auf einer ausführbaren Datei gibt.Aus der Dokumentation: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Um die Dokumentation mit meinen eigenen Worten neu zu formulieren:
quelle