Установите LINK_FLAGS для библиотек INTERFACE в cmake

Я работаю над библиотекой 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.

У меня два вопроса:

  1. Стоит ли вообще использовать *_LINKER_FLAGS, идущий от модулей, и,
  2. Если да, как мне полностью интегрировать их в мой проект CMake?

Что касается пункта 2. выше, я видел несколько предложений / ответов по использованию target_link_libraries, но я не уверен, стоит ли это делать.

Спасибо за уделенное время!

Что вы имеете в виду под своими пользователями? Вы имеете в виду людей, пользующихся вашей библиотекой?

Matthieu Brucher 19.11.2018 13:45

Да, @MatthieuBrucher, я имею в виду пользователей библиотеки. В конце концов, моя цель - создать социальную библиотеку с поддержкой cmake, в которой вы можете просто использовать add_library(foo foo.c) и target_link_libraries(foo PRIVATE polo::polo) в качестве пользователя.

Arda Aytekin 19.11.2018 14:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
1 214
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Приятно то, что вы можете предоставить для них вспомогательный .cmake (называемый polo-config.cmake).

Один из вариантов внутри файла .cmake - создать Библиотека IMPORTED, в котором вы храните нужные вам флаги, возможно, на этот раз как PUBLIC, чтобы они передавались следующему пользователю.

Конечно, вам нужно правильно добавить библиотеку, настроить пути включения, путь к библиотеке ...

Благодарю за ваш ответ. Я ценю ваше время, но я все еще не понимаю некоторых вещей. Во-первых, я уже предоставляю потребителям моей библиотеки файл конфигурации, который обнаруживает CMake после вызова find_package(polo). В этом файле уже перечислены мои зависимости, которые я позже использую в своем проекте CMake. Зачем любому потребителю polo нужно что-то знать о моих зависимостях, если я правильно их определил? Я имею в виду, почему я должен снова перечислять свои библиотеки, как в примере, как вы предоставили?

Arda Aytekin 19.11.2018 16:16

Кстати, у вас мог бы есть опечатка в определении вашей функции --- target_include_directories должен читать target_link_libraries для BLAS и LAPACK, я полагаю, или?

Arda Aytekin 19.11.2018 16:17

Это свойства уже построенной цели. Но они находятся на языке CMake, а не в самом файле. Итак, вам нужен способ распространения этих флагов от вашей цели polo (которая не существует для пользователя) на цель пользователя, и то, что делает файл конфигурации.

Matthieu Brucher 19.11.2018 16:22

И действительно, это была target_link_library. Например, для pybind11, libsimdpp они предоставляют функции в своих CMakeLists или своих .cmake для создания правильных ссылок с соответствующими флагами.

Matthieu Brucher 19.11.2018 16:23

Не могли бы вы также предоставить ссылки в своем комментарии или ответе на проекты CMake этих библиотек, чтобы я мог проверить? Я имею в виду, что я являюсь распространяю флаги и требования от моих зависимостей до потребителя, если вы проверите мой CMake проект. Но я не могу распространять LINK_FLAGS, потому что я являюсь библиотекой ИНТЕРФЕЙСА.

Arda Aytekin 19.11.2018 16:56

Также добавлено ИМПОРТНОЕ решение, которое может лучше соответствовать вашим целям (не уверен, что вы должны сделать используемые библиотеки частью вашего интерфейса, особенно если они являются общими библиотеками? За исключением blas / lapack, но имеет ли значение, чтобы они были частными?)

Matthieu Brucher 19.11.2018 17:03

Спасибо. Буду признателен, если вы измените свой ответ так, чтобы в качестве решения использовалась версия 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. РЕДАКТИРОВАТЬ. У этого подхода есть и другие проблемы.

Arda Aytekin 19.11.2018 17:14

Решение IMPORTED выдает ошибку «Нет правила для создания цели ...». Мне нужно проверить дальше.

Arda Aytekin 19.11.2018 17:16

Готово, удалил "старое" решение.

Matthieu Brucher 19.11.2018 17:22

Уважаемый Матье, я ценю ваше время и еще раз благодарю вас за ваш ответ, но, к сожалению, я отвечу на свой вопрос из ответа ребят из CMake, просто чтобы иметь возможность дать правильный / правильный ответ.

Arda Aytekin 19.11.2018 21:09
Ответ принят как подходящий

Прежде всего, я приношу свои извинения сообществу за проблему с кросс-постинг.

Матье пытался помочь мне двумя вариантами:

  1. Предоставление вспомогательной функции, чтобы потребители библиотеки могли вызвать функцию для правильной обработки LINK_FLAGS, и,
  2. Вариант библиотеки IMPORTED, который он оставил в качестве окончательного ответа (пожалуйста, смотрите комментарии для мотивации).

К сожалению, ни одно из этих решений не работает. Первый - это не чистый способ информирования потребителя о ваших зависимостях. Вторая версия, похоже, работает с библиотеками INTERFACE, но у любого потребителя, который зависит от библиотеки INTERFACE, которая создает объект, такого как, например, C-API библиотеки только для заголовков, которая создает библиотеку SHARED, возникают проблемы при сборке и установке. библиотека IMPORTED.

Похоже, что решение состоит в использовании CMake v3.13 и более поздних версий, которые на дату публикации находятся в состоянии кандидата на выпуск (rc3). Видимо, CMake v3.13 будет внедрять INTERFACE_LINK_OPTIONS для таких целей.

РЕДАКТИРОВАТЬ. CMake v3.13 был вышел.

@MatthieuBrucher, CMake v3.13 был выпущен, и команда target_link_options, похоже, работает.

Arda Aytekin 21.11.2018 16:12

Другие вопросы по теме