Bläddra i källkod

FPHSA: when EXACT version match is requested only compare the components given

Given that you have a foobar that identifies itself as 1.2.3 from now on a

  find_package(foobar 1.2 EXACT)

will succeed, as 1.2.3 will now be considered as being 1.2. Until now this was
only the case for version 1.2.0.
Rolf Eike Beer 11 år sedan
förälder
incheckning
4f9bf4468b

+ 32 - 4
Modules/FindPackageHandleStandardArgs.cmake

@@ -290,12 +290,40 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
     if(VERSION)
 
       if(${_NAME}_FIND_VERSION_EXACT)       # exact version required
-        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)
+        # 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)
+          # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
+          # is at most 4 here. Therefore a simple lookup table is used.
+          if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
+            set(_VERSION_REGEX "[^.]*")
+          elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
+            set(_VERSION_REGEX "[^.]*\\.[^.]*")
+          elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
+            set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
+          else ()
+            set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
+          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 ()
-          set(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+          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}")

+ 6 - 0
Tests/RunCMake/FPHSA/FindPseudo.cmake

@@ -0,0 +1,6 @@
+# pseudo find_module
+
+set(FOOBAR TRUE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Pseudo REQUIRED_VARS FOOBAR VERSION_VAR Pseudo_VERSION)

+ 20 - 0
Tests/RunCMake/FPHSA/RunCMakeTest.cmake

@@ -1,3 +1,23 @@
 include(RunCMake)
 
 run_cmake(BadFoundVar)
+
+# The pseudo module will "find" a package with the given version. Check if the
+# version selection code in FPHSA works correctly.
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=1.2.3.4.5")
+run_cmake(any_version)
+
+# test EXACT mode with every subcomponent
+run_cmake(exact_1)
+run_cmake(exact_1.2)
+run_cmake(exact_1.2.3)
+run_cmake(exact_1.2.3.4)
+
+# now test every component with an invalid version
+run_cmake(exact_2)
+run_cmake(exact_1.1)
+run_cmake(exact_1.3)
+run_cmake(exact_1.2.2)
+run_cmake(exact_1.2.4)
+run_cmake(exact_1.2.3.3)
+run_cmake(exact_1.2.3.5)

+ 1 - 0
Tests/RunCMake/FPHSA/any_version.cmake

@@ -0,0 +1 @@
+find_package(Pseudo REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.1-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.1.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.1 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.2-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.2.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.2 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.3 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.4 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3.5 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.3.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.3 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.4-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.4.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2.4 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.2.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.2 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.3-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.3.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1.3 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_1.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 1 EXACT REQUIRED)

+ 1 - 0
Tests/RunCMake/FPHSA/exact_2-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/FPHSA/exact_2.cmake

@@ -0,0 +1 @@
+find_package(Pseudo 2 EXACT REQUIRED)