Repository: conan-io/conan

Issue:
[bug] Propagation of cpp_info.name in cmake_find_package_multi
The `cmake_find_package_multi` correctly generates *XXXConfig.cmake* files using the dependency's `cpp_info.name` for the `XXX` part, but doesn't always correctly use `cpp_info.name` inside the generated file.

### Environment Details
  * Operating System+version: Ubuntu 18.04
  * Conan version: 1.19.2
  * Python version: 3.6.8

### Steps to reproduce

I have got an ITK recipe that requires both `zlib` and `hdf5` and uses `cmake_find_package_multi`, the `hdf5` recipe also requires `zlib`. Everything worked smoothly up to yesterday when the `cpp_info.name` of `zlib` was changed to `ZLIB`: now `cmake_find_package_multi` correctly generates *HDF5Config.cmake* and *ZLIBConfig.cmake* as expected, but the *HDF5Config.cmake* file contains the following lines:

```cmake
include(CMakeFindDependencyMacro)
if(${CMAKE_VERSION} VERSION_LESS "3.9.0")
  find_package(zlib REQUIRED NO_MODULE)
else()
  find_dependency(zlib REQUIRED NO_MODULE)
endif()
get_target_property(tmp zlib::zlib INTERFACE_LINK_LIBRARIES)
```

When the `find_dependency` above is called, it searches a file called *zlibConfig.cmake* instead of the generated *ZLIBConfig.cmake*. I can't tell for sure, but I believe that `cmake_find_package_multi` doesn't correctly propagate the `cpp_info.name` in to the `find_dependency` and subsequent target names when it should.

### Logs (Executed commands with output) (Include/Attach if Applicable)

The relevant logs are the following ones:

```
CMake Error at /usr/share/cmake-3.10/Modules/CMakeFindDependencyMacro.cmake:48 (find_package):
  Could not find a package configuration file provided by "zlib" with any of
  the following names:

    zlibConfig.cmake
    zlib-config.cmake

  Add the installation prefix of "zlib" to CMAKE_PREFIX_PATH or set
  "zlib_DIR" to a directory containing one of the above files.  If "zlib"
  provides a separate development package or SDK, be sure it has been
  installed.
Call Stack (most recent call first):
  HDF5Config.cmake:43 (find_dependency)
  source_subfolder/Modules/ThirdParty/HDF5/itk-module-init.cmake:5 (find_package)
  source_subfolder/CMake/ITKModuleEnablement.cmake:318 (include)
  source_subfolder/CMakeLists.txt:433 (include)


-- Configuring incomplete, errors occurred!
```



Discussion:
Sure, this is a clear bug. Thanks a lot for the detailed report

Resolving patch:
diff --git a/conans/client/generators/cmake_find_package.py b/conans/client/generators/cmake_find_package.py
--- a/conans/client/generators/cmake_find_package.py
+++ b/conans/client/generators/cmake_find_package.py
@@ -56,7 +56,8 @@ def _find_for_dep(self, name, cpp_info):
         lines = []
         if cpp_info.public_deps:
             # Here we are generating FindXXX, so find_modules=True
-            lines = find_dependency_lines(name, cpp_info, find_modules=True)
+            public_deps_names = [self.deps_build_info[dep].name for dep in cpp_info.public_deps]
+            lines = find_dependency_lines(name, public_deps_names, find_modules=True)
         find_package_header_block = find_package_header.format(name=name, version=cpp_info.version)
         find_libraries_block = target_template.format(name=name, deps=deps, build_type_suffix="")
         target_props = assign_target_properties.format(name=name, deps=deps)
@@ -69,26 +70,26 @@ def _find_for_dep(self, name, cpp_info):
         return tmp
 
 
-def find_dependency_lines(name, cpp_info, find_modules):
+def find_dependency_lines(name, public_deps_names, find_modules):
     lines = ["", "# Library dependencies", "include(CMakeFindDependencyMacro)"]
-    for dep in cpp_info.public_deps:
+    for dep_name in public_deps_names:
         def property_lines(prop):
             lib_t = "%s::%s" % (name, name)
-            dep_t = "%s::%s" % (dep, dep)
+            dep_t = "%s::%s" % (dep_name, dep_name)
             return ["get_target_property(tmp %s %s)" % (dep_t, prop),
                     "if(tmp)",
                     "  set_property(TARGET %s APPEND PROPERTY %s ${tmp})" % (lib_t, prop),
                     'endif()']
 
         if find_modules:
-            lines.append("find_dependency(%s REQUIRED)" % dep)
+            lines.append("find_dependency(%s REQUIRED)" % dep_name)
         else:
             # https://github.com/conan-io/conan/issues/4994
             # https://github.com/conan-io/conan/issues/5040
             lines.append('if(${CMAKE_VERSION} VERSION_LESS "3.9.0")')
-            lines.append('  find_package(%s REQUIRED NO_MODULE)' % dep)
+            lines.append('  find_package(%s REQUIRED NO_MODULE)' % dep_name)
             lines.append("else()")
-            lines.append('  find_dependency(%s REQUIRED NO_MODULE)' % dep)
+            lines.append('  find_dependency(%s REQUIRED NO_MODULE)' % dep_name)
             lines.append("endif()")
 
         lines.extend(property_lines("INTERFACE_LINK_LIBRARIES"))
diff --git a/conans/client/generators/cmake_find_package_multi.py b/conans/client/generators/cmake_find_package_multi.py
--- a/conans/client/generators/cmake_find_package_multi.py
+++ b/conans/client/generators/cmake_find_package_multi.py
@@ -88,7 +88,8 @@ def _find_for_dep(self, name, cpp_info):
         lines = []
         if cpp_info.public_deps:
             # Here we are generating only Config files, so do not search for FindXXX modules
-            lines = find_dependency_lines(name, cpp_info, find_modules=False)
+            public_deps_names = [self.deps_build_info[dep].name for dep in cpp_info.public_deps]
+            lines = find_dependency_lines(name, public_deps_names, find_modules=False)
 
         targets_props = self.target_properties.format(name=name)
 


Test patch:
diff --git a/conans/test/functional/generators/cmake_find_package_multi_test.py b/conans/test/functional/generators/cmake_find_package_multi_test.py
--- a/conans/test/functional/generators/cmake_find_package_multi_test.py
+++ b/conans/test/functional/generators/cmake_find_package_multi_test.py
@@ -5,6 +5,7 @@
 
 from nose.plugins.attrib import attr
 
+from conans.client.tools import replace_in_file
 from conans.test.utils.tools import TestClient
 from conans.util.files import load
 
@@ -76,3 +77,55 @@ def test_native_export_multi(self):
                         self.assertIn("Hello World {}!".format(bt), c.out)
                         self.assertIn("bye World {}!".format(bt), c.out)
                         os.remove(os.path.join(c.current_folder, "example"))
+
+    def cpp_info_name_test(self):
+        client = TestClient()
+        client.run("new hello/1.0 -s")
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'self.cpp_info.libs = ["hello"]',
+                        'self.cpp_info.libs = ["hello"]\n        self.cpp_info.name = "MYHELLO"',
+                        output=client.out)
+        client.run("create .")
+        client.run("new hello2/1.0 -s")
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'self.cpp_info.libs = ["hello"]',
+                        'self.cpp_info.libs = ["hello"]\n        self.cpp_info.name = "MYHELLO2"',
+                        output=client.out)
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'exports_sources = "src/*"',
+                        'exports_sources = "src/*"\n    requires = "hello/1.0"',
+                        output=client.out)
+        client.run("create .")
+        cmakelists = """
+project(consumer)
+cmake_minimum_required(VERSION 3.1)
+find_package(MYHELLO2)
+
+get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES)
+message("Target libs: ${tmp}")
+"""
+        conanfile = """
+from conans import ConanFile, CMake
+
+
+class Conan(ConanFile):
+    settings = "build_type"
+    requires = "hello2/1.0"
+    generators = "cmake_find_package_multi"
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure()
+        """
+        client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists})
+        client.run("install .")
+        client.run("build .")
+        self.assertIn("Target libs: $<$<CONFIG:Release>:CONAN_LIB::MYHELLO2_hello_RELEASE;>;"
+                      "$<$<CONFIG:RelWithDebInfo>:;>;"
+                      "$<$<CONFIG:MinSizeRel>:;>;"
+                      "$<$<CONFIG:Debug>:;>;$"
+                      "<$<CONFIG:Release>:CONAN_LIB::MYHELLO_hello_RELEASE;>;"
+                      "$<$<CONFIG:RelWithDebInfo>:;>;"
+                      "$<$<CONFIG:MinSizeRel>:;>;"
+                      "$<$<CONFIG:Debug>:;>",
+                      client.out)
diff --git a/conans/test/functional/generators/cmake_find_package_test.py b/conans/test/functional/generators/cmake_find_package_test.py
--- a/conans/test/functional/generators/cmake_find_package_test.py
+++ b/conans/test/functional/generators/cmake_find_package_test.py
@@ -1,9 +1,11 @@
+import os
 import platform
 import six
 import unittest
 
 from nose.plugins.attrib import attr
 
+from conans.client.tools import replace_in_file
 from conans.test.utils.cpp_test_files import cpp_hello_conan_files
 from conans.test.utils.tools import TestClient
 
@@ -250,3 +252,49 @@ def build(self):
         six.assertRegex(self, str(client.out), "Libraries to Link: .*Foundation\\.framework")
         six.assertRegex(self, str(client.out), "Target libs: .*Foundation\\.framework")
         self.assertIn("Version: 0.1", client.out)
+
+    def cpp_info_name_test(self):
+        client = TestClient()
+        client.run("new hello/1.0 -s")
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'self.cpp_info.libs = ["hello"]',
+                        'self.cpp_info.libs = ["hello"]\n        self.cpp_info.name = "MYHELLO"',
+                        output=client.out)
+        client.run("create .")
+        client.run("new hello2/1.0 -s")
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'self.cpp_info.libs = ["hello"]',
+                        'self.cpp_info.libs = ["hello"]\n        self.cpp_info.name = "MYHELLO2"',
+                        output=client.out)
+        replace_in_file(os.path.join(client.current_folder, "conanfile.py"),
+                        'exports_sources = "src/*"',
+                        'exports_sources = "src/*"\n    requires = "hello/1.0"',
+                        output=client.out)
+        client.run("create .")
+        cmakelists = """
+project(consumer)
+cmake_minimum_required(VERSION 3.1)
+find_package(MYHELLO2)
+
+get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES)
+message("Target libs: ${tmp}")
+"""
+        conanfile = """
+from conans import ConanFile, CMake
+
+
+class Conan(ConanFile):
+    requires = "hello2/1.0"
+    generators = "cmake_find_package"
+
+    def build(self):
+        cmake = CMake(self)
+        cmake.configure()
+        """
+        client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists})
+        client.run("install .")
+        client.run("build .")
+        self.assertIn('Found MYHELLO2: 1.0 (found version "1.0")', client.out)
+        self.assertIn('Found MYHELLO: 1.0 (found version "1.0")', client.out)
+        self.assertIn("Target libs: CONAN_LIB::MYHELLO2_hello;;;CONAN_LIB::MYHELLO_hello",
+                      client.out)
diff --git a/conans/test/unittests/client/generators/cmake_test.py b/conans/test/unittests/client/generators/cmake_test.py
--- a/conans/test/unittests/client/generators/cmake_test.py
+++ b/conans/test/unittests/client/generators/cmake_test.py
@@ -2,9 +2,11 @@
 import re
 import unittest
 
+import six
+
 from conans.client.build.cmake_flags import CMakeDefinitionsBuilder
 from conans.client.conf import default_settings_yml
-from conans.client.generators import CMakeFindPackageGenerator
+from conans.client.generators import CMakeFindPackageGenerator, CMakeFindPackageMultiGenerator
 from conans.client.generators.cmake import CMakeGenerator
 from conans.client.generators.cmake_multi import CMakeMultiGenerator
 from conans.errors import ConanException
@@ -34,7 +36,9 @@ def compiler(self):
     def constraint(self, _):
         return self
 
-    def get_safe(self, _):
+    def get_safe(self, name):
+        if name == "build_type":
+            return self.build_type
         return None
 
     def items(self):
@@ -345,21 +349,29 @@ def apple_frameworks_test(self):
         self.assertIn('set(CONAN_LIBS  ${CONAN_FRAMEWORK_OPENGL} '
                       '${CONAN_FRAMEWORK_OPENCL} ${CONAN_LIBS})', content)
 
-    def cpp_info_name_cmake_vars_test(self):
-        """
-        Test cpp_info.names values are applied instead of the reference name
-        """
-        conanfile = ConanFile(TestBufferConanOutput(), None)
-        conanfile.initialize(Settings({}), EnvValues())
+
+class CMakeCppInfoNameTest(unittest.TestCase):
+    """
+    Test cpp_info.name values are applied in generators instead of the reference name
+    """
+
+    def setUp(self):
+        self.conanfile = ConanFile(TestBufferConanOutput(), None)
+        settings = _MockSettings()
+        settings.build_type = "Debug"
+        self.conanfile.initialize(settings, EnvValues())
         ref = ConanFileReference.loads("my_pkg/0.1@lasote/stables")
         cpp_info = CppInfo("dummy_root_folder1")
         cpp_info.name = "MyPkG"
-        conanfile.deps_cpp_info.update(cpp_info, ref.name)
+        self.conanfile.deps_cpp_info.update(cpp_info, ref.name)
         ref = ConanFileReference.loads("my_pkg2/0.1@lasote/stables")
         cpp_info = CppInfo("dummy_root_folder2")
         cpp_info.name = "MyPkG2"
-        conanfile.deps_cpp_info.update(cpp_info, ref.name)
-        generator = CMakeGenerator(conanfile)
+        cpp_info.public_deps = ["my_pkg"]
+        self.conanfile.deps_cpp_info.update(cpp_info, ref.name)
+
+    def cmake_test(self):
+        generator = CMakeGenerator(self.conanfile)
         content = generator.content
         self.assertIn("set(CONAN_DEPENDENCIES my_pkg my_pkg2)", content)
         content = content.replace("set(CONAN_DEPENDENCIES my_pkg my_pkg2)", "")
@@ -370,21 +382,22 @@ def cpp_info_name_cmake_vars_test(self):
         self.assertNotIn('CONAN_PKG::my_pkg', content)
         self.assertNotIn('CONAN_PKG::my_pkg2', content)
 
-    def cpp_info_name_cmake_find_package_test(self):
-        """
-        Test cpp_info.names values are applied instead of the reference name
-        """
-        conanfile = ConanFile(TestBufferConanOutput(), None)
-        conanfile.initialize(Settings({}), EnvValues())
-        ref = ConanFileReference.loads("my_pkg/0.1@lasote/stables")
-        cpp_info = CppInfo("dummy_root_folder1")
-        cpp_info.name = "MyPkG"
-        conanfile.deps_cpp_info.update(cpp_info, ref.name)
-        ref = ConanFileReference.loads("my_pkg2/0.1@lasote/stables")
-        cpp_info = CppInfo("dummy_root_folder2")
-        cpp_info.name = "MyPkG2"
-        conanfile.deps_cpp_info.update(cpp_info, ref.name)
-        generator = CMakeFindPackageGenerator(conanfile)
+    def cmake_multi_test(self):
+        generator = CMakeMultiGenerator(self.conanfile)
+        content = generator.content
+        self.assertIn("set(CONAN_DEPENDENCIES_DEBUG my_pkg my_pkg2)",
+                      content["conanbuildinfo_debug.cmake"])
+        self.assertNotIn("my_pkg", content["conanbuildinfo_multi.cmake"])
+        self.assertNotIn("MY_PKG", content["conanbuildinfo_multi.cmake"])
+        self.assertIn('add_library(CONAN_PKG::MyPkG INTERFACE IMPORTED)',
+                      content["conanbuildinfo_multi.cmake"])
+        self.assertIn('add_library(CONAN_PKG::MyPkG2 INTERFACE IMPORTED)',
+                      content["conanbuildinfo_multi.cmake"])
+        self.assertNotIn('CONAN_PKG::my_pkg', content["conanbuildinfo_multi.cmake"])
+        self.assertNotIn('CONAN_PKG::my_pkg2', content["conanbuildinfo_multi.cmake"])
+
+    def cmake_find_package_test(self):
+        generator = CMakeFindPackageGenerator(self.conanfile)
         content = generator.content
         self.assertIn("FindMyPkG.cmake", content.keys())
         self.assertIn("FindMyPkG2.cmake", content.keys())
@@ -394,4 +407,20 @@ def cpp_info_name_cmake_find_package_test(self):
         self.assertNotIn("MY_PKG", content["FindMyPkG2.cmake"])
         self.assertIn("add_library(MyPkG::MyPkG INTERFACE IMPORTED)", content["FindMyPkG.cmake"])
         self.assertIn("add_library(MyPkG2::MyPkG2 INTERFACE IMPORTED)", content["FindMyPkG2.cmake"])
+        self.assertIn("find_dependency(MyPkG REQUIRED)", content["FindMyPkG2.cmake"])
 
+    def cmake_find_package_multi_test(self):
+        generator = CMakeFindPackageMultiGenerator(self.conanfile)
+        content = generator.content
+        six.assertCountEqual(self, ['MyPkG2Targets.cmake', 'MyPkGConfig.cmake', 'MyPkG2Config.cmake',
+                                    'MyPkGTargets.cmake', 'MyPkGTarget-debug.cmake',
+                                    'MyPkG2Target-debug.cmake'], content.keys())
+        self.assertNotIn("my_pkg", content["MyPkGConfig.cmake"])
+        self.assertNotIn("MY_PKG", content["MyPkGConfig.cmake"])
+        self.assertNotIn("my_pkg", content["MyPkG2Config.cmake"])
+        self.assertNotIn("MY_PKG", content["MyPkG2Config.cmake"])
+        self.assertIn("add_library(MyPkG::MyPkG INTERFACE IMPORTED)",
+                      content["MyPkGTargets.cmake"])
+        self.assertIn("add_library(MyPkG2::MyPkG2 INTERFACE IMPORTED)",
+                      content["MyPkG2Targets.cmake"])
+        self.assertIn("find_dependency(MyPkG REQUIRED NO_MODULE)", content["MyPkG2Config.cmake"])