[cmake-developers] Exported targets with imported dependencies in CMake 3.0

Stephen Kelly steveire at gmail.com
Thu Mar 6 10:20:29 EST 2014


Philipp Möller wrote:

> Stephen Kelly <steveire at gmail.com> writes:
> 
>> Philipp Möller wrote:
>>> It would be great, if I could export imported targets and if CMake could
>>> walk the dependency tree automatically and import those targets on an
>>> as-needed basis.
>>
>> Part of the problem is that the place where you import your dependent
>> targets from (and the locations calculated) are not necessarily the same
>> for your downstreams.
> 
> I understand the issue and have been fighting it in versions prior 3.0
> as well. It also arises if you simply export targets that have been
> target_link_librarie'd against full library paths returned by a
> find_package.

Yes, exactly. That's the problem with having paths in 
INTERFACE_LINK_LIBRARIES, and a good reason not to do that.

> That's why I thought some build-in functionality could be helpful for
> this, e.g. exporting and imported target would lead to a definition in
> the exports file that automatically triggers a corresponding
> find_package call.

Seems overly-complex to implement.

>> You export your targets to and -exports file, and presumably you import
>> that in a -config file. In the same config file, you should add code to
>> find your dependencies too.
>>
>>  http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#creating-packages
>>
>> The find_dependency macro can help with forwarding some find_package
>> arguments.
>>
>>  
http://www.cmake.org/cmake/help/v3.0/module/CMakeFindDependencyMacro.html
> 
> The documentation is a little sparse, but I think I understand the
> purpose.

The code is easy to read, if that helps. However, it's not designed for your 
complex case (it deliberately doesn't wrap all arguments of find_package), 
so you may have to do something similar to it on your own.

> I still need to traverse IMPORTED_LINK_INTERFACE_LIBRARIES and
> figure out which of the list members constitutes a target that needs to
> trigger a find_dependency and what a full library path is, correct?

No, I don't think so. You shouldn't introspect 
IMPORTED_LINK_INTERFACE_LIBRARIES like that.

Simply issue a find_dependency call and ensure that the package can be 
found. That probably means writing (and shipping with your config file) a 
Find-module for your dependency which creates the needed imported targets.

> I can also not rely on a find_package call to actually produce imported
> targets and need to ship the code that turns the results of find_package
> in targets.

You can actually. You just need to write and ship such a Find-module 
yourself (until the necessary imported targets are provided by the Find-
module itself).

Create a wrapper around the relevant Find-module and add the imported 
targets.

Something like:

 # FindFoo.cmake

 find_package(Foo PATH ${CMAKE_ROOT}/Modules NO_DEFAULT_PATH)
 add_library(Foo::Lib SHARED IMPORTED)
 # ...

and in the config file:

 find_package(Foo ${maybe_other_args}
   PATH ${CMAKE_CURRENT_LIST_DIR} NO_DEFAULT_PATH)


If you are going to write proper IMPORTED targets for cmake-shipped Find-
modules, I'd recommend contributing them to cmake instead anyway.

Thanks,

Steve.






More information about the cmake-developers mailing list