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

Brad King brad.king at kitware.com
Tue Jan 29 09:08:03 EST 2013


On 01/29/2013 03:53 AM, Stephen Kelly wrote:
> This INTERFACE_INCLUDE_DIRECTORIES case is not going to be the only time an 
> upstream will want to add to its interface. In theory, any time they want to 
> add a directory to the INTERFACE_INCLUDE_DIRECTORIES they would have to bump 
> the compatibility number.

Yes, so encouraging use of version numbers in find_package will help.
OTOH this is currently the case with the <pkg>_INCLUDE_DIRS variables
and no one has bothered with it.

> this issue is independent of whether tll() adds includes or a new command

Yes.  When you realized that we don't need a policy for that the reason
is actually because the policy needs to go in the individual upstreams
for their own interface in the form of an interface version number.

>> The upstream could require that a version be requested if the downstream
>> wants the new interfaces to be available, but that does not allow a
>> downstream to optionally work with older versions of the upstream.
> 
> Why not?

...because the downstream would need to do

 find_package(Foo ${version_with_new_interface})

to get the new interface and therefore CMake would not find an older
version now that the new one is requested.

>> Perhaps it could work if the upstream provided an explicit variable
>> (option 1 above) that has meaning when the requested version is not
>> present or not new enough.
> 
> Yes.
> 
>> Then downstreams would be able to use the
>> variable to get the new interfaces if the upstream is new enough to
>> provide them but still work with old upstreams.
> 
> Yes. The policy emulation using combined version check and variable is 
> probably the best way forward.

Agreed.

> In that case upstreamConfig.cmake would look something like this:
> 
>  include("${CMAKE_CURRENT_LIST_DIR}/upstreamTargets.cmake")
>  if (PACKAGE_FIND_VERSION VERSION_LESS 2.3)
>    foreach(_target ${maintained_list_of_targets})
>       set_target_property(${_target} 
>         INTERFACE_INCLUDE_DIRECTORIES ""
>       )
>    endforeach()
>  endif() 
> 
> The maintained_list_of_targets would have to be hand-maintained currently. 
> It might be an idea to 'leak' a variable out of the targets file containing 
> the list of targets, but I'm not sure that's a good idea.

I'd rather not populate the properties at all.  Perhaps we can combine
it with your option (2) and have:

 if(PACKAGE_FIND_VERSION VERSION_LESS 2.3
    AND NOT MyPkg_INTERFACE_INCLUDE_DIRECTORIES)
   set(${PACKAGE_FIND_NAME}_NO_INTERFACE_INCLUDE_DIRECTORIES 1)
 endif()
 include("${CMAKE_CURRENT_LIST_DIR}/upstreamTargets.cmake")

-----------------------------------------------------------------------

Even though this is strictly necessary only for include_directories
I wonder if we should do it for all usage requirements.  That will
be simpler to explain than "we are confident these other features
could not possibly break a build".  It would also allow the name of
the option to be more general than ..._INCLUDE_DIRECTORIES:

 if(PACKAGE_FIND_VERSION VERSION_LESS 2.3
    AND NOT MyPkg_INTERFACES)
   set(${PACKAGE_FIND_NAME}_NO_INTERFACES 1)
 endif()
 include("${CMAKE_CURRENT_LIST_DIR}/upstreamTargets.cmake")

-Brad



More information about the cmake-developers mailing list