[cmake-developers] Improving the version selection behavior of EXACT

Rolf Eike Beer eike at sf-mail.de
Fri Oct 3 12:47:31 EDT 2014


Brad King wrote:
> On 10/03/2014 11:53 AM, Rolf Eike Beer wrote:
> > It looks like this line is the culprit:
> >   if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
> > 
> > I can solve this in CMake language, but the question is again if it may be
> > worth solving in the command itself? Meanwhile I'll prepare an
> > implementation in CMake code, we can replace that with anything better
> > anytime later.
> Yes, I think the command should be fixed to compare only as many
> components as are given on both sides, ignoring extra on one side.
> However, that will require a policy.
> 
> Please fix it in the module by hand for now and look at adding a
> policy for this after the 3.1 release.

Yes, that was my plan. This is what I have now (diff -b for easier review):

diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index e8d1dfb..f8c990e 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -290,12 +290,38 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
     if(VERSION)
 
       if(${_NAME}_FIND_VERSION_EXACT)       # exact version required
+        # count the dots in the version string
+        string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}")
+        # add one dot because there is one dot more than there are components
+        string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
+        if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
+          # give an exact match if the first ${NAME}_FIND_VERSION_COUNT components of the version string match
+          # this constructs the equivalent of "(([^.]\\.){${${_NAME}_FIND_VERSION_COUNT}})"
+          unset(_VERSION_REGEX)
+          # foreach(RANGE) doesn't like it if stop is greater start
+          if (${${_NAME}_FIND_VERSION_COUNT} GREATER 1)
+            foreach (_NUM RANGE 2 ${${_NAME}_FIND_VERSION_COUNT})
+              set(_VERSION_REGEX "${_VERSION_REGEX}[^.]*\\.")
+            endforeach ()
+          endif ()
+          string(REGEX REPLACE "^(${_VERSION_REGEX}[^.]*)\\..*" "\\1" _VERSION_HEAD "${VERSION}")
+          unset(_VERSION_REGEX)
+          if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
+            set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
+            set(VERSION_OK FALSE)
+          else ()
+            set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+          endif ()
+          unset(_VERSION_HEAD)
+        else ()
           if (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
             set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
             set(VERSION_OK FALSE)
           else ()
             set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
           endif ()
+        endif ()
+        unset(_VERSION_DOTS)
 
       else()     # minimum version specified:
         if ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")


Eike
-- 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://public.kitware.com/pipermail/cmake-developers/attachments/20141003/ec41957c/attachment-0002.sig>


More information about the cmake-developers mailing list