[cmake-developers] Setting target properties before the target is defined ?

Alexander Neundorf neundorf at kde.org
Sun Feb 17 10:26:10 EST 2013


On Sunday 17 February 2013, Alexander Neundorf wrote:
> On Sunday 17 February 2013, Brad King wrote:
> > On 2/15/2013 5:54 PM, Alexander Neundorf wrote:
> > > The thing is, if I generate an error at configure time if at the end of
> > > a directory a target has been used but has not been defined, i.e. a
> > > target Foo has been imported which links against a missing imported
> > > target, it would still be possible that the project can build
> > > successfully if this bad imported target Foo is simply not used, e.g.
> > > because Foo_FOUND is set to FALSE.
> > 
> > Just to make sure I understand correctly, you're bringing up a use case
> > where an imported target's dependencies are not satisfied but it does
> > not matter when the imported target is not used by the project?
> 
> Yes.
> But I wouldn't call it use case, but a case which accidentially works right
> now, and which a new cmake release should not break.
> 
> > > How about that: when in the exported and then imported Target.cmake a
> > > used target is not yet defined, this target name is added to a cmake
> > > variable. When then cmake calculates the linking, and it can't find a
> > > target, it checks whether the name is contained in this cmake variable.
> > > If so, it errors out instead of assuming it is the name of a library.
> > 
> > Yes, the variable would simply be collecting names that, in the scope
> > of its directory, are expected to be target names.  It may be better
> > to use a directory property and then have the generate-time check
> > look in the current directory and up.  That will avoid problems with
> > scoping of the variable if the project loads the file from inside
> > a function scope.
> 
> Oh, right, from inside a function scope...

But directory properties don't propagate into subdirs.
So if I load a package in dir1/, it records "imp1" as a name which refers to 
an imported target in a directory property, "imp1" is not known in subdirs, 
cmake would have to go up the directory hierarchy to check them all up to 
CMAKE_SOURCE_DIR.
So this was nice about cmake variables, they have the same scope (directory-
wise) as imported targets.

Now, there is the GLOBAL keyword for imported targets, so they can be used 
anywhere.
Just put everything into a GLOBAL property ?
Can this lead to problems ?
I think only in the case of name clashes.
E.g. I could do in the root dir
tll(hello foo)
and expect it to link against -lfoo, 
while in some subdir I could do 
tll(world foo)
and expect it to link against an imported target named "foo".
With a GLOBAL property this would stop working and be detected as a missing 
imported target "foo" in the root directory.
So here a failure would mean the project does not build although it should.

Using a cmake variable a failure would mean the project fails at build time 
instead of at cmake time.

So, how about the following:
* if it's a GLOBAL imported target, put the required imported libs into the 
directory property of ${CMAKE_SOURCE_DIR}
* at generate time, generate once for each directory a vector of expected 
imported targets by inheriting the property from the parent directories down 
to the subdirectories
* check those accumulated directory properties in FindTargetToUse() 


Any better ideas ?

Alex



More information about the cmake-developers mailing list