CMake: target_include_directories () печатает ошибку, когда я пытаюсь добавить сам исходный каталог или один из его подкаталогов

Я пишу библиотеку C ++ (только для заголовков) и использую CMake для создания моих (Visual Studio) проектов и файлов решений. Я также пишу набор тестов, который является частью того же проекта CMake.

Моя проблема возникает, когда я вызываю target_include_directories () для цели, представляющей мою библиотеку только для заголовков, чтобы потребители моей библиотеки могли найти ее заголовочные файлы. Я получаю следующее сообщение об ошибке (хотя генерация НЕ прерывается).

CMake Error in CMakeLists.txt:
Target "Fonts" INTERFACE_INCLUDE_DIRECTORIES property contains path:

"D:/Projects/GPC/fonts/include"
which is prefixed in the source directory.

(D: / Projects / GPC / Fonts является каталогом верхнего уровня моего библиотечного проекта. Между прочим, проблема остается, если я перемещаю заголовочные файлы в верхний каталог.)

Обидная строка в моем CMakeLists.txt такова (адаптировано для простоты):

target_include_directories(Fonts INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")

Я не понимаю, что я делаю не так. Без target_include_directories () код потребительских проектов просто не может включать мои заголовочные файлы (если только в установленной форме, но я до сих пор не дошел до этого, и в любом случае я хочу иметь возможность использовать мою библиотеку из ее дерева сборки , без установки.)

Я чувствую, что мне здесь чего-то не хватает; все же я искал часы, не находя решения или объяснения.

18

Решение

Происхождение проблемы не в target_include_directories сама команда, но попытка install цель, которая имеет общедоступный или интерфейсный каталог с префиксом в исходном пути.

Хотя при создании библиотеки с нуля совершенно нормально и желательно использовать абсолютные пути, сторонняя библиотека, использующая предварительно собранную версию этой библиотеки, вероятно, захочет использовать другой путь включения. В конце концов, вы не хотите, чтобы все ваши пользователи отражали структуру каталогов вашей машины сборки, просто чтобы попасть в правильный путь включения.

Механизм упаковки CMake обеспечивает поддержку для обоих этих вариантов использования: вы можете извлечь библиотеку непосредственно из дерева сборки (то есть проверить источник, собрать его и указать find_package() в каталог) или из каталога установки (запустите make INSTALL скопировать собранный материал в каталог установки и указать find_package() в тот каталог). Последний подход должен быть перемещаемым (то есть я собираю и устанавливаю на своем компьютере, отправляю вам полученный каталог, и вы сможете использовать его на своем компьютере из другой структуры каталогов), тогда как первый — нет.

Это очень удобная функция, но вы должны учитывать ее при настройке включаемых каталогов. Цитирование руководства для target_include_directories:

Требования к использованию каталогов обычно различаются между
дерево сборки и дерево установки. 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()или когда цель используется другой целью в той же сборочной системе.
В противном случае расширяется до пустой строки.

41

Другие решения


По вопросам рекламы [email protected]