CMake target_include_directories значення області дії


Відповіді:


125

Ці ключові слова використовуються для того, щоб визначити, коли потрібен список включених каталогів, які ви передаєте цільовій. До , коли , це означає , що, в разі їх необхідності , включають каталоги:

  • Щоб скомпілювати цю ціль самостійно.
  • Компілювати інші цілі, які залежать від цієї цілі (наприклад, використовувати її загальнодоступні заголовки).
  • В обох вищевказаних ситуаціях.

Коли CMake компілює мета, він використовує цілі INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSі COMPILE_OPTIONSвластивість. Коли ви використовуєте PRIVATEключове слово як target_include_directories()і подібне, ви кажете CMake заповнити ці цільові властивості.

Коли CMake виявляє залежність між ціллю A та іншою ціллю B (наприклад, коли ви використовуєте target_link_libraries(A B)команду), він транзитивно поширює B вимоги щодо використання до Aцілі. Ці цільові вимоги використання включають каталоги, визначення компіляції тощо, яким Bповинна відповідати будь-яка ціль, від якої залежить . Вони визначаються INTERFACE_*версією властивостей, перерахованих вище (наприклад INTERFACE_INCLUDE_DIRECTORIES), і заповнюються за допомогою INTERFACEключового слова під час виклику target_*()команд.

PUBLICКлючове слово означає приблизно PRIVATE + INTERFACE.

Отже, припустимо, ви створюєте бібліотеку, Aяка використовує деякі заголовки Boost. Ви зробите:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})якщо ви використовуєте лише ті заголовки Boost у вихідних файлах ( .cpp) або приватні файли заголовків ( .h).
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})якщо ви не використовуєте заголовки Boost у вихідних файлах (отже, вони не потребують їх компіляції A). Я фактично не можу придумати для цього реальний приклад.
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})якщо ви використовуєте ті заголовки Boost у своїх загальнодоступних файлах заголовків, які ВХОДЯТЬ ОБОЄ в деякі Aвихідні файли, а також можуть бути включені в будь-який інший клієнт вашої Aбібліотеки.

Документація CMake 3.0 містить більше деталей щодо цієї специфікації збірки та властивостей вимог до використання .


18
Що стосується реального прикладу INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Це означає, що у вашій бібліотеці ви можете включати файли безпосередньо, але як користувач бібліотеки ви повинні вставити libname/спочатку.
KaareZ

2
Ці відповіді мають сенс для мене створення бібліотек. Але як щодо виклику target_include_directories для цілі, яка є виконуваним файлом?
Норман Пелле

1
@NormanPellet: Ви можете зателефонувати target_include_directories()до виконуваної цілі, якщо вам потрібно встановити включати каталоги, де будуть знаходитись файли заголовків, які використовуються цими виконуваними файлами (наприклад: Boost :: Program_options, якщо ви використовуєте його для синтаксичного аналізу аргументів у вашій main()функції) . Ви, мабуть, використовували б PRIVATEключове слово в цьому випадку, оскільки ці файли потрібні для компіляції самого виконуваного файлу. Я не знаю, чи є якесь застосування для виконуваного файлу INTERFACEчи PUBLICдля нього.
TManhente

13

Ключові слова ІНТЕРФЕЙС, ПУБЛІЧНІ та ПРИВАТНІ вимагають вказати обсяг наступних аргументів. ПРИВАТНІ та ПУБЛІЧНІ елементи заповнять властивість INCLUDE_DIRECTORIES <target>. Елементи PUBLIC та INTERFACE заповнять властивість INTERFACE_INCLUDE_DIRECTORIES <target>. Наступні аргументи вказують включати каталоги.

З документації: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

Щоб перефразувати документацію своїми словами:

  • ви хочете додати каталог до списку включити каталог для цілі
  • за допомогою PRIVATE каталог додається до каталогів включення цілі
  • з INTERFACE ціль не змінюється, але INTERFACE_INCLUDE_DIRECTORIES розширюється каталогом. Змінна - це список загальнодоступних каталогів для бібліотеки.
  • з PUBLIC виконуються як дії від PRIVATE, так і INTERFACE.

5
Я переглянув документацію CMAKE, але досі не зрозумів, що вони насправді означають і в якому контексті (створювати файли чи як їх компілювати)?
Sirish

@Sirish: Я намагався переформулювати документацію, сподіваюся, що це допоможе.
usr1234567
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.