Эти ключевые слова используются, чтобы указать, когда нужен список включаемых каталогов, который вы передаете целевой папке. К , когда , это означает , что, если таковые необходимы , включают каталоги:
Чтобы скомпилировать эту цель.
Для компиляции других целей, которые зависят от этой цели (например, с использованием ее общедоступных заголовков).
В обеих описанных выше ситуациях.
Когда CMake компилирует цель, он использует цели INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSи COMPILE_OPTIONSсвойство. Когда вы используете PRIVATEключевое слово in 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библиотеки.
Что касается реального примера 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
Ключевые слова INTERFACE, PUBLIC и PRIVATE необходимы для определения области действия следующих аргументов. Элементы PRIVATE и PUBLIC заполнят свойство INCLUDE_DIRECTORIES <target>. Элементы PUBLIC и INTERFACE заполнят свойство INTERFACE_INCLUDE_DIRECTORIES <target>. Следующие аргументы указывают подключаемые каталоги.
вы хотите добавить каталог в список включаемых каталогов для цели
с PRIVATE каталог добавляется в целевые каталоги include
с INTERFACE цель не изменяется, но INTERFACE_INCLUDE_DIRECTORIES расширяется каталогом. Переменная представляет собой список общедоступных подключаемых каталогов для библиотеки.
с PUBLIC выполняются оба действия из PRIVATE и INTERFACE.
Ответы:
Эти ключевые слова используются, чтобы указать, когда нужен список включаемых каталогов, который вы передаете целевой папке. К , когда , это означает , что, если таковые необходимы , включают каталоги:
Когда CMake компилирует цель, он использует цели
INCLUDE_DIRECTORIES
,COMPILE_DEFINITIONS
иCOMPILE_OPTIONS
свойство. Когда вы используетеPRIVATE
ключевое слово intarget_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
от него.Из документации: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Перефразируя документацию своими словами:
источник