Ответ 1
Происхождение проблемы - это не сама команда target_include_directories
, а попытка install
целевой, которая имеет общий или интерфейс, включать в себя каталог, префикс в путь источника.
В то время как совершенно бесплатно и желательно использовать абсолютные пути при создании библиотеки с нуля, сторонняя библиотека, которая втягивает в предварительно созданную версию этой библиотеки, вероятно, захочет использовать другой путь include. В конце концов, вы не хотите, чтобы все ваши пользователи зеркалировали структуру каталогов вашей машины сборки, чтобы закончить путь справа.
Механизм упаковки CMake обеспечивает поддержку обоих этих вариантов использования: вы можете вытащить библиотеку непосредственно из дерева сборки (то есть проверить источник, построить его и точку find_package()
в каталог) или из установочного каталога (запустите make INSTALL
, чтобы скопировать встроенные файлы в каталог установки и указать find_package()
в этот каталог). Последний подход должен быть перемещаемым (т.е. Я строю и устанавливаю на свою машину, отправляю вам результирующий каталог, и вы сможете использовать его на своем компьютере из другой структуры каталогов), в то время как первая не является.
Это очень аккуратная функция, но вы должны учитывать ее при настройке каталогов include. Указание руководства для target_include_directories
:
Включение требований к использованию каталогов обычно различается между build-tree и установочное дерево.
BUILD_INTERFACE
иINSTALL_INTERFACE
выражения генератора могут использоваться для описания отдельные требования к использованию, основанные на местоположении использования. Относительный пути допускаются в выраженииINSTALL_INTERFACE
и интерпретируется относительно префикса установки. Например:target_include_directories(mylib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib> $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib )
BUILD_INTERFACE
и INSTALL_INTERFACE
выражения генератора делают все волшебство:
$<INSTALL_INTERFACE:...>
Содержимое
...
, когда свойство экспортируется с помощьюinstall(EXPORT)
, и пустым в противном случае.
$<BUILD_INTERFACE:...>
Содержимое
...
, когда свойство экспортируется с помощьюexport()
, или когда цель используется другой целью в одной и той же сборке. Расширяется до пустой строки в противном случае.