Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

package

cmake

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.

like image 269
Knitschi Avatar asked Aug 03 '17 08:08

Knitschi


People also ask

What does Find_package do in CMake?

CMake searches for a file called Find<package>. cmake in the CMAKE_MODULE_PATH followed by the CMake installation. If the file is found, it is read and processed by CMake. It is responsible for finding the package, checking the version, and producing any needed messages.

What is imported target in CMake?

IMPORTED targets are used to convert files outside of a CMake project into logical targets inside of the project. IMPORTED targets are created using the IMPORTED option of the add_executable() and add_library() commands. No build files are generated for IMPORTED targets.

Where does CMake Find_package look?

CMake ships with its own set of built-in find_package scripts, and their location is in the default CMAKE_MODULE_PATH. The more normal use case for dependent projects that have been CMakeified would be to use CMake's external_project command and then include the Use[Project].


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.

like image 60
Knitschi Avatar answered Nov 22 '22 15:11

Knitschi


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.

like image 25
Nehal J Wani Avatar answered Nov 22 '22 15:11

Nehal J Wani