diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index e8d1dfb90..23f3f0511 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -284,18 +284,47 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) # version handling: set(VERSION_MSG "") set(VERSION_OK TRUE) - set(VERSION ${${FPHSA_VERSION_VAR}} ) - if (${_NAME}_FIND_VERSION) + set(VERSION ${${FPHSA_VERSION_VAR}}) - if(VERSION) + # check with DEFINED here as the requested or found version may be "0" + if (DEFINED ${_NAME}_FIND_VERSION) + if(DEFINED ${FPHSA_VERSION_VAR}) 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}") diff --git a/Tests/RunCMake/FPHSA/FindPseudo.cmake b/Tests/RunCMake/FPHSA/FindPseudo.cmake new file mode 100644 index 000000000..dc3558bd4 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake index 0d48fa973..bb7743c0f 100644 --- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake +++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake @@ -1,3 +1,28 @@ 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_0) +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) + +# check if searching for a version 0 works +list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=0") +run_cmake(exact_0_matching) diff --git a/Tests/RunCMake/FPHSA/any_version.cmake b/Tests/RunCMake/FPHSA/any_version.cmake new file mode 100644 index 000000000..b34a540c9 --- /dev/null +++ b/Tests/RunCMake/FPHSA/any_version.cmake @@ -0,0 +1 @@ +find_package(Pseudo REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_0-result.txt b/Tests/RunCMake/FPHSA/exact_0-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_0.cmake b/Tests/RunCMake/FPHSA/exact_0.cmake new file mode 100644 index 000000000..432887bad --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_0.cmake @@ -0,0 +1 @@ +find_package(Pseudo 0 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_0_matching.cmake b/Tests/RunCMake/FPHSA/exact_0_matching.cmake new file mode 100644 index 000000000..432887bad --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_0_matching.cmake @@ -0,0 +1 @@ +find_package(Pseudo 0 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.1-result.txt b/Tests/RunCMake/FPHSA/exact_1.1-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.1.cmake b/Tests/RunCMake/FPHSA/exact_1.1.cmake new file mode 100644 index 000000000..d967da927 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.1.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.1 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.2.2.cmake b/Tests/RunCMake/FPHSA/exact_1.2.2.cmake new file mode 100644 index 000000000..e959f610e --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.2.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.2 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake new file mode 100644 index 000000000..af53cc8da --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.3.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.3.3 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake new file mode 100644 index 000000000..1e2baa64e --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.4.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.3.4 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.5-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake new file mode 100644 index 000000000..ddb0d1378 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.5.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.3.5 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.3.cmake b/Tests/RunCMake/FPHSA/exact_1.2.3.cmake new file mode 100644 index 000000000..bf9b2a316 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.3.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.3 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt b/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.2.4.cmake b/Tests/RunCMake/FPHSA/exact_1.2.4.cmake new file mode 100644 index 000000000..548a07956 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.4.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2.4 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.2.cmake b/Tests/RunCMake/FPHSA/exact_1.2.cmake new file mode 100644 index 000000000..080d96108 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.2.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.2 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.3-result.txt b/Tests/RunCMake/FPHSA/exact_1.3-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_1.3.cmake b/Tests/RunCMake/FPHSA/exact_1.3.cmake new file mode 100644 index 000000000..e36b0c568 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.3.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1.3 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_1.cmake b/Tests/RunCMake/FPHSA/exact_1.cmake new file mode 100644 index 000000000..adadbc4cf --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_1.cmake @@ -0,0 +1 @@ +find_package(Pseudo 1 EXACT REQUIRED) diff --git a/Tests/RunCMake/FPHSA/exact_2-result.txt b/Tests/RunCMake/FPHSA/exact_2-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FPHSA/exact_2.cmake b/Tests/RunCMake/FPHSA/exact_2.cmake new file mode 100644 index 000000000..55353a8b8 --- /dev/null +++ b/Tests/RunCMake/FPHSA/exact_2.cmake @@ -0,0 +1 @@ +find_package(Pseudo 2 EXACT REQUIRED)