From eaec9cf65dc3a1136d6d1f97ca6e087d58b5e07a Mon Sep 17 00:00:00 2001 From: Christian Heimlich Date: Sun, 3 Jul 2022 01:36:36 -0400 Subject: FindDoxygen: Implement more complete version checking The foundation of the Doxygen Find Module's detection methodology is the command `find_program`, which has inhibited the module from properly handling user version restrictions when provided. Because `find_program` historically has always returned after the first match and does not consider version constraints, users of this module are inadvertently at the mercy of the command's search procedure. Essentially, `find_package(Doxygen ...)` will always provide the first Doxygen build found through said procedure, even if it conflicts with the user's version requirements, and even if another build exists on the system that would satisfy those requirements (i.e. shadowing). Utilizes the new `VALIDATOR` option of `find_program` to ensure all otherwise detectable builds of Doxygen on a given system are evaluated and that only a build in compliance with `Doxygen_FIND_VERSION` et. al., when defined, will be matched against. Also enables handling of version ranges specified within `find_package` via the **FindPackageHandleStandardArgs** module. Finally, ensures that only the major, minor, and patch components of Doxygen's `--version` output are captured for comparison in cases where it contains additional information, such as a git commit hash. Fixes: #23692 --- .../dev/finddoxygen-better-version-checking.rst | 11 ++++++ Modules/FindDoxygen.cmake | 46 ++++++++++++++++++---- 2 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Help/release/dev/finddoxygen-better-version-checking.rst diff --git a/Help/release/dev/finddoxygen-better-version-checking.rst b/Help/release/dev/finddoxygen-better-version-checking.rst new file mode 100644 index 0000000..3c2215d --- /dev/null +++ b/Help/release/dev/finddoxygen-better-version-checking.rst @@ -0,0 +1,11 @@ +finddoxygen-better-version-checking +----------------------------------- + +* The :module:`FindDoxygen` module now evaluates as many candidate + Doxygen installs as are necessary to satisfy version constraints, + with the package considered to be not found if none are available. + +* The :module:`FindDoxygen` module now handles version ranges. + +* The :module:`FindDoxygen` module now ignores non-semantic portions + of the output from Doxygen's `--version` option. diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 4a16e31..23b7107 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -432,9 +432,44 @@ endif() # or use something like homebrew. # ============== End OSX stuff ================ +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + # # Find Doxygen... # +function(_Doxygen_get_version doxy_version result_var doxy_path) + execute_process( + COMMAND "${doxy_path}" --version + OUTPUT_VARIABLE full_doxygen_version + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE version_result + ) + + # Ignore any commit hashes, etc. + string(REGEX MATCH [[^[0-9]+\.[0-9]+\.[0-9]+]] sem_doxygen_version "${full_doxygen_version}") + + set(${result_var} ${version_result} PARENT_SCOPE) + set(${doxy_version} ${sem_doxygen_version} PARENT_SCOPE) +endfunction() + +function(_Doxygen_version_validator version_match doxy_path) + if(NOT DEFINED Doxygen_FIND_VERSION) + set(${is_valid_version} TRUE PARENT_SCOPE) + else() + _Doxygen_get_version(candidate_version version_result "${doxy_path}") + + if(version_result) + message(DEBUG "Unable to determine candidate doxygen version at ${doxy_path}: ${version_result}") + endif() + + find_package_check_version("${candidate_version}" valid_doxy_version + HANDLE_VERSION_RANGE + ) + + set(${version_match} "${valid_doxy_version}" PARENT_SCOPE) + endif() +endfunction() + macro(_Doxygen_find_doxygen) find_program( DOXYGEN_EXECUTABLE @@ -446,16 +481,13 @@ macro(_Doxygen_find_doxygen) /Applications/Utilities/Doxygen.app/Contents/Resources /Applications/Utilities/Doxygen.app/Contents/MacOS DOC "Doxygen documentation generation tool (http://www.doxygen.org)" + VALIDATOR _Doxygen_version_validator ) mark_as_advanced(DOXYGEN_EXECUTABLE) if(DOXYGEN_EXECUTABLE) - execute_process( - COMMAND "${DOXYGEN_EXECUTABLE}" --version - OUTPUT_VARIABLE DOXYGEN_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _Doxygen_version_result - ) + _Doxygen_get_version(DOXYGEN_VERSION _Doxygen_version_result "${DOXYGEN_EXECUTABLE}") + if(_Doxygen_version_result) message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}") endif() @@ -642,11 +674,11 @@ endforeach() unset(_comp) # Verify find results -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args( Doxygen REQUIRED_VARS DOXYGEN_EXECUTABLE VERSION_VAR DOXYGEN_VERSION + HANDLE_VERSION_RANGE HANDLE_COMPONENTS ) -- cgit v0.12