CMake target_include_directories Bedeutung des Gültigkeitsbereichs

97

Was ist die Bedeutung des Schlüsselworts PUBLIC, PRIVATEund INTERFACEzu CMake der Zusammenhang target_include_directories?

Poorna
quelle

Antworten:

117

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 B Verwendungsanforderungen 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 der CMake 3.0-Dokumentation finden Sie weitere Details zu diesen Eigenschaften der Buildspezifikation und den Verwendungsanforderungen .

TManhente
quelle
18
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.

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:

  • 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.
usr1234567
quelle
4
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.
usr1234567