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

Philipp Moeller bootsarehax at gmail.com
Thu Mar 6 10:27:21 EST 2014


Stephen Kelly <steveire at gmail.com> writes:

> 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.

Some of my dependencies are chosen at configuration time, so I need to
specify somehow if a target has been build with a public dependency
enabled.

e.g. I have mylib1 and mylib2, mylib1 depends on mylib2 and optionally
on External::stuff. The classic way would be to write a variable
mylib_external_depends and go through that to trigger the appropriate
find_packages. I thought I could save myself the duplication and just
use the interface libraries instead, but you are probably right.

>
>> 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.

I'll see what I can do.




More information about the cmake-developers mailing list