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

Brad King brad.king at kitware.com
Wed Jan 30 11:25:39 EST 2013


On 01/30/2013 10:57 AM, Stephen Kelly wrote:
> Now that fix-target-property-commands was merged to master, I've rebased 
> tll-includes-defines to master and your testcase works.

Thanks.  However, now it leaks out all non-targets referenced by tll
as giant strings in the exported interfaces:

 if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)
   set_target_properties(bar PROPERTIES
     INTERFACE_COMPILE_DEFINITIONS "$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>;$<$<TARGET_DEFINED:m>:$<TARGET_PROPERTY:m,INTERFACE_COMPILE_DEFINITIONS>>"
     INTERFACE_INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>;$<$<TARGET_DEFINED:m>:$<TARGET_PROPERTY:m,INTERFACE_INCLUDE_DIRECTORIES>>"
   )
 endif()

This is not acceptable.  We need to recognize when something was added
by tll and was not a target and remove it from the non-linking interfaces.
Can export() and install(EXPORT) do partial evaluation to remove these?
We can document that $<TARGET_DEFINED> has scope only in the current
project and will be processed away during export.  I do not think we
want an upstream interface modifying its behavior based on the mere
presence of an arbitrary target in the downstream anyway.

Other thoughts:

* The $<INSTALL_PREFIX> expression should evaluate as an error if
  it is ever reached by any path except install(EXPORT).  Otherwise
  the empty string in $<INSTALL_PREFIX>/somewhere is unlikely to
  do the right thing.

* If exported interfaces were partially evaluated then $<INSTALL_PREFIX>
  could be handled with a real evaluation instead of string replacement.

* Transitive linking is handled in C++ code rather than in generator
  expressions so there is no bloat in the LINK_LIBRARIES properties
  for non-target elements like the above.  Perhaps we can have a special
  generator expression that has context-sensitive evaluation e.g.

    $<LINKED:blah>

  tll() would add this to COMPILE_DEFINITIONS and INCLUDE_DIRECTORIES
  properties where it would be evaluated to get relevant target interface
  properties.  In other contexts it would be an empty string (or error?).
  It could be preprocessed out during export and replaced by nothing for
  non-targets or the relevant $<TARGET_PROPERTY:...> for targets.

* To optimize the large strings these interfaces generate, perhaps
  properties can be represented in general as compiled generator
  expressions that do not directly store their original strings but
  have references to pieces of them and can reconstruct them.
  This can be done later though.

-Brad



More information about the cmake-developers mailing list