Getting imported targets via find_package?

The CMake manual for Qt 5 uses find_package and says:

Imported targets are created for each Qt module. Imported target names should be preferred over using a variable of type Qt5<Module>_LIBRARIES in CMake commands such as target_link_libraries.

Is it special for Qt or find_package create imported targets for all libraries? The documentation for find_package in CMake 3.0 states:

When a package is found, information about a specific package is provided through the variables and imported targets documented by the package itself.

The manual for cmake packages says:

The result of using find_package is either a set of IMPORTED targets, or a set of variables corresponding to the information related to the construction.

But I did not see another FindXXX.cmake - a script where the documentation says that the imported object was created.

+6
source share
2 answers

find_package is a two-headed beast these days:

CMake provides direct support for two forms of packages, Config-file Packages and Find-Module Packages.

A source

Now what does that mean?

Find-module packages are the ones you are most likely familiar with. They execute a CMake code script (like this one ) that does a bunch of calls to functions like find_library and find_path to figure out where to find the library.

The great advantage of this approach is that it is extremely general. As long as there is something in the file system, we can find it. The big disadvantage is that it often provides a little more information than the physical location of this. That is, the result of an operation with a search module, as a rule, is simply a bunch of file system paths. This means that modeling like transitive dependencies or multiple assembly configurations is quite complicated.

This becomes especially painful if the thing you are trying to find is itself built with CMake. In this case, you already have a bunch of things modeled in your build scripts that you now need to carefully rebuild to find the script so that it becomes available for future projects.

This is where the configuration file files are displayed. Unlike find-modules, the result of running a script is not just a bunch of paths, but instead creates fully functional CMake targets. In a dependent project, it looks like dependencies were created as part of the same project.

This allows you to transfer much more information in a very convenient way. The obvious downside is that config-file scripts are much more complicated than find-scripts. Therefore, you do not want to write them yourself, but CMake generates them for you. Or rather, the dependency provides a configuration file as part of its deployment, which you can then simply load by calling find_package . And that is exactly what Qt5 does.

It also means that if your own project is a library, consider creating a configuration file as part of the build process . This is not the easiest CMake feature, but the results are quite powerful.

Here is a brief comparison of how the two approaches usually look in CMake code:

Find-module style

 find_package(foo) target_link_libraries(bar ${FOO_LIBRARIES}) target_include_directories(bar ${FOO_INCLUDE_DIR}) # [...] potentially lots of other stuff that has to be set manually 

Config file style

 find_package(foo) target_link_libraries(bar foo) # magic! 

tl; dr : always prefer configuration file packages, if available. If not, use find- script instead.

+7
source

Actually there is no β€œmagic” with the results of find_package : this command simply searches for the corresponding FindXXX.cmake script and executes it.

If the Find script sets the variable XXX_LIBRARY , then the caller can use this variable.

If the Find script creates the imported targets, then the caller can use these targets.

If the Find script does not set the XXX_LIBRARY variable and does not create the imported targets ... well, then using the script is somehow different.

The documentation for find_package describes the usual use of Find scripts. But in any case, you need to consult the documentation for a particular script (this documentation is usually contained in the script itself).

+2
source

All Articles