Есть ли правильный и чистый способ добавления зависимостей к цели IMPORTED
в CMake (v3.17)?
Я использую CommonAPI-DBus
, который устанавливает файл CommonAPI-DBusConfig.cmake
, но не определяет «полезные» цели, поэтому я хочу обернуть его своей собственной целью. Мое предпочтительное имя - CommonAPI::DBus
(потому что в моей идеальной настройке DBus
был бы одним из многих компонентов в пространстве имен CommonAPI
), а из-за ::
он должен быть импортированной целью, хорошо.
CommonAPI-DBus
зависит от DBus-1, который нигде не импортирован неявно, поэтому я хочу, чтобы моя цель также привнесла DBus-1 (который я могу получить с помощью find_package(DBus-1)
), и здесь я сталкиваюсь с проблемами .
Я вижу два варианта:
1) Скопируйте свойства dbus-1
в мою цель:
Пакет DBus-1
создает dbus-1
target, поэтому я могу настроить свою цель, например:
if(NOT TARGET CommonAPI::DBus)
add_library(CommonAPI::DBus INTERFACE IMPORTED)
set_target_properties(CommonAPI::DBus PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${COMMONAPI_DBUS_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${CommonAPI_DBus_LIBRARY}"
)
foreach(var IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES INTERFACE_COMPILE_DEFINITIONS)
get_target_property(tmp dbus-1 ${var})
if(tmp)
message("Coping ${var} from dbus-1: ${tmp}")
set_property(TARGET CommonAPI::DBus APPEND PROPERTY ${var} ";${tmp}")
endif()
endforeach()
# Get the dbus-1 library
get_target_property(tmp dbus-1 IMPORTED_LOCATION)
set_property(TARGET CommonAPI::DBus APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${tmp})
unset(tmp)
endif()
Но это довольно некрасиво, и много кода для поддержки
2) Игнорируйте dbus-1
target и использовать экспортированные переменные
find_package(dbus-1)
экспортирует DBus1_INCLUDE_DIR
и DBus1_LIBRARY
, et c. Я мог бы просто использовать эти свойства, но это похоже на «старый» способ использования CMake. На мой взгляд, главным преимуществом CMake является возможность определять цели, которые диктуют собственный интерфейс и инкапсулировать их логические настройки c, а не артефакты нижестоящего потока с использованием частных переменных из его сценария настройки.
Я полагаю, что хочу - это цель INTERFACE
, которая использует ::
, чтобы было ясно, что я использую пространство имен.