Який сенс ключового слова PUBLIC
, PRIVATE
і INTERFACE
пов'язаний з CMake - х target_include_directories
?
Відповіді:
Ці ключові слова використовуються для того, щоб визначити, коли потрібен список включених каталогів, які ви передаєте цільовій. До , коли , це означає , що, в разі їх необхідності , включають каталоги:
Коли 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 містить більше деталей щодо цієї специфікації збірки та властивостей вимог до використання .
INTERFACE
. target_include_directories(libname INTERFACE include PRIVATE include/libname)
. Це означає, що у вашій бібліотеці ви можете включати файли безпосередньо, але як користувач бібліотеки ви повинні вставити libname/
спочатку.
target_include_directories()
до виконуваної цілі, якщо вам потрібно встановити включати каталоги, де будуть знаходитись файли заголовків, які використовуються цими виконуваними файлами (наприклад: Boost :: Program_options, якщо ви використовуєте його для синтаксичного аналізу аргументів у вашій main()
функції) . Ви, мабуть, використовували б PRIVATE
ключове слово в цьому випадку, оскільки ці файли потрібні для компіляції самого виконуваного файлу. Я не знаю, чи є якесь застосування для виконуваного файлу INTERFACE
чи PUBLIC
для нього.
Ключові слова ІНТЕРФЕЙС, ПУБЛІЧНІ та ПРИВАТНІ вимагають вказати обсяг наступних аргументів. ПРИВАТНІ та ПУБЛІЧНІ елементи заповнять властивість INCLUDE_DIRECTORIES <target>. Елементи PUBLIC та INTERFACE заповнять властивість INTERFACE_INCLUDE_DIRECTORIES <target>. Наступні аргументи вказують включати каталоги.
З документації: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Щоб перефразувати документацію своїми словами: