text: import textwrap
  
  from jinja2 import Template
  
  from conans.client.generators.cmake import DepsCppCmake
  from conans.client.generators.cmake_find_package_common import (target_template,
                                                                  CMakeFindPackageCommonMacros,
                                                                  find_transitive_dependencies)
  from conans.client.generators.cmake_multi import extend
  from conans.model import Generator
  from conans.model.conan_generator import GeneratorComponentsMixin
  
  
  class CMakeFindPackageGenerator(GeneratorComponentsMixin, Generator):
      name = "cmake_find_package"
  
      find_template = textwrap.dedent("""
          {macros_and_functions}
  
          include(FindPackageHandleStandardArgs)
  
          conan_message(STATUS "Conan: Using autogenerated Find{filename}.cmake")
          # Global approach
          set({filename}_FOUND 1)
          set({filename}_VERSION "{version}")
  
          find_package_handle_standard_args({filename} REQUIRED_VARS
                                            {filename}_VERSION VERSION_VAR {filename}_VERSION)
          mark_as_advanced({filename}_FOUND {filename}_VERSION)
  
          {find_libraries_block}
          if(NOT ${{CMAKE_VERSION}} VERSION_LESS "3.0")
              # Target approach
              if(NOT TARGET {namespace}::{name})
                  add_library({namespace}::{name} INTERFACE IMPORTED)
                  if({name}_INCLUDE_DIRS)
                      set_target_properties({namespace}::{name} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
                                            "${{{name}_INCLUDE_DIRS}}")
                  endif()
                  set_property(TARGET {namespace}::{name} PROPERTY INTERFACE_LINK_LIBRARIES
                               "${{{name}_LIBRARIES_TARGETS}};${{{name}_LINKER_FLAGS_LIST}}")
                  set_property(TARGET {namespace}::{name} PROPERTY INTERFACE_COMPILE_DEFINITIONS
                               ${{{name}_COMPILE_DEFINITIONS}})
                  set_property(TARGET {namespace}::{name} PROPERTY INTERFACE_COMPILE_OPTIONS
                               "${{{name}_COMPILE_OPTIONS_LIST}}")
                  {find_dependencies_block}
              endif()
          endif()
  
          foreach(_BUILD_MODULE_PATH ${{{name}_BUILD_MODULES_PATHS}})
              include(${{_BUILD_MODULE_PATH}})
          endforeach()
          """)
  
      find_components_tpl = Template(textwrap.dedent("""\
          ########## MACROS ###########################################################################
          #############################################################################################
          {{ conan_message }}
          {{ conan_find_apple_frameworks }}
          {{ conan_package_library_targets }}
  
          ########### FOUND PACKAGE ###################################################################
          #############################################################################################
  
          include(FindPackageHandleStandardArgs)
  
          conan_message(STATUS "Conan: Using autogenerated Find{{ pkg_filename }}.cmake")
          set({{ pkg_filename }}_FOUND 1)
          set({{ pkg_filename }}_VERSION "{{ pkg_version }}")
  
          find_package_handle_standard_args({{ pkg_filename }} REQUIRED_VARS
                                            {{ pkg_filename }}_VERSION VERSION_VAR {{ pkg_filename }}_VERSION)
          mark_as_advanced({{ pkg_filename }}_FOUND {{ pkg_filename }}_VERSION)
  
          set({{ pkg_name }}_COMPONENTS {{ pkg_components }})
  
          if({{ pkg_filename }}_FIND_COMPONENTS)
              foreach(_FIND_COMPONENT {{ '${'+pkg_filename+'_FIND_COMPONENTS}' }})
                  list(FIND {{ pkg_name }}_COMPONENTS "{{ namespace }}::${_FIND_COMPONENT}" _index)
                  if(${_index} EQUAL -1)
                      conan_message(FATAL_ERROR "Conan: Component '${_FIND_COMPONENT}' NOT found in package '{{ pkg_name }}'")
                  else()
                      conan_message(STATUS "Conan: Component '${_FIND_COMPONENT}' found in package '{{ pkg_name }}'")
                  endif()
              endforeach()
          endif()
  
          ########### VARIABLES #######################################################################
          #############################################################################################
  
          {{ global_target_variables }}
  
          {%- for comp_name, comp in components %}
  
          ########### COMPONENT {{ comp_name }} VARIABLES #############################################
  
          set({{ pkg_name }}_{{ comp_name }}_INCLUDE_DIRS {{ comp.include_paths }})
          set({{ pkg_name }}_{{ comp_name }}_INCLUDE_DIR {{ comp.include_path }})
          set({{ pkg_name }}_{{ comp_name }}_INCLUDES {{ comp.include_paths }})
          set({{ pkg_name }}_{{ comp_name }}_LIB_DIRS {{ comp.lib_paths }})
          set({{ pkg_name }}_{{ comp_name }}_RES_DIRS {{ comp.res_paths }})
          set({{ pkg_name }}_{{ comp_name }}_DEFINITIONS {{ comp.defines }})
          set({{ pkg_name }}_{{ comp_name }}_COMPILE_DEFINITIONS {{ comp.compile_definitions }})
          set({{ pkg_name }}_{{ comp_name }}_COMPILE_OPTIONS_C "{{ comp.cflags_list }}")
          set({{ pkg_name }}_{{ comp_name }}_COMPILE_OPTIONS_CXX "{{ comp.cxxflags_list }}")
          set({{ pkg_name }}_{{ comp_name }}_LIBS {{ comp.libs }})
          set({{ pkg_name }}_{{ comp_name }}_SYSTEM_LIBS {{ comp.system_libs }})
          set({{ pkg_name }}_{{ comp_name }}_FRAMEWORK_DIRS {{ comp.framework_paths }})
          set({{ pkg_name }}_{{ comp_name }}_FRAMEWORKS {{ comp.frameworks }})
          set({{ pkg_name }}_{{ comp_name }}_BUILD_MODULES_PATHS {{ comp.build_modules_paths }})
          set({{ pkg_name }}_{{ comp_name }}_DEPENDENCIES {{ comp.public_deps }})
          set({{ pkg_name }}_{{ comp_name }}_LINKER_FLAGS_LIST
                  "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:{{ comp.sharedlinkflags_list }}>"
                  "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:{{ comp.sharedlinkflags_list }}>"
                  "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:{{ comp.exelinkflags_list }}>"
          )
  
          {%- endfor %}
  
  
          ########## FIND PACKAGE DEPENDENCY ##########################################################
          #############################################################################################
  
          include(CMakeFindDependencyMacro)
  
          {%- for pkg_public_dep_filename in pkg_public_deps_filenames %}
  
          if(NOT {{ pkg_public_dep_filename }}_FOUND)
              find_dependency({{ pkg_public_dep_filename }} REQUIRED)
          else()
              conan_message(STATUS "Conan: Dependency {{ pkg_public_dep_filename }} already found")
          endif()
  
          {%- endfor %}
  
  
          ########## FIND LIBRARIES & FRAMEWORKS / DYNAMIC VARS #######################################
          #############################################################################################
  
          {%- for comp_name, comp in components %}
  
          ########## COMPONENT {{ comp_name }} FIND LIBRARIES & FRAMEWORKS / DYNAMIC VARS #############
  
          set({{ pkg_name }}_{{ comp_name }}_FRAMEWORKS_FOUND "")
          conan_find_apple_frameworks({{ pkg_name }}_{{ comp_name }}_FRAMEWORKS_FOUND "{{ '${'+pkg_name+'_'+comp_name+'_FRAMEWORKS}' }}" "{{ '${'+pkg_name+'_'+comp_name+'_FRAMEWORK_DIRS}' }}")
  
          set({{ pkg_name }}_{{ comp_name }}_LIB_TARGETS "")
          set({{ pkg_name }}_{{ comp_name }}_NOT_USED "")
          set({{ pkg_name }}_{{ comp_name }}_LIBS_FRAMEWORKS_DEPS {{ '${'+pkg_name+'_'+comp_name+'_FRAMEWORKS_FOUND}' }} {{ '${'+pkg_name+'_'+comp_name+'_SYSTEM_LIBS}' }} {{ '${'+pkg_name+'_'+comp_name+'_DEPENDENCIES}' }})
          conan_package_library_targets("{{ '${'+pkg_name+'_'+comp_name+'_LIBS}' }}"
                                        "{{ '${'+pkg_name+'_'+comp_name+'_LIB_DIRS}' }}"
                                        "{{ '${'+pkg_name+'_'+comp_name+'_LIBS_FRAMEWORKS_DEPS}' }}"
                                        {{ pkg_name }}_{{ comp_name }}_NOT_USED
                                        {{ pkg_name }}_{{ comp_name }}_LIB_TARGETS
                                        ""
                                        "{{ pkg_name }}_{{ comp_name }}")
  
          set({{ pkg_name }}_{{ comp_name }}_LINK_LIBS {{ '${'+pkg_name+'_'+comp_name+'_LIB_TARGETS}' }} {{ '${'+pkg_name+'_'+comp_name+'_LIBS_FRAMEWORKS_DEPS}' }})
  
          set(CMAKE_MODULE_PATH {{ comp.build_paths }} ${CMAKE_MODULE_PATH})
          set(CMAKE_PREFIX_PATH {{ comp.build_paths }} ${CMAKE_PREFIX_PATH})
  
          {%- endfor %}
  
  
          ########## TARGETS ##########################################################################
          #############################################################################################
  
          {%- for comp_name, comp in components %}
  
          ########## COMPONENT {{ comp_name }} TARGET #################################################
  
          if(NOT ${CMAKE_VERSION} VERSION_LESS "3.0")
              # Target approach
              if(NOT TARGET {{ namespace }}::{{ comp_name }})
                  add_library({{ namespace }}::{{ comp_name }} INTERFACE IMPORTED)
                  set_target_properties({{ namespace }}::{{ comp_name }} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
                                        "{{ '${'+pkg_name+'_'+comp_name+'_INCLUDE_DIRS}' }}")
                  set_target_properties({{ namespace }}::{{ comp_name }} PROPERTIES INTERFACE_LINK_DIRECTORIES
                                        "{{ '${'+pkg_name+'_'+comp_name+'_LIB_DIRS}' }}")
                  set_target_properties({{ namespace }}::{{ comp_name }} PROPERTIES INTERFACE_LINK_LIBRARIES
                                        "{{ '${'+pkg_name+'_'+comp_name+'_LINK_LIBS}' }};{{ '${'+pkg_name+'_'+comp_name+'_LINKER_FLAGS_LIST}' }}")
                  set_target_properties({{ namespace }}::{{ comp_name }} PROPERTIES INTERFACE_COMPILE_DEFINITIONS
                                        "{{ '${'+pkg_name+'_'+comp_name+'_COMPILE_DEFINITIONS}' }}")
                  set_target_properties({{ namespace }}::{{ comp_name }} PROPERTIES INTERFACE_COMPILE_OPTIONS
                                        "{{ '${'+pkg_name+'_'+comp_name+'_COMPILE_OPTIONS_C}' }};{{ '${'+pkg_name+'_'+comp_name+'_COMPILE_OPTIONS_CXX}' }}")
              endif()
          endif()
  
          {%- endfor %}
  
          ########## GLOBAL TARGET ####################################################################
  
          if(NOT ${CMAKE_VERSION} VERSION_LESS "3.0")
              if(NOT TARGET {{ namespace }}::{{ pkg_name }})
                  add_library({{ namespace }}::{{ pkg_name }} INTERFACE IMPORTED)
              endif()
              set_property(TARGET {{ namespace }}::{{ pkg_name }} APPEND PROPERTY
                           INTERFACE_LINK_LIBRARIES "{{ '${'+pkg_name+'_COMPONENTS}' }}")
          endif()
  
          ########## BUILD MODULES ####################################################################
          #############################################################################################
  
          {%- for comp_name, comp in components %}
          ########## COMPONENT {{ comp_name }} BUILD MODULES ##########################################
  
          foreach(_BUILD_MODULE_PATH {{ '${'+pkg_name+'_'+comp_name+'_BUILD_MODULES_PATHS}' }})
              include(${_BUILD_MODULE_PATH})
          endforeach()
  
          {%- endfor %}
  
      """))
  
      @property
      def filename(self):
          return None
  
      @classmethod
      def _get_filename(cls, obj):
          return obj.get_filename(cls.name)
  
      @property
      def content(self):
          ret = {}
          for pkg_name, cpp_info in self.deps_build_info.dependencies:
              pkg_filename = self._get_filename(cpp_info)
              pkg_findname = self._get_name(cpp_info)
              pkg_namespace = pkg_findname
              ret["Find%s.cmake" % pkg_filename] = self._find_for_dep(
                  pkg_name=pkg_name,
                  pkg_findname=pkg_findname,
                  pkg_filename=pkg_filename,
                  pkg_namespace=pkg_namespace,
                  cpp_info=cpp_info
              )
          return ret
  
      def _get_components(self, pkg_name, cpp_info):
          components = super(CMakeFindPackageGenerator, self)._get_components(pkg_name, cpp_info)
          ret = []
          for comp_genname, comp, comp_requires_gennames in components:
              deps_cpp_cmake = DepsCppCmake(comp, self.name)
              deps_cpp_cmake.public_deps = " ".join(
                  ["{}::{}".format(*it) for it in comp_requires_gennames])
              ret.append((comp_genname, deps_cpp_cmake))
          return ret
  
      def _find_for_dep(self, pkg_name, pkg_findname, pkg_filename, pkg_namespace, cpp_info):
          # return the content of the FindXXX.cmake file for the package "pkg_name"
          self._validate_components(cpp_info)
  
          public_deps = self.get_public_deps(cpp_info)
          deps_names = []
          for it in public_deps:
              name = "{}::{}".format(*self._get_require_name(*it))
              if name not in deps_names:
                  deps_names.append(name)
          deps_names = ';'.join(deps_names)
          pkg_public_deps_filenames = [self._get_filename(self.deps_build_info[it[0]]) for it in
                                       public_deps]
  
          pkg_version = cpp_info.version
          if cpp_info.components:
              components = self._get_components(pkg_name, cpp_info)
              # Note these are in reversed order, from more dependent to less dependent
              pkg_components = " ".join(["{p}::{c}".format(p=pkg_namespace, c=comp_findname) for
                                         comp_findname, _ in reversed(components)])
              pkg_info = DepsCppCmake(cpp_info, self.name)
              global_target_variables = target_template.format(name=pkg_findname, deps=pkg_info,
                                                               build_type_suffix="",
                                                               deps_names=deps_names)
              return self.find_components_tpl.render(
                  pkg_name=pkg_findname,
                  namespace=pkg_namespace,
                  pkg_filename=pkg_filename,
                  pkg_version=pkg_version,
                  pkg_components=pkg_components,
                  global_target_variables=global_target_variables,
                  pkg_public_deps_filenames=pkg_public_deps_filenames,
                  components=components,
                  conan_message=CMakeFindPackageCommonMacros.conan_message,
                  conan_find_apple_frameworks=CMakeFindPackageCommonMacros.apple_frameworks_macro,
                  conan_package_library_targets=CMakeFindPackageCommonMacros.conan_package_library_targets)
          else:
              # The common macros
              macros_and_functions = "\n".join([
                  CMakeFindPackageCommonMacros.conan_message,
                  CMakeFindPackageCommonMacros.apple_frameworks_macro,
                  CMakeFindPackageCommonMacros.conan_package_library_targets,
              ])
  
              # compose the cpp_info with its "debug" or "release" specific config
              dep_cpp_info = cpp_info
              build_type = self.conanfile.settings.get_safe("build_type")
              if build_type:
                  dep_cpp_info = extend(dep_cpp_info, build_type.lower())
  
              # The find_libraries_block, all variables for the package, and creation of targets
              deps = DepsCppCmake(dep_cpp_info, self.name)
              find_libraries_block = target_template.format(name=pkg_findname,
                                                            deps=deps, build_type_suffix="",
                                                            deps_names=deps_names)
  
              # The find_transitive_dependencies block
              find_dependencies_block = ""
              if pkg_public_deps_filenames:
                  # Here we are generating FindXXX, so find_modules=True
                  f = find_transitive_dependencies(pkg_public_deps_filenames, find_modules=True)
                  # proper indentation
                  find_dependencies_block = ''.join("        " + line if line.strip() else line
                                                    for line in f.splitlines(True))
  
              return self.find_template.format(name=pkg_findname, namespace=pkg_namespace,
                                               version=pkg_version,
                                               filename=pkg_filename,
                                               find_libraries_block=find_libraries_block,
                                               find_dependencies_block=find_dependencies_block,
                                               macros_and_functions=macros_and_functions)
  