[cmake-developers] Setting includes, defines and other usage requirements with one command

Stephen Kelly steveire at gmail.com
Sat Jan 26 06:57:41 EST 2013


Brad King wrote:
> I've longed for "usage requirements" for years and always pictured
> them propagating through linking.  The huge threads of discussion
> earlier made usage requirements seem more complicated than they are
> and made it feel like we should hide it all behind new interfaces.
> Now I think a new command will actually be *more* confusing in the
> long run because the two will be different only in subtle ways and
> users will wonder which one to use.

Yes, that's exactly my thinking too.

> I'm almost ready to accept the proposed behavior for
> target_link_libraries.  However, we still need to construct a
> recommended way for packages and their dependents to handle the
> transition.  There are many, many instances of the old style usage
> since it is the only one that previously worked.
> 
> How can a package author allow old dependents using the old style to
> keep working while also allowing new dependents using the new style
> to work?

As compile definitions are uniq'd, they don't pose any backward 
compatibility concerns for downstreams of a project whose upstream adds 
them. 

In the worst case, the needed compile definitions will be duplicated by an 
existing call to add_definitions(), and in the best case the needed 
defintions will be added where they were absent before.

In the case of the include directories, there could be incompatibility 
introduced by an upstream newly using the feature. Even if upstream has all-
unique headers in multiple directories (think Qt), downstream might be also 
using another project which has conflicting headers (in the case of Qt, 
that's not likely as the 'q' prefix is well claimed).

So, the options I see are:

1) Upstream introduces a find_package-time variable to evaluate whether to 
populate the INTERFACE_INCLUDE_DIRECTORIES (similar to 
QT4_USE_IMPORTED_TARGETS). Upstream would likely have to clear the target 
property in that case after including the exported targets file.
2) CMake introduces a standard documented way to not populate the target 
property in the exported targets file at all 
(<PACKAGE_NAME>_NO_INTERFACE_INCLUDE_DIRECTORIES, off by default).
3) Upstream introduces a new set of IMPORTED targets which have the 
INTERFACE_INCLUDE_DIRECTORIES set. CMake introduces a way to control at 
INSTALL(EXPORT) time whether to populate it. So upstream would do this:

 INSTALL(EXPORT fooTargets NAMESPACE Foo:: ...)
 INSTALL(EXPORT fooTargets EXPORT_INCLUDE_INTERFACE NAMESPACE FooNew:: ...)

or some other naming change, and include() both in the config file.

(2) is easy for us and for upstream, but source incompatible for downstream. 
(3) is more awkward for all upstreams, but source compatible for downstream.

Thanks,

Steve.





More information about the cmake-developers mailing list