Який сенс ключового слова 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
Щоб перефразувати документацію своїми словами: