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

Stephen Kelly steveire at gmail.com
Tue Jan 29 10:16:53 EST 2013


Brad King wrote:

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

I had the same thought, but it is indeed essentially the same situation. I 
see why some would use the feature we're discussing in this thread, but I 
can also imagine many upstreams ignoring it.

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

 find_package(Foo ${oldversion})
 if (NOT Foo_FOUND 
      OR Foo_VERSION VERSION_GREATER ${version_with_new_interface})
   find_package(Foo ${version_with_new_interface})
 endif()
 # Now Foo_LIBRARIES might be targets with interfaces or not, which 
 # means include_directories is still needed anyway until the minimum 
 # version required is ${version_with_new_interface}.

So, really if they want their minimum version of Foo to be lower than 
${version_with_new_interface} they should assume they never get interfaces 
and always use include_directories until they bump that minimum requirement. 
Otherwise all their doing is maintaining multiple codepaths (one with 
include_directories, one without) for no reason.

>> 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")

Yes, I'm sure that would be fine.

> 
> -----------------------------------------------------------------------
> 
> 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")

Yes, I'm fine with that too, though it will only affect 'new' interfaces, 
not LINK_INTERFACE_LIBRARIES.

Thanks,

Steve.





More information about the cmake-developers mailing list