[cmake-developers] [CMake 0014317]: Configuration dependent install EXPORT

Stephen Kelly steveire at gmail.com
Wed Jul 31 11:05:47 EDT 2013


Brad King wrote:
>> So, I think for the case of INCLUDES DESTINATION, we can either decide
>> and fix it now, or revert the change adding it for 2.8.12.
> 
> Let's try to decide now and revert as a last resort.
> 
> So the only reason we need partial evaluation is to leave
> configuration-dependent sub-expressions untouched since the
> configuration is not known until generation of the consumer?

Yes, I think that is the case. 

Includes are not generally different files for debug/release as the 
preprocessor is generally used instead where needed. However, let's assume 
that for the debug config we install a foo_debug.h, and otherwise not.

To get more concrete, here's some cases I could think of:

A) I want to install all includes to 

 set(config_suffix $<$<CONFIG:Debug>:debug>$<NOT:$<CONFIG:Debug>:release>)

 INCLUDES DESTINATION "$<INSTALL_PREFIX>/include/${config_suffix}"

and for consumers of the target to get either the 'debug' or the 'release' 
include directory.

I would use 

 install(FILES ${files} 
   DESTINATION include/${config_suffix})

(when that works) to install the files.

B) I only want to install the foo_debug.h to a special location

 install(FILES ${files} 
   DESTINATION include)
 install(FILES foo_debug.h 
   DESTINATION include/debug
   CONFIGURATIONS Debug
 )

 INCLUDES DESTINATION 
   "include;$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/debug>"

So that consumers get both include directories. This probably works already 
with master.

C) As B, but with target-named include paths

 install(FILES ${foo_files} 
   DESTINATION include/foo)
 install(FILES ${bar_files} 
   DESTINATION include/bar)
 install(FILES foo_debug.h 
   DESTINATION include/foo/debug
   CONFIGURATIONS Debug
 )

 set(basic_path $<INSTALL_PREFIX>/include/<$<TARGET_PROPERTY:NAME>)
 INCLUDES DESTINATION 
   "${basic_path}"
   "$<$<CONFIG:Debug>:${basic_path}/debug>"

This does not work with master. However, there is a workaround.

 target_include_directories(foo INTERFACE 
   include/foo
   "$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/foo/debug>"
 )

ie, not using the INCLUDES DESTINATION feature, which is 'just' a 
convenience for the 'common case'.


> I think the partial evaluation should work by traversing
> the expression tree and collapsing sub-tree that does not
> depend on the configuration into a leaf node with a constant
> value.
> 
> Alternatively we could generate an error if any config-dependent
> expressions are found in INCLUDES DESTINATION and otherwise
> do full evaluation.  That way we can decide on the partial
> evaluation semantics later.

Yes, such an error would be quite easy to generate, as that fact is already 
recorded. I considered that and decided not to implement it because the bug 
report specifically wanted config support. However, that was for libraries, 
not includes. Config sensitive dirs are likely more common for libraries 
than includes, so actually I think it would be fine to make that an error 
and always do full evaluation.

I've pushed INCLUDES-DESTINATION-no-config to my clone with an 
implementation. Can I merge it to next?

Thanks,

Steve.







More information about the cmake-developers mailing list