[cmake-developers] Adding automatic checks for required targets in target-export files ?

Alexander Neundorf neundorf at kde.org
Tue Feb 12 13:47:33 EST 2013


On Monday 11 February 2013, Alexander Neundorf wrote:
> On Monday 11 February 2013, Brad King wrote:
> > On 02/10/2013 10:14 AM, Alexander Neundorf wrote:
> > > 1) either put a check for the required targets in the generated targets
> > > file, and make find_package() fail by setting foo_FOUND to FALSE. This
> > > should be relatively straightforward to implement, and needs only code
> > > in the generated targets file. This is good.
> > 
> > I like this approach better than the second one also.
> > 
> > > On the downside, this will probably make the cmake
> > > run fail for (some ?) projects where it currently succeeds, although
> > > they do not take the dependency order into account when searching
> > > packages.
> > 
> > I think we can add a policy for this.  If not set, warn and use OLD.
> > If OLD, silently accept the missing targets.  If NEW, error.
> 
> So the exported targets file should do something like the following ?
> 
> set(failWithError FALSE)
> cmake_policy(GET CMP00xy POLICY_SET_TO_NEW)
> if("${POLICY_SET_TO_NEW}" STREQUAL "NEW")
>    set(Foo_FOUND FALSE);
>    set(Foo_NOT_FOUND_MESSAGE "Foo not found because some target is
> missing") else()
>    message(STATUS "Foo may not work because some imported target is
>                    currently still missing")
> endif()

I implemented this mostly yesterday, but now I think doing this using a policy 
does not make much sense.

One thing is, the Config.cmake file itself could set the policy to NEW or OLD. 
Setting it to OLD would mean failure at build time for the consuming project 
(as before).
Setting it to NEW would mean failure at cmake time for the consuming project. 

But IMO the policies should be controlled by the consuming project, not by the 
used projects.

Also, the NEW mode, i.e. fail at cmake time, would only be active for projects 
which require 2.8.11, for others it would just be a warning at cmake time, and 
a failure at build time.
IMO it really should be an error at cmake time if a referenced imported target 
has not been imported, because it will not link.

So I actually see only the following two reasonable options:

1) fail immediately in the targets file if a referenced target does not exist 
yet. If imported targets would be new, I would do this. But since they already 
exist for some time, there are most probably projects where the order of 
find_package() does not take the dependencies into account, so they build now, 
but would fail at cmake time then. Would that be acceptable ?

2) Collect the referenced imported targets and check later whether they all 
have been imported, and error out if not.
I'm not completely sure when "later" is.
First I thought at the end of the configure-step, but since imported targets 
do not have global scope, I think this has to be done per directory. So I 
could do this check in some way at the end of processing a CMakeLists.txt, 
i.e. before leaving a directory.

If 1) is not acceptable, I'll try to do 2). This also does not need a new 
policy, which is good. And it will always error out when it should.

Am I seeing something wrong ?

Alex



More information about the cmake-developers mailing list