[cmake-developers] Generator expressisons in target properties (was Re: conditionals in generator expressions)

Brad King brad.king at kitware.com
Tue Oct 23 07:45:51 EDT 2012


On 10/22/2012 05:42 PM, Stephen Kelly wrote:
> Ah, I was wondering about that when I wrote that patch, but forgot to put in 
> the email. I thought they would be able to have per-config dependencies.
> 
>  set_property(TARGET foo LINK_LIBRARIES $<$<Config:Debug>:debughelpers>
> 
> will never work with IDE generators? That's not a limitation of the 
> generators but of the IDEs?

That can work because the IDEs support per-config link libraries.
It's the logical build ordering dependencies among targets that are
not per-config.  That means in a Release build the IDE will still
want to build debughelpers before foo, but will not actually have
to link to it.

>  target_link_libraries(bar LINK_PUBLIC foo)
>  # bar LINK_LIBRARIES is now:
>  #   "foo;$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>"
>  # bar INTERFACE_LINK_LIBRARIES is now:
>  #   "foo;$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>"

Why does "$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>"
belong in either one of them?  The transitive closure should be
computed by link-aware code that knows it must follow foo's link
interface, not just by generator expression evaluation.  The
purpose of GetOriginalLinkLibraries is to get the directly linked
libraries without any transitive dependencies.

>  # In my branch WIN32_EXECUTABLE would be defaulted to:
>  #
>  # $<EACH:$<TARGET_PROPERTY:LINK_LIBRARIES>,"
>  #           "$<OR:$<EACH_ACCUMULATED:0>,"
>  #                "$<BOOL:$<TARGET_PROPERTY:$<EACH_ARG>,"
>  #                "INTERFACE_WIN32_EXECUTABLE>>>"
>  #
>  # That is, check if any of the link libraries say WIN32_EXECUTABLE should 
>  # be ON.

What is the use case for that default?  I think enabling the
WIN32_EXECUTABLE option should remain an explicit choice.

> Can you give more information about the case you mention? I don't see any 
> mention in the documentation of using find_package() with a directory.

Projects may do this:

 if(NOT USE_SYSTEM_FOO)
   add_subdirectory(Foo)
   set(Foo_DIR ${CMAKE_CURRENT_BINARY_DIR}/Foo)
 endif()
 find_package(Foo)
 ...
 target_link_libraries(MyExe ${Foo_LIBRARIES})

such that Foo_LIBRARIES ends up with namespaced imported targets
that refer to the in-tree real targets.

>> We need to consider how to handle compatibility here,
>> but only with projects not using the new features enabled by delaying
>> export() until generate time.  Can you explain this in more detail?
> 
> This may only be doable by duplicating a lot more code and making 
> cmExportBuildFileGenerator not inherit from cmExportFileGenerator. The 
> latter uses GetLinkInterface, GetSoName and HasSoName. 
> 
> HasSoName depends on the link languages, and therefore the libraries and 
> therefore has to move to cmGeneratorTarget. If export() is to remain a 
> configure-time construct, then HasSoName would have to remain in some form 
> in cmTarget. That could mean a lot of duplication.

We may need a policy implemented with minimum duplication to provide
the capabilities that export() used to.

-Brad



More information about the cmake-developers mailing list