Я работаю над библиотекой C++ 11 только для заголовков, которая использует современный CMake. Под «современным» я имею в виду не только использование CMake v3.0+, но и попытку максимально использовать лучшие практики из говорить Дэниела Пфайфера.
Я провел некоторое исследование по своему вопросу, но ответы в основном касаются модификации LINK_FLAGS непосредственно на глобальном уровне, чего я не хочу. Прямо сейчас в моем проекте мне требуется минимальная версия 3.9.0 CMake из-за некоторых функций, которые я использую.
У меня вопрос о том, можно ли / как добавить LINK_FLAGS из двух моих зависимостей: BLAS и LAPACK. По сути, у меня есть следующий отрывок из моего файла CMakeLists.txt:
cmake_minimum_required(VERSION 3.9.0)
project(polo VERSION 1.0.0 LANGUAGES C CXX)
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
add_library(polo INTERFACE)
add_library(polo::polo ALIAS polo)
target_compile_features(polo INTERFACE cxx_std_11)
target_include_directories(polo
INTERFACE
$<BUILD_INTERFACE:${polo_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(polo
INTERFACE
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
)
set_property(
TARGET
polo
PROPERTY LINK_FLAGS
${BLAS_LINKER_FLAGS}
${LAPACK_LINKER_FLAGS}
)
Насколько я могу понять из документации модулей FindBLAS и FindLAPACK, мне нужно проинформировать моих пользователей хотя бы о {BLAS,LAPACK}_LIBRARIES и {BLAS,LAPACK}_LINKER_FLAGS. Что касается первого, я думаю, что решил проблему должным образом. Однако для последнего мне нужно использовать либо set_target_properties, либо set_property. Последнее, кажется, дает мне более четкое решение, поскольку я могу использовать обе переменные, поступающие из модулей Find{BLAS,LAPACK}, вместе. Когда я пытаюсь собрать свою библиотеку, используя вышеуказанное решение, я получаю очевидную ошибку:
CMake Error at src/CMakeLists.txt:32 (set_property):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "LINK_FLAGS" is not allowed.
У меня два вопроса:
*_LINKER_FLAGS, идущий от модулей, и,Что касается пункта 2. выше, я видел несколько предложений / ответов по использованию target_link_libraries, но я не уверен, стоит ли это делать.
Спасибо за уделенное время!
Да, @MatthieuBrucher, я имею в виду пользователей библиотеки. В конце концов, моя цель - создать социальную библиотеку с поддержкой cmake, в которой вы можете просто использовать add_library(foo foo.c) и target_link_libraries(foo PRIVATE polo::polo) в качестве пользователя.





Приятно то, что вы можете предоставить для них вспомогательный .cmake (называемый polo-config.cmake).
Один из вариантов внутри файла .cmake - создать Библиотека IMPORTED, в котором вы храните нужные вам флаги, возможно, на этот раз как PUBLIC, чтобы они передавались следующему пользователю.
Конечно, вам нужно правильно добавить библиотеку, настроить пути включения, путь к библиотеке ...
Благодарю за ваш ответ. Я ценю ваше время, но я все еще не понимаю некоторых вещей. Во-первых, я уже предоставляю потребителям моей библиотеки файл конфигурации, который обнаруживает CMake после вызова find_package(polo). В этом файле уже перечислены мои зависимости, которые я позже использую в своем проекте CMake. Зачем любому потребителю polo нужно что-то знать о моих зависимостях, если я правильно их определил? Я имею в виду, почему я должен снова перечислять свои библиотеки, как в примере, как вы предоставили?
Кстати, у вас мог бы есть опечатка в определении вашей функции --- target_include_directories должен читать target_link_libraries для BLAS и LAPACK, я полагаю, или?
Это свойства уже построенной цели. Но они находятся на языке CMake, а не в самом файле. Итак, вам нужен способ распространения этих флагов от вашей цели polo (которая не существует для пользователя) на цель пользователя, и то, что делает файл конфигурации.
И действительно, это была target_link_library. Например, для pybind11, libsimdpp они предоставляют функции в своих CMakeLists или своих .cmake для создания правильных ссылок с соответствующими флагами.
Не могли бы вы также предоставить ссылки в своем комментарии или ответе на проекты CMake этих библиотек, чтобы я мог проверить? Я имею в виду, что я являюсь распространяю флаги и требования от моих зависимостей до потребителя, если вы проверите мой CMake проект. Но я не могу распространять LINK_FLAGS, потому что я являюсь библиотекой ИНТЕРФЕЙСА.
Также добавлено ИМПОРТНОЕ решение, которое может лучше соответствовать вашим целям (не уверен, что вы должны сделать используемые библиотеки частью вашего интерфейса, особенно если они являются общими библиотеками? За исключением blas / lapack, но имеет ли значение, чтобы они были частными?)
Спасибо. Буду признателен, если вы измените свой ответ так, чтобы в качестве решения использовалась версия IMPORTED, а это именно то, что мне нужно. Кажется, проблема решена. Я не хочу отвечать на свой вопрос, поскольку эта идея пришла вам в голову, но если вы напишете: add_library(foo UNKNOWN IMPORTED); target_link_libraries(foo ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES}); set_property(TARGET foo PROPERTY LINK_FLAGS ${BLAS_LINKER_FLAGS} ${LAPACK_LINKER_FLAGS}), похоже, это сработает. Кстати, видимо, использовать свойства INTERFACE можно только в библиотеках IMPORTED. РЕДАКТИРОВАТЬ. У этого подхода есть и другие проблемы.
Решение IMPORTED выдает ошибку «Нет правила для создания цели ...». Мне нужно проверить дальше.
Готово, удалил "старое" решение.
Уважаемый Матье, я ценю ваше время и еще раз благодарю вас за ваш ответ, но, к сожалению, я отвечу на свой вопрос из ответа ребят из CMake, просто чтобы иметь возможность дать правильный / правильный ответ.
Прежде всего, я приношу свои извинения сообществу за проблему с кросс-постинг.
Матье пытался помочь мне двумя вариантами:
LINK_FLAGS, и,IMPORTED, который он оставил в качестве окончательного ответа (пожалуйста, смотрите комментарии для мотивации).К сожалению, ни одно из этих решений не работает. Первый - это не чистый способ информирования потребителя о ваших зависимостях. Вторая версия, похоже, работает с библиотеками INTERFACE, но у любого потребителя, который зависит от библиотеки INTERFACE, которая создает объект, такого как, например, C-API библиотеки только для заголовков, которая создает библиотеку SHARED, возникают проблемы при сборке и установке. библиотека IMPORTED.
Похоже, что решение состоит в использовании CMake v3.13 и более поздних версий, которые на дату публикации находятся в состоянии кандидата на выпуск (rc3). Видимо, CMake v3.13 будет внедрять INTERFACE_LINK_OPTIONS для таких целей.
РЕДАКТИРОВАТЬ. CMake v3.13 был вышел.
Что вы имеете в виду под своими пользователями? Вы имеете в виду людей, пользующихся вашей библиотекой?