CMake: Is there a way to get a list of imported targets that belong to a package

Viewed 1993

Sometimes I wish I could get a list of the imported targets that belong to a package. Is there a variable that holds them?

This would allow me to write something like this

find_package(Qt5 CONFIG REQUIRED)
message("Imported Qt5 targets: ${Qt5_IMPORTED_TARGETS}") # speculative code

With my current knowledge I have to rely on the documentation of the package to give me the names of all imported targets. Reading them from a variable or property would be easier.

2 Answers

CMake 3.21 introduced the directory property IMPORTED_TARGETS that can be used to get a list of all imported targets. This can be used to derive a list of targets that were imported by a single find_package() call when it is queried before and after the call to find_package(). The code could look something like this:

...
get_property(importTargets DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

get_property(importTargetsAfter DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS)
list(REMOVE_ITEM importTargetsAfter ${importTargets})

message("${importTargetsAfter}")
...

Usually it is good enough to only print the list of all imported targets and guess from the names which of them were imported by the package of interest.

Not precisely what you asked for, but for Qt5, one can do:

cmake_minimum_required(VERSION 3.14)

project(so)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

get_cmake_property(_variableNames VARIABLES)
foreach(_variableName ${_variableNames})
  if(_variableName MATCHES "^Qt5.*LIBRARIES")
      message(STATUS "${_variableName}")
      message(STATUS "\t${${_variableName}}")
  endif()
endforeach()

Example output:

-- Qt5Core_LIBRARIES
--  Qt5::Core
-- Qt5Gui_EGL_LIBRARIES
--  Qt5::Gui_EGL
-- Qt5Gui_LIBRARIES
--  Qt5::Gui
-- Qt5Gui_OPENGL_LIBRARIES
--  Qt5::Gui_GL
-- Qt5Widgets_LIBRARIES
--  Qt5::Widgets
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/build

Caveat with approach: One needs to know the component names.

Related