From 7f447609916d4faed8fc5b055ac337a89a47979a Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Mon, 14 Dec 2020 14:33:50 +0100 Subject: CMakePackageConfigHelpers: Relax restrictions on version range --- .../BasicConfigVersion-SameMajorVersion.cmake.in | 33 ++++-- .../BasicConfigVersion-SameMinorVersion.cmake.in | 40 ++++--- Modules/CMakePackageConfigHelpers.cmake | 9 +- .../RunCMake/WriteBasicConfigVersionFile/All.cmake | 125 ++++++++++++++++++--- 4 files changed, 160 insertions(+), 47 deletions(-) diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in index 662900d..dc04e54 100644 --- a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in @@ -9,13 +9,6 @@ # The variable CVF_VERSION must be set before calling configure_file(). -if (PACKAGE_FIND_VERSION_RANGE) - message(AUTHOR_WARNING - "`find_package()` specify a version range but the version strategy " - "(SameMajorVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible " - "with this request. Only the lower endpoint of the range will be used.") -endif() - set(PACKAGE_VERSION "@CVF_VERSION@") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) @@ -28,14 +21,30 @@ else() set(CVF_VERSION_MAJOR "@CVF_VERSION@") endif() - if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) - set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major version + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() else() - set(PACKAGE_VERSION_COMPATIBLE FALSE) - endif() + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) + endif() endif() endif() diff --git a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in index bddf4ce..9bb2efc 100644 --- a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in @@ -10,13 +10,6 @@ # The variable CVF_VERSION must be set before calling configure_file(). -if (PACKAGE_FIND_VERSION_RANGE) - message(AUTHOR_WARNING - "`find_package()` specify a version range but the version strategy " - "(SameMinorVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible " - "with this request. Only the lower endpoint of the range will be used.") -endif() - set(PACKAGE_VERSION "@CVF_VERSION@") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) @@ -31,15 +24,36 @@ else() set(CVF_VERSION_MINOR "") endif() - if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND - (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR)) - set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major and minor versions + math (EXPR CVF_VERSION_MINOR_NEXT "${CVF_VERSION_MINOR} + 1") + if (NOT (PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR) + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND NOT (PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MAX_MINOR STREQUAL CVF_VERSION_MINOR)) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL ${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR_NEXT}))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() else() - set(PACKAGE_VERSION_COMPATIBLE FALSE) - endif() + if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND + (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR)) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) + endif() endif() endif() diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index 1a7f9cf..36f2f7f 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -159,10 +159,11 @@ If your project has more elaborated version matching rules, you will need to write your own custom ``ConfigVersion.cmake`` file instead of using this macro. -.. note:: ``COMPATIBILITY_MODE`` ``AnyNewerVersion`` handles the version range - if any is specified (see :command:`find_package` command for the details). - All other modes are incompatible with version ranges and will display an - author warning if one is specified. +.. note:: ``COMPATIBILITY_MODE`` ``AnyNewerVersion``, ``SameMajorVersion`` and + ``SameMinorVersion`` handle the version range if any is specified (see + :command:`find_package` command for the details). ``ExactVersion`` is + incompatible with version ranges and will display an author warning if one is + specified. If ``ARCH_INDEPENDENT`` is given, the installed package version will be considered compatible even if it was built for a different architecture than diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake index 4253652..c32c92d 100644 --- a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake @@ -3,16 +3,16 @@ set(CMAKE_SIZEOF_VOID_P 4) include(WriteBasicConfigVersionFile) -set(_compatibilities AnyNewerVersion - SameMajorVersion - SameMinorVersion - ExactVersion) +set(COMPATIBILITIES AnyNewerVersion + SameMajorVersion + SameMinorVersion + ExactVersion) function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE_PREPARE _version_installed) set(_same_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) set(_no_CMAKE_SIZEOF_VOID_P "") math(EXPR _diff_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P} + 1") - foreach(_compat ${_compatibilities}) + foreach(_compat ${COMPATIBILITIES}) set(_pkg ${_compat}${_version_installed}) string(REPLACE "." "" _pkg ${_pkg}) set(_filename "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}ConfigVersion.cmake") @@ -71,20 +71,58 @@ function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE _version_installed _expected_compatible_SameMajorVersion _expected_compatible_SameMinorVersion _expected_compatible_ExactVersion) - set(PACKAGE_FIND_VERSION ${_version_requested}) - if("${PACKAGE_FIND_VERSION}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_4}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_6}") - set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_8}") - else() - message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") - endif() - - if ("${_version_installed}" STREQUAL "${_version_requested}") - set(_expected_exact 1) - else() + if("${_version_requested}" MATCHES [[^([0-9]+(\.[0-9]+)*)\.\.\.(<)?([0-9]+(\.[0-9]+)*)$]]) + set (_compatibilities ${COMPATIBILITIES}) + # ExactVersion must not be tested + list(POP_BACK _compatibilities) + set(PACKAGE_FIND_VERSION_RANGE TRUE) + set(PACKAGE_FIND_VERSION_RANGE_MIN INCLUDE) + if ("${CMAKE_MATCH_3}" STREQUAL "<") + set(PACKAGE_FIND_VERSION_RANGE_MAX EXCLUDE) + else() + set(PACKAGE_FIND_VERSION_RANGE_MAX INCLUDE) + endif() + set(PACKAGE_FIND_VERSION_MIN "${CMAKE_MATCH_1}") + set(PACKAGE_FIND_VERSION_MAX "${CMAKE_MATCH_4}") + if("${PACKAGE_FIND_VERSION_MIN}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MIN_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MIN_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_MIN_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_MIN_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version range") + endif() + set(PACKAGE_FIND_VERSION "${PACKAGE_FIND_VERSION_MIN}") + set(PACKAGE_FIND_VERSION_MAJOR "${PACKAGE_FIND_VERSION_MIN_MAJOR}") + set(PACKAGE_FIND_VERSION_MINOR "${PACKAGE_FIND_VERSION_MIN_MINOR}") + set(PACKAGE_FIND_VERSION_PATCH "${PACKAGE_FIND_VERSION_MIN_PATCH}") + set(PACKAGE_FIND_VERSION_TWEAK "${PACKAGE_FIND_VERSION_MIN_TWEAK}") + if("${PACKAGE_FIND_VERSION_MAX}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MAX_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MAX_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_MAX_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_MAX_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version range") + endif() set(_expected_exact 0) + else() + set (_compatibilities ${COMPATIBILITIES}) + set(PACKAGE_FIND_VERSION ${_version_requested}) + if("${PACKAGE_FIND_VERSION}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") + endif() + + if ("${_version_installed}" STREQUAL "${_version_requested}") + set(_expected_exact 1) + else() + set(_expected_exact 0) + endif() endif() unset(PACKAGE_VERSION_COMPATIBLE) @@ -882,3 +920,54 @@ test_write_basic_config_version_file(4.5.6.7 9.9.9.0 0 0 0 0) # Request [ne test_write_basic_config_version_file(4.5.6.7 9.9.9.2 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[older tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.7 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[same tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] + +test_write_basic_config_version_file(4 0...5 1 0 0 0) +test_write_basic_config_version_file(4 2...5 1 0 0 0) +test_write_basic_config_version_file(4 2...4 1 0 0 0) +test_write_basic_config_version_file(4 4...<5 1 1 0 0) +test_write_basic_config_version_file(4 9...10 0 0 0 0) + +test_write_basic_config_version_file(4 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4 2.1...4 1 0 0 0) +test_write_basic_config_version_file(4 2.8...4 1 0 0 0) +test_write_basic_config_version_file(4 4.0...<5 1 1 0 0) +test_write_basic_config_version_file(4 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4 4.1...5 0 0 0 0) +test_write_basic_config_version_file(4 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4 9.8...10 0 0 0 0) + + +test_write_basic_config_version_file(4.5 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.1...4 0 0 0 0) +test_write_basic_config_version_file(4.5 2.8...4 0 0 0 0) +test_write_basic_config_version_file(4.5 2.8...4.8 1 0 0 0) +test_write_basic_config_version_file(4.5 4.1...<5 1 1 0 0) +test_write_basic_config_version_file(4.5 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4.5 4.5...4.5.8 1 1 1 0) +test_write_basic_config_version_file(4.5 4.5...<4.6 1 1 1 0) +test_write_basic_config_version_file(4.5 4.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4.5 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4.5 9.8...10 0 0 0 0) + + +test_write_basic_config_version_file(4.5.6 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.1...4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...4.8 1 0 0 0) +test_write_basic_config_version_file(4.5.6 4.1...<5 1 1 0 0) +test_write_basic_config_version_file(4.5.6 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4.5.6 4.5...4.5.4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 4.5...4.5.8 1 1 1 0) +test_write_basic_config_version_file(4.5.6 4.5...<4.6 1 1 1 0) +test_write_basic_config_version_file(4.5.6 4.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4.5.6 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4.5.6 9.8...10 0 0 0 0) -- cgit v0.12 From 55c3b6a77e700554e6303f5cd6c4e443499363d8 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Mon, 14 Dec 2020 14:55:05 +0100 Subject: CMakePackageConfigHelpers: Relax restrictions on version range --- .../BasicConfigVersion-SameMajorVersion.cmake.in | 33 ++++-- .../BasicConfigVersion-SameMinorVersion.cmake.in | 40 ++++--- Modules/CMakePackageConfigHelpers.cmake | 7 +- .../RunCMake/WriteBasicConfigVersionFile/All.cmake | 125 ++++++++++++++++++--- 4 files changed, 159 insertions(+), 46 deletions(-) diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in index 662900d..dc04e54 100644 --- a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in @@ -9,13 +9,6 @@ # The variable CVF_VERSION must be set before calling configure_file(). -if (PACKAGE_FIND_VERSION_RANGE) - message(AUTHOR_WARNING - "`find_package()` specify a version range but the version strategy " - "(SameMajorVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible " - "with this request. Only the lower endpoint of the range will be used.") -endif() - set(PACKAGE_VERSION "@CVF_VERSION@") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) @@ -28,14 +21,30 @@ else() set(CVF_VERSION_MAJOR "@CVF_VERSION@") endif() - if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) - set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major version + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() else() - set(PACKAGE_VERSION_COMPATIBLE FALSE) - endif() + if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) + endif() endif() endif() diff --git a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in index bddf4ce..9bb2efc 100644 --- a/Modules/BasicConfigVersion-SameMinorVersion.cmake.in +++ b/Modules/BasicConfigVersion-SameMinorVersion.cmake.in @@ -10,13 +10,6 @@ # The variable CVF_VERSION must be set before calling configure_file(). -if (PACKAGE_FIND_VERSION_RANGE) - message(AUTHOR_WARNING - "`find_package()` specify a version range but the version strategy " - "(SameMinorVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible " - "with this request. Only the lower endpoint of the range will be used.") -endif() - set(PACKAGE_VERSION "@CVF_VERSION@") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) @@ -31,15 +24,36 @@ else() set(CVF_VERSION_MINOR "") endif() - if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND - (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR)) - set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION_RANGE) + # both endpoints of the range must have the expected major and minor versions + math (EXPR CVF_VERSION_MINOR_NEXT "${CVF_VERSION_MINOR} + 1") + if (NOT (PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR) + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND NOT (PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MAX_MINOR STREQUAL CVF_VERSION_MINOR)) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL ${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR_NEXT}))) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() else() - set(PACKAGE_VERSION_COMPATIBLE FALSE) - endif() + if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND + (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR)) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_COMPATIBLE FALSE) + endif() - if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) + endif() endif() endif() diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index 372e9f4..ad719ef 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -177,9 +177,10 @@ macro. packages with no binaries. .. versionadded:: 3.19 - ``COMPATIBILITY_MODE`` ``AnyNewerVersion`` handles the version range - if any is specified (see :command:`find_package` command for the details). - All other modes are incompatible with version ranges and will display an + ``COMPATIBILITY_MODE`` ``AnyNewerVersion``, ``SameMajorVersion`` and + ``SameMinorVersion`` handle the version range if any is specified + (see :command:`find_package` command for the details). + ``ExactVersion`` mode is incompatible with version ranges and will display an author warning if one is specified. Internally, this macro executes :command:`configure_file()` to create the diff --git a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake index 4253652..c32c92d 100644 --- a/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake +++ b/Tests/RunCMake/WriteBasicConfigVersionFile/All.cmake @@ -3,16 +3,16 @@ set(CMAKE_SIZEOF_VOID_P 4) include(WriteBasicConfigVersionFile) -set(_compatibilities AnyNewerVersion - SameMajorVersion - SameMinorVersion - ExactVersion) +set(COMPATIBILITIES AnyNewerVersion + SameMajorVersion + SameMinorVersion + ExactVersion) function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE_PREPARE _version_installed) set(_same_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) set(_no_CMAKE_SIZEOF_VOID_P "") math(EXPR _diff_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P} + 1") - foreach(_compat ${_compatibilities}) + foreach(_compat ${COMPATIBILITIES}) set(_pkg ${_compat}${_version_installed}) string(REPLACE "." "" _pkg ${_pkg}) set(_filename "${CMAKE_CURRENT_BINARY_DIR}/${_pkg}ConfigVersion.cmake") @@ -71,20 +71,58 @@ function(TEST_WRITE_BASIC_CONFIG_VERSION_FILE _version_installed _expected_compatible_SameMajorVersion _expected_compatible_SameMinorVersion _expected_compatible_ExactVersion) - set(PACKAGE_FIND_VERSION ${_version_requested}) - if("${PACKAGE_FIND_VERSION}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) - set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_2}") - set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_4}") - set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_6}") - set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_8}") - else() - message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") - endif() - - if ("${_version_installed}" STREQUAL "${_version_requested}") - set(_expected_exact 1) - else() + if("${_version_requested}" MATCHES [[^([0-9]+(\.[0-9]+)*)\.\.\.(<)?([0-9]+(\.[0-9]+)*)$]]) + set (_compatibilities ${COMPATIBILITIES}) + # ExactVersion must not be tested + list(POP_BACK _compatibilities) + set(PACKAGE_FIND_VERSION_RANGE TRUE) + set(PACKAGE_FIND_VERSION_RANGE_MIN INCLUDE) + if ("${CMAKE_MATCH_3}" STREQUAL "<") + set(PACKAGE_FIND_VERSION_RANGE_MAX EXCLUDE) + else() + set(PACKAGE_FIND_VERSION_RANGE_MAX INCLUDE) + endif() + set(PACKAGE_FIND_VERSION_MIN "${CMAKE_MATCH_1}") + set(PACKAGE_FIND_VERSION_MAX "${CMAKE_MATCH_4}") + if("${PACKAGE_FIND_VERSION_MIN}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MIN_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MIN_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_MIN_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_MIN_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version range") + endif() + set(PACKAGE_FIND_VERSION "${PACKAGE_FIND_VERSION_MIN}") + set(PACKAGE_FIND_VERSION_MAJOR "${PACKAGE_FIND_VERSION_MIN_MAJOR}") + set(PACKAGE_FIND_VERSION_MINOR "${PACKAGE_FIND_VERSION_MIN_MINOR}") + set(PACKAGE_FIND_VERSION_PATCH "${PACKAGE_FIND_VERSION_MIN_PATCH}") + set(PACKAGE_FIND_VERSION_TWEAK "${PACKAGE_FIND_VERSION_MIN_TWEAK}") + if("${PACKAGE_FIND_VERSION_MAX}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MAX_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MAX_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_MAX_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_MAX_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version range") + endif() set(_expected_exact 0) + else() + set (_compatibilities ${COMPATIBILITIES}) + set(PACKAGE_FIND_VERSION ${_version_requested}) + if("${PACKAGE_FIND_VERSION}" MATCHES [[(^([0-9]+)(\.([0-9]+)(\.([0-9]+)(\.([0-9]+))?)?)?)?$]]) + set(PACKAGE_FIND_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(PACKAGE_FIND_VERSION_MINOR "${CMAKE_MATCH_4}") + set(PACKAGE_FIND_VERSION_PATCH "${CMAKE_MATCH_6}") + set(PACKAGE_FIND_VERSION_TWEAK "${CMAKE_MATCH_8}") + else() + message(FATAL_ERROR "_version_requested (${_version_requested}) should be a version number") + endif() + + if ("${_version_installed}" STREQUAL "${_version_requested}") + set(_expected_exact 1) + else() + set(_expected_exact 0) + endif() endif() unset(PACKAGE_VERSION_COMPATIBLE) @@ -882,3 +920,54 @@ test_write_basic_config_version_file(4.5.6.7 9.9.9.0 0 0 0 0) # Request [ne test_write_basic_config_version_file(4.5.6.7 9.9.9.2 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[older tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.7 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[same tweak] test_write_basic_config_version_file(4.5.6.7 9.9.9.9 0 0 0 0) # Request [newer major].[newer minor].[newer patch].[newer tweak] + +test_write_basic_config_version_file(4 0...5 1 0 0 0) +test_write_basic_config_version_file(4 2...5 1 0 0 0) +test_write_basic_config_version_file(4 2...4 1 0 0 0) +test_write_basic_config_version_file(4 4...<5 1 1 0 0) +test_write_basic_config_version_file(4 9...10 0 0 0 0) + +test_write_basic_config_version_file(4 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4 2.1...4 1 0 0 0) +test_write_basic_config_version_file(4 2.8...4 1 0 0 0) +test_write_basic_config_version_file(4 4.0...<5 1 1 0 0) +test_write_basic_config_version_file(4 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4 4.1...5 0 0 0 0) +test_write_basic_config_version_file(4 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4 9.8...10 0 0 0 0) + + +test_write_basic_config_version_file(4.5 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4.5 2.1...4 0 0 0 0) +test_write_basic_config_version_file(4.5 2.8...4 0 0 0 0) +test_write_basic_config_version_file(4.5 2.8...4.8 1 0 0 0) +test_write_basic_config_version_file(4.5 4.1...<5 1 1 0 0) +test_write_basic_config_version_file(4.5 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4.5 4.5...4.5.8 1 1 1 0) +test_write_basic_config_version_file(4.5 4.5...<4.6 1 1 1 0) +test_write_basic_config_version_file(4.5 4.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4.5 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4.5 9.8...10 0 0 0 0) + + +test_write_basic_config_version_file(4.5.6 0.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 2.1...4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 2.8...4.8 1 0 0 0) +test_write_basic_config_version_file(4.5.6 4.1...<5 1 1 0 0) +test_write_basic_config_version_file(4.5.6 4.8...<5 0 0 0 0) +test_write_basic_config_version_file(4.5.6 4.5...4.5.4 0 0 0 0) +test_write_basic_config_version_file(4.5.6 4.5...4.5.8 1 1 1 0) +test_write_basic_config_version_file(4.5.6 4.5...<4.6 1 1 1 0) +test_write_basic_config_version_file(4.5.6 4.1...5 1 0 0 0) +test_write_basic_config_version_file(4.5.6 4.8...5 0 0 0 0) +test_write_basic_config_version_file(4.5.6 9.1...10 0 0 0 0) +test_write_basic_config_version_file(4.5.6 9.8...10 0 0 0 0) -- cgit v0.12