В чем смысл ключевого слова PUBLIC, PRIVATE и INTERFACE, связанного с CMake target_include_directories?
Значение CMake target_include_directories
Ответ 1
Эти ключевые слова используются для указания , когда необходим список каталогов include, которые вы передаете цели. По , когда, это означает, что нужны те, которые содержат каталоги:
- Скомпилировать эту цель.
- Чтобы скомпилировать другие цели, которые зависят от этой цели (например, с использованием ее публичных заголовков).
- В обеих указанных ситуациях.
Когда CMake компилирует цель, он использует целевые объекты INCLUDE_DIRECTORIES, COMPILE_DEFINITIONS и COMPILE_OPTIONS. Когда вы используете ключевое слово PRIVATE в target_include_directories() и аналогично, вы указываете CMake для заполнения этих целевых свойств.
Когда CMake обнаруживает зависимость между целью A и другой целью B (например, когда вы используете команду target_link_libraries(A B)), она транзитно распространяет требования к использованию B к целевому объекту A. Эти целевые требования использования - это каталоги include, определения компиляции и т.д., Которые должны соответствовать любой цели, которая зависит от 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 в своих общедоступных файлах заголовков, которые включены в BOTH в некоторых исходных файлахAи могут также быть включены в любой другой клиент вашей библиотекиA.
Документация CMake 3.0 содержит более подробную информацию об этом свойствах сборки и условиях использования.
Ответ 2
Ключевые слова INTERFACE, PUBLIC и PRIVATE должны указывать область действия следующих аргументов. ЧАСТНЫЕ и ПУБЛИЧНЫЕ заполняют свойство INCLUDE_DIRECTORIES <target> . ОБЩЕСТВЕННЫЕ и Элементы INTERFACE заполнят INTERFACE_INCLUDE_DIRECTORIES свойство <target> . Следующие аргументы указывают: каталоги.
Из документации: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Чтобы перефразировать документацию своими словами:
- вы хотите добавить каталог в список каталога include для целевого
- с PRIVATE каталог добавляется в целевые каталоги include
- с INTERFACE цель не изменяется, но INTERFACE_INCLUDE_DIRECTORIES расширяется каталогом. Переменная - это список общедоступных каталогов для библиотеки.
- с PUBLIC выполняются оба действия из PRIVATE и INTERFACE.