Repository: conan-io/conan

Issue:
[bug] CMake compontent 'filename' produces error in generated find.cmake and causes conflicts when consumer packages
Earlier this week I upgrade our CI from Conan client 1.27.1 to 1.28.1 after our CI broke on new 1.28 features that caught me off guard.

It's the first time we are consuming the upgrades from #7320 and #7447 en mass

There was a PR merged https://github.com/conan-io/conan-center-index/pull/2545 that is a transitive dependency of mine. 

```
my_project
|___restinio
|    |___expected-lite
|    |___string-view-lite // this is called second and it's not being picked up in my INC_DIRS
|    |___etc
|___etc
```

> *So unfortunately we did not have it pinned down by RREV... now I'm in 💩 with my boss, since this is twice in a week, send an  🚑 please. The price of progress.*

Doing a lot of digging this morning... the following is not correct.

https://github.com/conan-io/conan/blob/3658bb16d49cb85ae44cb67e76fb45b37b8986ba/conans/client/generators/cmake_find_package.py#L24-L28

According to the CMake docs [here](https://cmake.org/cmake/help/latest/module/FindPackageHandleStandardArgs.html?highlight=FindPackageHandleStandardArgs)

> This module provides a function intended to be used in Find Modules implementing find_package(\<PackageName\>) calls. 

> find_package_handle_standard_args(\<PackageName\>

Currently because the incorrect values are passed in the generator it seems I am having a collision between two packages which are a valid combination when consumed through the upstream CMake installed files. Thusly the only issue is missing files which are on disk.

It seems there is some missing tests about this corner case, two different package names should be consumable.

### Environment Details (include every applicable attribute)
  * Operating System+version:  Windows 10 / Centos 7 
  * Compiler+version: MSVC 2017 and 2019 /  GCC 7
  * Conan version: 1.28.1
  * Python version: 3.8 / 3.6

### Steps to reproduce (Include if Applicable)
- `conan install restinio/0.6.8.1`
- CMakeLists.txt: `find_package(restinio REQUIRED)`

### Logs (Executed commands with output) (Include/Attach if Applicable)

- CMake configure/generate command
```
    -- Conan: Using autogenerated Findexpected-lite.cmake
    CMake Warning (dev) at /usr/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:272 (message):
      The package name passed to `find_package_handle_standard_args` (nonstd)
      does not match the name of the calling package (expected-lite).  This can
      lead to problems in calling code that expects `find_package` result
      variables (e.g., `_FOUND`) to follow a certain pattern.
    Call Stack (most recent call first):
      build/Findexpected-lite.cmake:81 (find_package_handle_standard_args)
      /usr/share/cmake-3.17/Modules/CMakeFindDependencyMacro.cmake:47 (find_package)
      build/Findrestinio.cmake:195 (find_dependency)
      CMakeLists.txt:18 (find_package)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Found nonstd: 0.4.0 (found version "0.4.0") 
    -- Conan: Using autogenerated Findoptional-lite.cmake
    -- Found optional-lite: 3.2.0 (found version "3.2.0") 
    -- Conan: Using autogenerated Findstring-view-lite.cmake
    CMake Warning (dev) at /usr/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:272 (message):
      The package name passed to `find_package_handle_standard_args` (nonstd)
      does not match the name of the calling package (string-view-lite).  This
      can lead to problems in calling code that expects `find_package` result
      variables (e.g., `_FOUND`) to follow a certain pattern.
    Call Stack (most recent call first):
      build/Findstring-view-lite.cmake:81 (find_package_handle_standard_args)
      /usr/share/cmake-3.17/Modules/CMakeFindDependencyMacro.cmake:47 (find_package)
      build/Findrestinio.cmake:209 (find_dependency)
      CMakeLists.txt:18 (find_package)
    This warning is for project developers.  Use -Wno-dev to suppress it.
```

- build command
```
.h:32:10: fatal error: nonstd/string_view.hpp: No such file or directory
     #include <nonstd/string_view.hpp>

              ^~~~~~~~~~~~~~~~~~~~~~~~
```


Discussion:
Not to be rude, but because I am invested in Conan's success in an enterprise setting... @memsharded @danimtb if you can please take a look at this issue I just opened, that would be amazing.
So, AFAIK, the CMake code you posted above should be:

```
find_package_handle_standard_args({filename} REQUIRED_VARS 
                                  {name}_VERSION VERSION_VAR {name}_VERSION) 
```

right?
Yes that's exactly what I would expect!
Even the version variable should be `filename` for it to be unique
yeah, taking a look at the CMake documentation I see what is happening there. It might have been an oversight from our side due to the different discussions around `cpp_info.filename`. We'll fix it as a minor or in the next release.

As a general recommendation, you should not rely on ConanCenter updates in production, or in case you do so, stick to a specific recipe revision to avoid breaking with new PRs introducing changes in ConanCenter.

Anyway, thanks a lot for the report and for taking the time to investigate the issue 👍 
> yeah, taking a look at the CMake documentation I see what is happening there. It might have been an oversight from our side due to the different discussions around cpp_info.filename. We'll fix it as a minor or in the next release.

:100: It's very confusing which is which. That's perfect, once it's released I will upgrade our CI (hopefully soon).

> As a general recommendation, you should not rely on ConanCenter updates in production, or in case you do so, stick to a specific recipe revision to avoid breaking with new PRs introducing changes in ConanCenter.

That's been a rule since we started using Conan however, along the lines of https://github.com/conan-io/conan-center-index/issues/2566, how do I do take into account new dependencies? 

One of the advantages of Conan was that I did not worry about the tree, just naming my direct dependencies, but more and more I need to add all of them (which is still produced by Conan but its cumbersome) but worse _know_ all of them as well. It's a heavy time cost, reviewing all the PRs trying to determine which ones impact us, as you know, it time consuming.

I would like to say "I depend on openssl" as opposed to "I depend on openssl and all of it's requirements".

Secondly I can not `install --update` some packages. Currently it's impossible for me to bump the cache entries of my `conanfile.txt` without absorbing all the update within the tree.

I will certainly change our policy this afternoon, **all** dependencies must be RREV'd in a conanfile.txt which will avoid any future problems.  smooth :boat: :smile: 

> Anyway, thanks a lot for the report and for taking the time to investigate the issue :+1:

Always a pleasure!

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
@@ -22,11 +22,11 @@ class CMakeFindPackageGenerator(Generator):
         conan_message(STATUS "Conan: Using autogenerated Find{filename}.cmake")
         # Global approach
         set({filename}_FOUND 1)
-        set({name}_VERSION "{version}")
+        set({filename}_VERSION "{version}")
 
-        find_package_handle_standard_args({name} REQUIRED_VARS
-                                          {name}_VERSION VERSION_VAR {name}_VERSION)
-        mark_as_advanced({filename}_FOUND {name}_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")
@@ -62,12 +62,13 @@ class CMakeFindPackageGenerator(Generator):
 
         conan_message(STATUS "Conan: Using autogenerated Find{{ pkg_filename }}.cmake")
         set({{ pkg_filename }}_FOUND 1)
-        set({{ pkg_name }}_VERSION "{{ pkg_version }}")
-        set({{ pkg_name }}_COMPONENTS {{ pkg_components }})
+        set({{ pkg_filename }}_VERSION "{{ pkg_version }}")
 
-        find_package_handle_standard_args({{ pkg_name }} REQUIRED_VARS
-                                          {{ pkg_name }}_VERSION VERSION_VAR {{ pkg_name }}_VERSION)
-        mark_as_advanced({{ pkg_filename }}_FOUND {{ pkg_name }}_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_name }}_FIND_COMPONENTS)
             foreach(_FIND_COMPONENT {{ '${'+pkg_name+'_FIND_COMPONENTS}' }})


Test patch:
diff --git a/conans/test/functional/generators/cmake_components_test.py b/conans/test/functional/generators/cmake_components_test.py
--- a/conans/test/functional/generators/cmake_components_test.py
+++ b/conans/test/functional/generators/cmake_components_test.py
@@ -644,88 +644,122 @@ def component_not_found_same_name_as_pkg_require_test(self):
 
     def filenames_test(self):
         client = TestClient()
-        conanfile = textwrap.dedent("""
+        conanfile_tpl = textwrap.dedent("""
             import os
-            from conans import ConanFile, tools
+            from conans import ConanFile, tools, CMake
 
-            class HelloConan(ConanFile):
-                name = "hello"
+            class {name}(ConanFile):
+                name = "{name}"
                 version = "1.0"
                 settings = "os", "compiler", "build_type", "arch"
+                generators = "cmake"
+                exports_sources = "src/*"
+                {requires}
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure(source_folder="src")
+                    cmake.build()
 
                 def package(self):
-                    tools.save(os.path.join(self.package_folder, "lib", "hello.lib"), "")
-                    tools.save(os.path.join(self.package_folder, "lib", "libhello.a"), "")
+                    self.copy("*.h", dst="include", src="src")
+                    self.copy("*.lib", dst="lib", keep_path=False)
+                    self.copy("*.a", dst="lib", keep_path=False)
 
                 def package_info(self):
                     self.cpp_info.names["cmake_find_package"] = "MYHELLO"
-                    self.cpp_info.filenames["cmake_find_package"] = "hello_1"
-                    self.cpp_info.components["1"].names["cmake_find_package"] = "HELLO1"
-                    self.cpp_info.components["1"].libs = ["hello"]
+                    self.cpp_info.filenames["cmake_find_package"] = "{name}"
+                    self.cpp_info.components["1"].names["cmake_find_package"] = "{name}_TARGET"
+                    self.cpp_info.components["1"].libs = ["{name}"]
+                    if self.name == "hello2":
+                        self.cpp_info.components["1"].requires = ["hello1::1"]
         """)
-        client.save({"conanfile.py": conanfile})
-        client.run("create .")
+        hello_h_tpl = textwrap.dedent("""
+            #pragma once
+            #include <string>
 
-        conanfile = textwrap.dedent("""
-            import os
-            from conans import ConanFile, tools
+            void {name}(std::string noun);
+            """)
 
-            class HelloConan(ConanFile):
-                name = "hello2"
-                version = "1.0"
-                settings = "os", "compiler", "build_type", "arch"
-                requires = "hello/1.0"
+        hello_cpp_tpl = textwrap.dedent("""
+            #include <iostream>
+            #include <string>
 
-                def package(self):
-                    tools.save(os.path.join(self.package_folder, "lib", "hello2.lib"), "")
-                    tools.save(os.path.join(self.package_folder, "lib", "libhello2.a"), "")
+            #include "{name}.h"
 
-                def package_info(self):
-                    self.cpp_info.names["cmake_find_package"] = "MYHELLO"
-                    self.cpp_info.filenames["cmake_find_package"] = "hello_2"
-                    self.cpp_info.components["1"].names["cmake_find_package"] = "HELLO2"
-                    self.cpp_info.components["1"].libs = ["hello2"]
-                    self.cpp_info.components["1"].requires = ["hello::1"]
-        """)
-        client.save({"conanfile.py": conanfile})
+            void {name}(std::string noun) {{
+                std::cout << "{name} " << noun << "!" << std::endl;
+            }}
+            """)
+        hello_cmakelists_tpl = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.0)
+            project({name} CXX)
+
+            include(${{CMAKE_BINARY_DIR}}/conanbuildinfo.cmake)
+            conan_basic_setup()
+
+            add_library({name} {name}.cpp)
+            """)
+        client.save({"conanfile.py": conanfile_tpl.format(name="hello1", requires=""),
+                     "src/CMakeLists.txt": hello_cmakelists_tpl.format(name="hello1"),
+                     "src/hello1.h": hello_h_tpl.format(name="hello1"),
+                     "src/hello1.cpp": hello_cpp_tpl.format(name="hello1")})
+        client.run("create .")
+
+        client.save({"conanfile.py": conanfile_tpl.format(name="hello2",
+                                                          requires="requires = 'hello1/1.0'"),
+                     "src/CMakeLists.txt": hello_cmakelists_tpl.format(name="hello2"),
+                     "src/hello2.h": hello_h_tpl.format(name="hello2"),
+                     "src/hello2.cpp": hello_cpp_tpl.format(name="hello2")}, clean_first=True)
         client.run("create .")
 
         conanfile = textwrap.dedent("""
+            import os
             from conans import ConanFile, CMake
 
             class Conan(ConanFile):
+                name = "consumer"
+                version = "1.0"
                 requires = "hello2/1.0"
-                generators = "cmake_find_package"
+                generators = "cmake_find_package", "cmake"
                 settings = "os", "compiler", "build_type", "arch"
+                exports_sources = "src/*"
 
                 def build(self):
                     cmake = CMake(self)
-                    cmake.configure()
+                    cmake.configure(source_folder="src")
+                    cmake.build()
+                    bin_path = os.path.join("bin", "main")
+                    self.run(bin_path, run_environment=True)
             """)
         cmakelists = textwrap.dedent("""
             project(consumer)
             cmake_minimum_required(VERSION 3.1)
-            find_package(hello_2)
-            get_target_property(tmp MYHELLO::HELLO2 INTERFACE_LINK_LIBRARIES)
-            message("Target libs (hello2): ${tmp}")
-            get_target_property(tmp MYHELLO::HELLO1 INTERFACE_LINK_LIBRARIES)
-            message("Target libs (hello): ${tmp}")
-            """)
-        client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists})
-        client.run("install .")
-        client.run("build .")
 
+            include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+            conan_basic_setup()
+
+            find_package(hello2)
+
+            add_executable(main main.cpp)
+            target_link_libraries(main MYHELLO::hello1_TARGET MYHELLO::hello2_TARGET)
+            """)
+        main_cpp = textwrap.dedent("""
+        #include "hello1.h"
+        #include "hello2.h"
+        
+        int main() {
+            hello1("world");
+            hello2("world");
+        }
+        """)
+        client.save({"conanfile.py": conanfile,
+                     "src/CMakeLists.txt": cmakelists,
+                     "src/main.cpp": main_cpp}, clean_first=True)
+        client.run("create .")
+        self.assertIn('Found hello1: 1.0 (found version "1.0")', client.out)
+        self.assertIn('Found hello2: 1.0 (found version "1.0")', client.out)
         self.assertIn('Library hello2 found', client.out)
-        self.assertIn('Library hello found', client.out)
-        self.assertIn("Target libs (hello2): "
-                      "CONAN_LIB::MYHELLO_HELLO2_hello2;MYHELLO::HELLO1;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>",
-                      client.out)
-        self.assertIn("Target libs (hello): "
-                      "CONAN_LIB::MYHELLO_HELLO1_hello;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;"
-                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>",
-                      client.out)
+        self.assertIn('Library hello1 found', client.out)
+        self.assertIn('hello1 world!', client.out)
+        self.assertIn('hello2 world!', 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
@@ -566,8 +566,8 @@ def build(self):
         print(client.out)
         print('~' * 120)
 
-        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('Found hello_2: 1.0 (found version "1.0")', client.out)
+        self.assertIn('Found hello_1: 1.0 (found version "1.0")', client.out)
         self.assertIn("Target libs (hello2): "
                       "CONAN_LIB::MYHELLO2_HELLO2_hello2;MYHELLO::HELLO1;"
                       "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"