[cmake-developers] Target usage requirements and conventions

Brad King brad.king at kitware.com
Wed May 2 08:20:07 EDT 2012


On 5/1/2012 5:33 PM, Stephen Kelly wrote:
> I think Alex' suggestion solves the problem anyway:

Yes.

> target_use_package(Foo IMPORTED_TARGETS Bar)

There is no reason that targets built in the same project can't provide
package interfaces just like imported targets.  I think this can be
just "TARGETS", or just "TARGET" if we allow only one package per call.
Would this one ever imply find_package?

> target_use_package(Foo VIA_PREFIX Bar )

The name here should indicate that the prefix is for variables and
not an installation prefix or something.  Perhaps one of

  (VAR|VARIABLE)_(PREFIX|GROUP|NAMESPACE)

?  Would this one ever imply find_package to set the variables?

> target_use_package(Foo PACKAGE Bar)

There is debate elsewhere in this thread over whether this would
imply find_package(Bar).  Perhaps we should say that "PACKAGE"
means use an already-found package and error if not found already.

Then add

  target_use_package(Foo FIND_PACKAGE Bar)

to mean find-if-necessary.  Then arguments after "Bar" would be
passed to the implied find_package for version and all the other
options.  Either Module mode or Config mode could detect whether
there is enough information to define the Bar package, and then
do so.  See below.

This brings up a fundamental question for this design discussion.
Are usage requirements associated with packages, with targets, or
with either/both?

>> We will likely need to make packages something first-class on the
>> C++ side.  If find_package(Bar) detects that the files it loaded
>> define sufficient information for a package it should construct a
>> C++ object to represent the package.  This event should establish
>> the package.  A loose sequence of variable set()s is not explicit
>> enough.
>
> Right.

How might find_package detect/define a first-class package object?
Just look for the right variables?  Perhaps we could add an (optional)
explicit package declaration:

  cmake_package(Bar LIBRARIES ... DEFINITIONS ...)

that can be either in the Find module or in the package configuration
file.  This would allow more detailed information to be set.

>> We need to settle on a generator-expression syntax for per-config
>> conditions.  The $<CONFIG?Debug:...>  syntax is sufficient for
>> discussion but needs more thorough discussion before it is final.
>
> In particular, I think it might be necessary to set multiple conditions in
> such expressions.

Good point.  That could get ugly with my originally proposed syntax :(
I'll have to think about it more.

> set_target_property(Foo INTERFACE_INCLUDE_DIRS
>    "$<INCLUDE_MODE=Build:${CMAKE_SOURCE_DIR}/src/foo/debugstuff>"
>    "$<CONFIG=Debug?INCLUDE_MODE=Build:${CMAKE_SOURCE_DIR}/src/foo>"
>    "$<INCLUDE_MODE=Install:${CMAKE_INSTALL_PREFIX}/mylib>"
> )

I don't think we should have something like INCLUDE_MODE.  There will
be much more about a package that varies between build tree and install
tree.  Currently when I write a project that can be used from either
tree I create separate package configuration files and separate target
files, one with export() and one with install(EXPORT).  Essentially
each one is its own complete package that doesn't care about the other.

I'd prefer that the properties set directly on the target in the build
tree affect only its usage requirements for use from the build tree.
The export() command would transfer this information to the imported
target it generates.

We need a way to separately specify the install-tree usage requirements
to be associated with its imported targets.  Currently I don't like our
target properties like INSTALL_RPATH that are set on the build-tree
target but affect the install-tree file.  It breaks with the fact that
our install(TARGETS) interface allows the same target file to be put
in multiple install locations.  Perhaps we can fix that mistake along
with the new interface.  New options could be added to the install
command's TARGETS mode to specify usage requirements for the targets.

Perhaps a new install(PACKAGE) command?  We have export(PACKAGE)
already which could be extended for this purpose.

> Yes, I think we'll need to first have a list of 'dimensions' that are
> relevant....Is there anything missing from the list I made?

It looks good to me but I don't think we'll know for sure until it is
implemented and new cases are encountered ;)

-Brad



More information about the cmake-developers mailing list