Modern cmake advise for transitive library dependencies

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Modern cmake advise for transitive library dependencies

Mario Emmenlauer

Dear cmake team and user community,

I'd kindly like to ask for advice on how to handle transitive
dependencies cleanly with "modern" cmake. I'm often plagued by this
problem: I have a library X that optionally depends on library A.
When I build library Y that depends on X, how do I (cleanly) handle
the optional dependency A?
Assume "A" would be "Qt5Core". I can link X publicly against Qt5::Core.
But when I import X into Y, then Y will complain about unknown target
Qt5::Core, unless I do find_package(Qt5 COMPONENTS Core) in Y. But since
Qt is optional in X, I would need to track somehow if Qt was enabled
before.

But what good is the public transitive dependency when I manually need
to track it, to find the libraries again? Am I missing something?
Can the dependency be automatically resolved, or can I query some
variable if X was linking A?

How to do this cleanly?

Thanks a lot and all the best,

     Mario Emmenlauer
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Modern cmake advise for transitive library dependencies

Alan W. Irwin-2
On 2018-12-17 21:35+0100 Mario Emmenlauer wrote:

>
> Dear cmake team and user community,
>
> I'd kindly like to ask for advice on how to handle transitive
> dependencies cleanly with "modern" cmake. I'm often plagued by this
> problem: I have a library X that optionally depends on library A.
> When I build library Y that depends on X, how do I (cleanly) handle
> the optional dependency A?
> Assume "A" would be "Qt5Core". I can link X publicly against Qt5::Core.
> But when I import X into Y, then Y will complain about unknown target
> Qt5::Core, unless I do find_package(Qt5 COMPONENTS Core) in Y. But since
> Qt is optional in X, I would need to track somehow if Qt was enabled
> before.
>
> But what good is the public transitive dependency when I manually need
> to track it, to find the libraries again? Am I missing something?
> Can the dependency be automatically resolved, or can I query some
> variable if X was linking A?
>
> How to do this cleanly?

Hi Mario:

One way to cleanly automate this is to configure the XConfig.cmake
file (depending on whether X is linked with Qt5 or not) to optionally
execute

find_package(Qt5 ...)

As a result, when the logic in XConfig.cmake is executed as a result of

find_package(X ...)

from Y, Qt5 should be found automatically when needed.

Alan
__________________________
Alan W. Irwin

Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________

Linux-powered Science
__________________________
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Modern cmake advise for transitive library dependencies

Craig Scott-3


On Wed, Dec 19, 2018 at 5:36 AM Alan W. Irwin <[hidden email]> wrote:
On 2018-12-17 21:35+0100 Mario Emmenlauer wrote:

>
> Dear cmake team and user community,
>
> I'd kindly like to ask for advice on how to handle transitive
> dependencies cleanly with "modern" cmake. I'm often plagued by this
> problem: I have a library X that optionally depends on library A.
> When I build library Y that depends on X, how do I (cleanly) handle
> the optional dependency A?
> Assume "A" would be "Qt5Core". I can link X publicly against Qt5::Core.
> But when I import X into Y, then Y will complain about unknown target
> Qt5::Core, unless I do find_package(Qt5 COMPONENTS Core) in Y. But since
> Qt is optional in X, I would need to track somehow if Qt was enabled
> before.
>
> But what good is the public transitive dependency when I manually need
> to track it, to find the libraries again? Am I missing something?
> Can the dependency be automatically resolved, or can I query some
> variable if X was linking A?
>
> How to do this cleanly?

Hi Mario:

One way to cleanly automate this is to configure the XConfig.cmake
file (depending on whether X is linked with Qt5 or not) to optionally
execute

find_package(Qt5 ...)

As a result, when the logic in XConfig.cmake is executed as a result of

find_package(X ...)

from Y, Qt5 should be found automatically when needed.


Your XConfig.cmake is responsible for also ensuring all targets it depends on are defined. This shouldn't be left up to consumers of X. The way this is normally done is pretty much as Alan suggests (it's also the way I handle cases analogous to yours in our projects at work). There's even a find_dependency() command intended for precisely this situation to make it a little easier, although I generally advise against using it for packages that support components due to the way a particular optimisation in its implementation affects later find_dependency() calls for the same package.
 
--
Craig Scott
Melbourne, Australia


--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Modern cmake advise for transitive library dependencies

Mario Emmenlauer

Dear Craig, Alan,

thanks so much for this hint! I did not write the initial XConfig.cmake
myself and so it slipped my attention. Now things are perfectly clear,
I'll extend the XConfig.cmake.in and add the configuration steps there.

All the best,

     Mario



On 18.12.18 21:54, Craig Scott wrote:

>
>
> On Wed, Dec 19, 2018 at 5:36 AM Alan W. Irwin <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     On 2018-12-17 21:35+0100 Mario Emmenlauer wrote:
>
>      >
>      > Dear cmake team and user community,
>      >
>      > I'd kindly like to ask for advice on how to handle transitive
>      > dependencies cleanly with "modern" cmake. I'm often plagued by this
>      > problem: I have a library X that optionally depends on library A.
>      > When I build library Y that depends on X, how do I (cleanly) handle
>      > the optional dependency A?
>      > Assume "A" would be "Qt5Core". I can link X publicly against Qt5::Core.
>      > But when I import X into Y, then Y will complain about unknown target
>      > Qt5::Core, unless I do find_package(Qt5 COMPONENTS Core) in Y. But since
>      > Qt is optional in X, I would need to track somehow if Qt was enabled
>      > before.
>      >
>      > But what good is the public transitive dependency when I manually need
>      > to track it, to find the libraries again? Am I missing something?
>      > Can the dependency be automatically resolved, or can I query some
>      > variable if X was linking A?
>      >
>      > How to do this cleanly?
>
>     Hi Mario:
>
>     One way to cleanly automate this is to configure the XConfig.cmake
>     file (depending on whether X is linked with Qt5 or not) to optionally
>     execute
>
>     find_package(Qt5 ...)
>
>     As a result, when the logic in XConfig.cmake is executed as a result of
>
>     find_package(X ...)
>
>     from Y, Qt5 should be found automatically when needed.
>
>
>
> Your XConfig.cmake is responsible for also ensuring all targets it depends on
> are defined. This shouldn't be left up to consumers of X. The way this is
> normally done is pretty much as Alan suggests (it's also the way I handle cases
> analogous to yours in our projects at work). There's even a find_dependency()
> <https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html>
> command intended for precisely this situation to make it a little easier,
> although I generally advise against using it for packages that support
> components due to the way a particular optimisation in its implementation
> affects later find_dependency() calls for the same package.
> --
> Craig Scott
> Melbourne, Australia
> https://crascit.com
>
> New book released: Professional CMake: A Practical Guide
> <https://crascit.com/professional-cmake/>



Viele Gruesse,

     Mario Emmenlauer


--
BioDataAnalysis GmbH, Mario Emmenlauer      Tel. Buero: +49-89-74677203
Balanstr. 43                   mailto: memmenlauer * biodataanalysis.de
D-81669 München                          http://www.biodataanalysis.de/
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Modern cmake advise for transitive library dependencies

Roger Leigh
In reply to this post by Craig Scott-3
On 18/12/2018 20:54, Craig Scott wrote:

>
> Your XConfig.cmake is responsible for also ensuring all targets it
> depends on are defined. This shouldn't be left up to consumers of X. The
> way this is normally done is pretty much as Alan suggests (it's also the
> way I handle cases analogous to yours in our projects at work). There's
> even a find_dependency()
> <https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html>
> command intended for precisely this situation to make it a little
> easier, although I generally advise against using it for packages that
> support components due to the way a particular optimisation in its
> implementation affects later find_dependency() calls for the same package.

Can't we drop this optimisation and fix find_dependency, making it
properly usable?  I've tested a few of the modules using components to
see if they behave correctly with different sets of components, and I've
not yet encountered any problems due to calling multiple times.

In consequence, I wonder if we could simply drop the "optimisation" and
have find_dependency do nothing more than be a thin wrapper around
find_package.  This would solve the problems and should not break
backward compatibility.

The only difference would be if the first find_package call succeeds and
subsequent calls fail, which would alter the value of _FOUND.  However,
that's likely exactly what one should expect.


Regards,
Roger
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake