[cmake-developers] A policy for Policies

Stephen Kelly steveire at gmail.com
Mon Jun 8 15:38:33 EDT 2015


Brad King wrote:

> On 06/06/2015 06:36 AM, Stephen Kelly wrote:
>> The documentation notes that Policies are not feature toggles:
>> 
>>  http://www.cmake.org/cmake/help/git-master/manual/cmake-policies.7.html
>> 
>> However, the reality is that Policies *are* feature toggles because they
>> are so long-lived. Users have no expectation that Policies will 'stop
>> working', and happily set them to OLD and encourage others to do the
>> same. I see this on StackOverflow all the time, and on the users mailing
>> list.
> 
> Yes.  Documentation is never enough to discourage such decisions.  When
> faced with the choice of "add this line" or "read and understand the
> policy and port your code to the new behavior while possibly maintaining
> compatibility with versions of cmake that do not have the policy", which
> one will many users pick?

For most software out there, users get no choice. They upgrade, get an error 
with NEW behavior, and apply a workaround or search the internet for a 
workaround, and they're done. 

I like that the cmake Policy system allows something better, but I think it 
is not well-understood because it is unique. I know nothing else like it.

For most Policies, the only question is whether a) a good workaround will be 
chosen, or b) the policy will be set to OLD.

For example, on hitting CMP0002 the right approach would be to use unique 
target names. That policy was easy to overcome because it indicates a pure 
error in user code which can be fixed without affecting behavior of any 
cmake version on the code.

CMP0020 is a little harder to deal with. Instead of setting it to OLD, users 
would have to change their code to contain an if() for the CMAKE_VERSION, 
and it doesn't indicate an error in the user code, but just a new behavior 
of CMake. But it is low-impact. CMP0024 also falls into this category.

CMP0022 is higher impact, and also indicates only a new behavior but not an 
error in user code. It is quite easy to deal with though as user code can 
choose some lowest common denominator or use if() on the CMake version.

CMP0026 is high impact and hard to deal with for users.

Most Policies which are only about new CMake behavior are introduced several 
releases after new preferred features, such as CMP0043.

I think it should be ok to deprecate/remove OLD behavior of Policies falling 
into the category with CMP0002 without waiting 5 years. 

For most of the other categories, I think 5 years is too long because the 
user code can gain a if() on the CMAKE_VERSION. We should consider the 
impact of the Policy on users, the difficulty of doing the right thing, and 
the impact on the cmake implementation, not just time. 

I don't see any reason to wait 5 years for CMP0044 for example. 2 years is 
also "long" for that one, but it doesn't have a very bad impact on the cmake 
implementation anyway either, so making it REQUIRED_ALWAYS would be a very 
small cleanup.

Making CMP0003 REQUIRED_ALWAYS would be a big cleanup, and actually is also 
something I think we should do for CMake 3.4 as it would help my 
refactoring. It is now 7 years old. Making it REQUIRED_IF_USED would make it 
easier to implement saner CMP0024 and CMP0026 OLD behavior I think.

>> will then result in an error if code attempts to set it to OLD, and
>> recommend the user to use an older release or fix the code instead.
> 
> It is not just explicit attempts to set the policy to OLD that will
> give an error.  It is any time CMake needs to know the policy setting
> and it has not been set to NEW either explicitly or by use of
> cmake_minimum_required with a sufficiently recent version.

Right. Implementations of policies typically determine whether checking the 
policy is needed before actually checking it. So it will only try to 
determine the CMP0044 behavior at all if a case insensitive match is found. 
For most projects, that will not ever have been the case. The same scenario 
is true for many policies.

> In the case of CMP0011, the include() command will be used all over
> even within CMake's own modules and trigger query of the policy.
> This makes REQUIRED_IF_USED effectively REQUIRED_ALWAYS.  This
> means any project that does not call cmake_minimum_required
> with version 2.6.3 will not be able to build with newer CMake
> versions.  The only recourse a user will have to get such a project
> building will be to edit the source or try setting the policy to
> NEW using CMAKE_POLICY_DEFAULT_CMP<NNNN>:

Thanks for the clarification. I've added an entry to the release notes that 
CMP0011 is deprecated, and I can add something similar for CMP0003.

> This may be okay for CMP0011, but CMP0024 and CMP0026 were much
> more recent (3.0).  I think 5 years is a more reasonable cut-off
> than 2 years, especially given the time it takes CMake versions
> included in older distro releases to fall out of common use.

I think 5 years is too long for most policies, at least those which are easy 
for third party maintainers to deal with.

You seem to be thinking here about the scenario of using CMake 2.6 on RHEL 5 
or so together with some project which is not designed for that system, or 
not maintained for it. For most policies, the maintainer can add code which 
does not use cmake_policy to make the project work with CMake 2.6 and 3.2 
without warnings, if that is a reasonable thing for them to do. 

Thanks,

Steve.




More information about the cmake-developers mailing list