From d71ec0cd1d5a6fe288cb8462e6ca9805798947a3 Mon Sep 17 00:00:00 2001 From: Sergiu Deitsch Date: Sun, 20 Nov 2016 14:36:34 +0100 Subject: [PATCH] cmake: support OPTIONAL_COMPONENTS in OpenCVConfig.cmake find_package allows to specify optional components. This way, the command will not fail if any of the components marked as optional was not found. This is useful in cases where components such as xfeatures2d, viz etc. are not available either because they were not compiled by the user or package maintainers decided to not provide the packages at all. The user can check the availability of the optional component using the OpenCV__FOUND variable. --- cmake/templates/OpenCVConfig.cmake.in | 51 ++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/cmake/templates/OpenCVConfig.cmake.in b/cmake/templates/OpenCVConfig.cmake.in index dfe9aeafe1..47751f55cf 100644 --- a/cmake/templates/OpenCVConfig.cmake.in +++ b/cmake/templates/OpenCVConfig.cmake.in @@ -14,6 +14,10 @@ # # find_package(OpenCV REQUIRED core videoio) # +# You can also mark OpenCV components as optional: + +# find_package(OpenCV REQUIRED core OPTIONAL_COMPONENTS viz) +# # If the module is found then OPENCV__FOUND is set to TRUE. # # This file will define the following variables: @@ -48,6 +52,21 @@ SET(OpenCV_VERSION_PATCH @OPENCV_VERSION_PATCH@) SET(OpenCV_VERSION_TWEAK 0) SET(OpenCV_VERSION_STATUS "@OPENCV_VERSION_STATUS@") +include(FindPackageHandleStandardArgs) + +if(NOT CMAKE_VERSION VERSION_LESS 2.8.8 + AND OpenCV_FIND_COMPONENTS # prevent excessive output +) + # HANDLE_COMPONENTS was introduced in CMake 2.8.8 + list(APPEND _OpenCV_FPHSA_ARGS HANDLE_COMPONENTS) + # The missing components will be handled by the FindPackageHandleStandardArgs + # module. + set(_OpenCV_HANDLE_COMPONENTS_MANUALLY FALSE) +else() + # The missing components will be handled by this config. + set(_OpenCV_HANDLE_COMPONENTS_MANUALLY TRUE) +endif() + # Extract directory name from full path of the file currently being processed. # Note that CMake 2.8.3 introduced CMAKE_CURRENT_LIST_DIR. We reimplement it # for older versions of CMake to support these as well. @@ -120,24 +139,33 @@ endif() set(OpenCV_WORLD_COMPONENTS @OPENCV_WORLD_MODULES@) # expand short module names and see if requested components exist -set(OpenCV_FIND_COMPONENTS_ "") foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) + # Store the name of the original component so we can set the + # OpenCV__FOUND variable which can be checked by the user. + set (__original_cvcomponent ${__cvcomponent}) if(NOT __cvcomponent MATCHES "^opencv_") set(__cvcomponent opencv_${__cvcomponent}) endif() list(FIND OpenCV_LIB_COMPONENTS ${__cvcomponent} __cvcomponentIdx) if(__cvcomponentIdx LESS 0) - #requested component is not found... - if(OpenCV_FIND_REQUIRED) - message(FATAL_ERROR "${__cvcomponent} is required but was not found") - elseif(NOT OpenCV_FIND_QUIETLY) - message(WARNING "${__cvcomponent} is required but was not found") - endif() + if(_OpenCV_HANDLE_COMPONENTS_MANUALLY) + # Either the component is required or the user did not set any components at + # all. In the latter case, the OpenCV_FIND_REQUIRED_ variable + # will not be defined since it is not set by this config. So let's assume + # the implicitly set components are always required. + if(NOT DEFINED OpenCV_FIND_REQUIRED_${__original_cvcomponent} OR + OpenCV_FIND_REQUIRED_${__original_cvcomponent}) + message(FATAL_ERROR "${__cvcomponent} is required but was not found") + elseif(NOT OpenCV_FIND_QUIETLY) + # The component was marked as optional using OPTIONAL_COMPONENTS + message(WARNING "Optional component ${__cvcomponent} was not found") + endif() + endif(_OpenCV_HANDLE_COMPONENTS_MANUALLY) #indicate that module is NOT found string(TOUPPER "${__cvcomponent}" __cvcomponentUP) set(${__cvcomponentUP}_FOUND "${__cvcomponentUP}_FOUND-NOTFOUND") + set(OpenCV_${__original_cvcomponent}_FOUND FALSE) else() - list(APPEND OpenCV_FIND_COMPONENTS_ ${__cvcomponent}) # Not using list(APPEND) here, because OpenCV_LIBS may not exist yet. # Also not clearing OpenCV_LIBS anywhere, so that multiple calls # to find_package(OpenCV) with different component lists add up. @@ -145,6 +173,7 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) #indicate that module is found string(TOUPPER "${__cvcomponent}" __cvcomponentUP) set(${__cvcomponentUP}_FOUND 1) + set(OpenCV_${__original_cvcomponent}_FOUND TRUE) endif() if(OpenCV_SHARED AND ";${OpenCV_WORLD_COMPONENTS};" MATCHES ";${__cvcomponent};" AND NOT TARGET ${__cvcomponent}) get_target_property(__implib_dbg opencv_world IMPORTED_IMPLIB_DEBUG) @@ -170,7 +199,6 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS}) endif() endif() endforeach() -set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_}) # ============================================================== # Compatibility stuff @@ -226,3 +254,8 @@ macro(ocv_list_filterout lst regex) endif() endforeach() endmacro() + +# We do not actually need REQUIRED_VARS to be checked for. Just use the +# installation directory for the status. +find_package_handle_standard_args(OpenCV REQUIRED_VARS OpenCV_INSTALL_PATH + VERSION_VAR OpenCV_VERSION ${_OpenCV_FPHSA_ARGS})