Repository: conan-io/conan

Issue:
[feature] Add executables to cpp_info model
Coming from https://github.com/conan-io/conan-center-index/pull/1717#discussion_r441501353
Related to #5090

In order to allow a better integration with executables, cpp_info could model those with an extra field similar to the current `cpp_info.libs`. Something similar to the proposal at #5090 with `cpp_info.exes = []` that will allow adding `<NAME>_EXECUTABLE` being `<NAME>` the name of the component or similar

cc/ @madebr

[bug] check_c_source_compiles for openssl is not working with CMakeToolChain and Visual Studio generator
### Environment Details (include every applicable attribute)
  * Operating System+version: Windows 11
  * Compiler+version: Visual Studio 2019
  * Conan version: 1.51.3
  * Python version: 3.10.3

### Steps to reproduce (Include if Applicable)
- in the conanfile:
  - use CMakeToolChain to build the package
  - require openssl `self.requires("openssl/1.1.1q")`
- in the cmakefile of the project:
  -  link with openssl like `LINK_LIBRARIES(OpenSSL::SSL OpenSSL::Crypto)`
  - use check_c_source_compiles like
```
CHECK_C_SOURCE_COMPILES("#include <openssl/opensslv.h>
			#ifndef OPENSSL_VERSION_NUMBER
			#error No OPENSSL_VERSION_NUMBER defined
			#endif
			#if OPENSSL_VERSION_NUMBER < 0x10100000L
			#error This is not OpenSSL 1.1 or higher
			#endif
			int main(void) { return 0; }" PODOFO_HAVE_OPENSSL_1_1)
```

=> you get the following error:
```
C:/J/w/prod/BuildSingleReference/.conan/data/podofo/0.9.7/_/_/build/f8220457d46bfa1f3246ae8e28788767027bcd82/build/CMakeFiles/CMakeTmp/CMakeLists.txt:20 (add_executable):
  Target "cmTC_491e9" links to target
  "CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE" but the target was not
  found.  Perhaps a find_package() call is missing for an IMPORTED target, or
  an ALIAS target is missing?
```

Note: the error does not appear if you use another generator like Ninja.

This error was found when working on this pull request: https://github.com/conan-io/conan-center-index/pull/12615
[bug] CMakeDeps: `<name>_LIBRARIES` variable is not suitable for macros like `check_symbol_exists`
<!--
  Please don't forget to update the issue title.
  Include all applicable information to help us reproduce your problem.

  To help us debug your issue please explain:
-->

### Environment Details (include every applicable attribute)
  * Operating System+version: macOS Monterey
  * Compiler+version: AppleClang 14
  * Conan version: 1.52.0
  * Python version: 3.10.6
  * cmake version: 3.24.2

### Steps to reproduce (Include if Applicable)

CMakeLists.txt

```cmake
cmake_minimum_required(VERSION 3.15)
project(test_check_symbol_exists LANGUAGES C)

find_package(zstd REQUIRED)

include(CheckSymbolExists)
set(CMAKE_REQUIRED_INCLUDES_SAVE ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
list(PREPEND CMAKE_REQUIRED_INCLUDES ${zstd_INCLUDE_DIRS})
list(PREPEND CMAKE_REQUIRED_LIBRARIES ${zstd_LIBRARIES})
check_symbol_exists(ZSTD_decompressStream "zstd.h" ZSTD_RECENT_ENOUGH)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE})

if(ZSTD_RECENT_ENOUGH)
    message(STATUS "Test succeeded")
else()
    message(FATAL_ERROR "Test failed")
endif()
```

test succeeds with `cmake_find_package`:

```shell
mkdir build1 && cd build1
conan install zstd/1.5.2@ -g CMakeToolchain -g cmake_find_package -c tools.cmake.cmaketoolchain:find_package_prefer_config="OFF"
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
```

test fails with `CMakeDeps`:

```shell
mkdir build2 && cd build2
conan install zstd/1.5.2@ -g CMakeToolchain -g CMakeDeps
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
```

`CMAKE_REQUIRED_INCLUDES` works fine here, but not `CMAKE_REQUIRED_LIBRARIES`, because `zstd_LIBRARIES` is  set to zstd imported target instead of full paths of all libraries.
According to CMake documentation, `check_c_source_compiles` allows imported targets in `CMAKE_REQUIRED_LIBRARIES`, but they don't say anything for `check_symbol_exists`.

It's quite annoying for conan v2 migration of several CCI recipes.

### Logs (Executed commands with output) (Include/Attach if Applicable)

`CMakeError.log` of `CMakeDeps` test:

```
Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
Build flags: ;;;;-m64
Id flags:

The output was:
1
ld: library not found for -lSystem
clang: error: linker command failed with exit code 1 (use -v to see invocation)


Determining if the ZSTD_decompressStream exist failed with the following output:
Change Dir: /Users/spaceim/Documents/Personnel/test_check_symbol/build2/CMakeFiles/CMakeTmp

Run Build Command(s):/usr/bin/make -f Makefile cmTC_ed876/fast && /Applications/Xcode.app/Contents/Developer/usr/bin/make  -f CMakeFiles/cmTC_ed876.dir/build.make CMakeFiles/cmTC_ed876.dir/build
Building C object CMakeFiles/cmTC_ed876.dir/CheckSymbolExists.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc  -I/Users/spaceim/.conan/data/zstd/1.5.2/_/_/package/258f9d253d0e975fcb3ab38da19bbea0bc9bf506/include -m64  -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -MD -MT CMakeFiles/cmTC_ed876.dir/CheckSymbolExists.c.o -MF CMakeFiles/cmTC_ed876.dir/CheckSymbolExists.c.o.d -o CMakeFiles/cmTC_ed876.dir/CheckSymbolExists.c.o -c /Users/spaceim/Documents/Personnel/test_check_symbol/build2/CMakeFiles/CMakeTmp/CheckSymbolExists.c
Linking C executable cmTC_ed876
/Applications/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/cmTC_ed876.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -m64  -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names -m64  CMakeFiles/cmTC_ed876.dir/CheckSymbolExists.c.o -o cmTC_ed876
Undefined symbols for architecture x86_64:
  "_ZSTD_decompressStream", referenced from:
      _main in CheckSymbolExists.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [cmTC_ed876] Error 1
make: *** [cmTC_ed876/fast] Error 2


File /Users/spaceim/Documents/Personnel/test_check_symbol/build2/CMakeFiles/CMakeTmp/CheckSymbolExists.c:
/* */
#include <zstd.h>

int main(int argc, char** argv)
{
  (void)argv;
#ifndef ZSTD_decompressStream
  return ((int*)(&ZSTD_decompressStream))[argc];
#else
  (void)argc;
  return 0;
#endif
}
```
[bug] conan 2.x: linking against a shared lib with private shared dependencies fails on Linux (again)
### Environment details

* Operating System+version: Ubuntu 22.04
* Compiler+version: gcc 12.1.0
* Conan version: 2.0.2
* Python version: 3.10.6


### Steps to reproduce

`conan install --requires="libzippp/6.0-1.9.2" -o "*:shared=True" -b missing`

### Logs

<details><summary>build log</summary>

```
libzippp/6.0-1.9.2: Building from source
libzippp/6.0-1.9.2: Package libzippp/6.0-1.9.2:ee3488ab65102991abf5b636e39de538d8d3e7ab
libzippp/6.0-1.9.2: Copying sources to build folder
libzippp/6.0-1.9.2: Building your package in /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b
libzippp/6.0-1.9.2: Calling generate()
libzippp/6.0-1.9.2: Generators folder: /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release/generators
libzippp/6.0-1.9.2: CMakeToolchain generated: conan_toolchain.cmake
libzippp/6.0-1.9.2: CMakeToolchain generated: CMakePresets.json
libzippp/6.0-1.9.2: CMakeToolchain generated: ../../../src/CMakeUserPresets.json
libzippp/6.0-1.9.2: Generating aggregated env files
libzippp/6.0-1.9.2: Generated aggregated env files: ['conanbuild.sh', 'conanrun.sh']
libzippp/6.0-1.9.2: Calling build()
libzippp/6.0-1.9.2: Running CMake.configure()
libzippp/6.0-1.9.2: RUN: cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release/generators/conan_toolchain.cmake" -DCMAKE_INSTALL_PREFIX="/home/spaceim/.conan2/p/t/libzic30b1ebec828d/p" -DCMAKE_POLICY_DEFAULT_CMP0091="NEW" -DCMAKE_BUILD_TYPE="Release" "/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src"
-- Using Conan toolchain: /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release/generators/conan_toolchain.cmake
-- Conan toolchain: Setting BUILD_SHARED_LIBS = ON
-- The C compiler identification is GNU 12.1.0
-- The CXX compiler identification is GNU 12.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc-12 - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++-12 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Component target declared 'libzip::zip'
-- Conan: Target declared 'ZLIB::ZLIB'
-- Conan: Target declared 'BZip2::BZip2'
-- Conan: Including build module from '/home/spaceim/.conan2/p/bzip2b4101dd1d9e37/p/lib/cmake/conan-official-bzip2-variables.cmake'
-- Conan: Target declared 'LibLZMA::LibLZMA'
-- Conan: Including build module from '/home/spaceim/.conan2/p/xz_utae9210766e49b/p/lib/cmake/conan-official-xz_utils-variables.cmake'
-- Conan: Component target declared 'zstd::libzstd_shared'
-- Conan: Component target declared 'OpenSSL::Crypto'
-- Conan: Component target declared 'OpenSSL::SSL'
-- Conan: Target declared 'openssl::openssl'
-- Conan: Including build module from '/home/spaceim/.conan2/p/opens3b56123e737a3/p/lib/cmake/conan-official-openssl-variables.cmake'
-- Configuring done (5.2s)
-- Generating done (0.0s)
-- Build files have been written to: /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release

libzippp/6.0-1.9.2: Running CMake.build()
libzippp/6.0-1.9.2: RUN: cmake --build "/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release" -- -j8
[1/4] Building CXX object CMakeFiles/libzippp.dir/src/libzippp.cpp.o
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp: In function ‘void defaultErrorHandler(const std::string&, const std::string&, int, int)’:
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp:127:37: warning: unused parameter ‘zip_error_code’ [-Wunused-parameter]
  127 |                                 int zip_error_code,
      |                                 ~~~~^~~~~~~~~~~~~~
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp:128:37: warning: unused parameter ‘system_error_code’ [-Wunused-parameter]
  128 |                                 int system_error_code)
      |                                 ~~~~^~~~~~~~~~~~~~~~~
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp: In function ‘void progress_callback(zip*, double, void*)’:
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp:350:29: warning: unused parameter ‘archive’ [-Wunused-parameter]
  350 | void progress_callback(zip* archive, double progression, void* ud) {
      |                        ~~~~~^~~~~~~
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp: In function ‘int progress_cancel_callback(zip*, void*)’:
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/src/libzippp.cpp:359:35: warning: unused parameter ‘archive’ [-Wunused-parameter]
  359 | int progress_cancel_callback(zip *archive, void *ud) {
      |                              ~~~~~^~~~~~~
[3/4] Building CXX object CMakeFiles/libzippp_test.dir/tests/tests.cpp.o
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp: In function ‘void test21()’:
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp:678:45: warning: the address of ‘int fflush(FILE*)’ will never be NULL [-Waddress]
  678 |     cout << "Running test 21..." << endl << fflush;
      |                                             ^~~~~~
In file included from /usr/include/c++/12/cstdio:42,
                 from /usr/include/c++/12/ext/string_conversions.h:43,
                 from /usr/include/c++/12/bits/basic_string.h:3960,
                 from /usr/include/c++/12/string:53,
                 from /usr/include/c++/12/bits/locale_classes.h:40,
                 from /usr/include/c++/12/bits/ios_base.h:41,
                 from /usr/include/c++/12/ios:42,
                 from /usr/include/c++/12/ostream:38,
                 from /usr/include/c++/12/iostream:39,
                 from /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp:38:
/usr/include/stdio.h:230:12: note: ‘int fflush(FILE*)’ declared here
  230 | extern int fflush (FILE *__stream);
      |            ^~~~~~
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp: In function ‘int main(int, char**)’:
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp:895:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
  895 | int main(int argc, char** argv) {
      |          ~~~~^~~~
/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/src/tests/tests.cpp:895:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
  895 | int main(int argc, char** argv) {
      |                    ~~~~~~~^~~~
[4/4] Linking CXX executable libzippp_shared_test
FAILED: libzippp_shared_test
: && /usr/bin/g++-12 -W -Wall -Wextra -ansi -pedantic -std=c++11 -O3 -m64 CMakeFiles/libzippp_test.dir/tests/tests.cpp.o -o libzippp_shared_test  -Wl,-rpath,/home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release  libzippp.so && :
/usr/bin/ld: warning: libcrypto.so.1.1, needed by /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_aes_128_ecb@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `PKCS5_PBKDF2_HMAC_SHA1@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `HMAC_CTX_new@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_sha1@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `HMAC_Final@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_aes_192_ecb@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `HMAC_Init_ex@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_EncryptUpdate@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `HMAC_CTX_free@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_CIPHER_CTX_new@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_EncryptInit_ex@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_aes_256_ecb@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `EVP_CIPHER_CTX_free@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `RAND_bytes@OPENSSL_1_1_0'
/usr/bin/ld: /home/spaceim/.conan2/p/libzi1690beeedfbba/p/lib/libzip.so.5: undefined reference to `HMAC_Update@OPENSSL_1_1_0'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

libzippp/6.0-1.9.2: ERROR:
Package 'ee3488ab65102991abf5b636e39de538d8d3e7ab' build failed
libzippp/6.0-1.9.2: WARN: Build folder /home/spaceim/.conan2/p/t/libzic30b1ebec828d/b/build/Release
*********************************************************
Recipe 'libzippp/6.0-1.9.2' cannot build its binary
It is possible that this recipe is not Conan 2.0 ready
If the recipe comes from ConanCenter check: https://conan.io/cci-v2.html
If it is your recipe, check if it is updated to 2.0
*********************************************************

ERROR: libzippp/6.0-1.9.2: Error in build() method, line 88
        cmake.build()
        ConanException: Error 1 while executing
```

</details>

related to https://github.com/conan-io/conan/issues/13000

If you dig into libzippp recipe, recipe of its dependency libzip, their upstream CMakeLists and how they are patched, you'll see that libzippp properly links to `libzip::zip` target defined in libzip recipe, and that `openssl::crypto` conan component of openssl recipe is properly appended to `requires` of this `libzip::_libzip` conan component in `package_info()` of libzip. Still, openssl crypto is missing in `-rpath-link` when linker tries to create libzippp shared lib.
[bug] conan_package_library_targets does not set IMPORTED_CONFIGURATIONS
### Environment details

* Operating System+version: macOS
* Conan version: 1.60
* Python version: 3.11

### Steps to reproduce

Install TBB with Conan and observe `cmakedeps_macros.cmake` file. It contains 
```cmake
function(conan_package_library_targets libraries package_libdir deps_target out_libraries_target config_suffix package_name)
    set(_out_libraries_target "")

    foreach(_LIBRARY_NAME ${libraries})
        find_library(CONAN_FOUND_LIBRARY NAMES ${_LIBRARY_NAME} PATHS ${package_libdir}
                     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
        if(CONAN_FOUND_LIBRARY)
            message(VERBOSE "Conan: Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")

            # Create a micro-target for each lib/a found
            # Allow only some characters for the target name
            string(REGEX REPLACE "[^A-Za-z0-9.+_-]" "_" _LIBRARY_NAME ${_LIBRARY_NAME})
            set(_LIB_NAME CONAN_LIB::${package_name}_${_LIBRARY_NAME}${config_suffix})
            if(NOT TARGET ${_LIB_NAME})
                # Create a micro-target for each lib/a found
                add_library(${_LIB_NAME} UNKNOWN IMPORTED)
            endif()
            # Link library file
            set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION${config_suffix} ${CONAN_FOUND_LIBRARY})
            list(APPEND _out_libraries_target ${_LIB_NAME})
            message(VERBOSE "Conan: Found: ${CONAN_FOUND_LIBRARY}")
        else()
            message(FATAL_ERROR "Library '${_LIBRARY_NAME}' not found in package. If '${_LIBRARY_NAME}' is a system library, declare it with 'cpp_info.system_libs' property")
        endif()
        unset(CONAN_FOUND_LIBRARY CACHE)
    endforeach()

    # Add the dependencies target for all the imported libraries
    foreach(_T ${_out_libraries_target})
        set_property(TARGET ${_T} PROPERTY INTERFACE_LINK_LIBRARIES ${deps_target} APPEND)
    endforeach()

    set(${out_libraries_target} ${_out_libraries_target} PARENT_SCOPE)
endfunction()
```
Which sets `IMPORTED_LOCATION_<config>`, but does not set `IMPORTED_CONFIGURATIONS`. 

As a I users, sometimes I need an access to library location. So, I have to understand imported configurations and then take appropriate `IMPORTED_LOCATION_<config>`, but Conan does not do it.

It's a good practice to set this property (done by cmake automatically)

### Logs

_No response_
[feature] CMakeDeps: define `IMPORTED_LINK_INTERFACE_LANGUAGES` in case of static C++ lib
### What is your suggestion?

Config files generated by `CMakeDeps` have several flaws compared to regular CMake config files generated by CMake.
One of them is that they miss `IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"` property in case of C++ static lib (see also this summary I made in https://github.com/conan-io/conan/issues/13560#issuecomment-1545947074).

When this property is missing, linking a static C++ lib with C API into a pure C executable or shared lib can't work out of the box -while it should with a proper CMake config file (information comes transitively from imported target linked into C executable or shared lib)- because CMake doesn't know that it should use C++ linker.

Currently, package_info() doesn't provide a way to specify which lib in a recipe is a C++ lib, nor if it's static or not (though for this one there is the global shared option, or package_type value eventually but it's not sufficient when there are components which might not be all shared or static), so it's a little bit hard to implement such feature without some improvements in package_info() and an abstraction allowing to specify if a component refers to a C or C++ lib.

### Have you read the CONTRIBUTING guide?

- [x] I've read the CONTRIBUTING guide
[bug] Conan setting `CMAKE_FIND_ROOT_PATH_MODE_*=BOTH` fundamentally breaks cross-compilation
### Describe the bug

When cross-compiling, it is essential that the _build_ system and the _host_ system are strictly separated. In CMake, this can be ensured by setting `CMAKE_FIND_ROOT_PATH_MODE_{LIBRARY,INCLUDE,PACKAGE}=ONLY`, which tells the corresponding `find_*` command to only look for libraries, headers and packages in the _host_ system's sysroot or in the `CMAKE_FIND_ROOT_PATH`.

However, when `tools.build.cross_building:cross_build=true`, Conan **silently** (!) sets these variables to `BOTH`, and in doing so it allows CMake to look for libraries, headers and packages in the _build_ system's root filesystem as well. As a result, packages cross-compiled using Conan can silently link to wrong versions of libraries it found in `/usr/lib`, headers of different versions than intended, etc.  
In the best case, this results in linker errors because of incompatible architectures, in the worst case, the resulting binaries are subtly broken because they depend on libraries (or versioned symbols in those libraries) that are unavailable on the _host_ system.

If a user explicitly sets `CMAKE_FIND_ROOT_PATH_MODE_{LIBRARY,INCLUDE,PACKAGE}=ONLY` in their toolchain file, it is often for good reasons, and IMHO silently changing those values inside of Conan's toolchain file is not an acceptable solution.  
I can help with a PR, but wanted to discuss here first. In the meantime, I'd suggest adding a very clear warning to Conan's toolchain file if it detects that the user set these variables to `ONLY`. (It will still be broken, but at least then the people know that it's broken.)

Here are some previous discussions on the same topic:
- https://github.com/conan-io/conan/issues/10513 Another user bitten by this bug (unresolved).
- https://github.com/conan-io/conan/issues/9427#issuecomment-995642284 Discussion that seemingly lead to the following commit:
- https://github.com/conan-io/conan/commit/861170cdf2959942828f6db33c488c1b823522c2#diff-a9d80c0c1c5562fe43298a71c13ddd118d2c6f346c029c7d6ddfe7281761b108R444

Addressing some of the comments there:

> <sup>https://github.com/conan-io/conan/issues/10513</sup>
> I see the problems with using CMAKE_FIND_ROOT_PATH, though - conan doesn't really want to re-root everybody else's path's either.

I don't believe that this is a problem. Re-rooting all paths is exactly what you want when cross-compiling. If a user wants to search the _build_ system's paths as well, they should not set `CMAKE_FIND_ROOT_PATH_MODE_*=ONLY` in the first place. But that's for the user to decide, Conan should not silently change this.

> <sup>https://github.com/conan-io/conan/issues/9427#issuecomment-995642284</sup>
> Here is the problem, let's take `CMAKE_FIND_ROOT_PATH_MODE_INCLUDE` set to `ONLY` as an example: `find_file()` doesn't look into `CMAKE_INCLUDE_PATH` (or `CMAKE_PREFIX_PATH`) in this case, it iterates in paths of `CMAKE_FIND_ROOT_PATH`, but not the paths themselves, only `<path>/include`. 

Exactly, that's what you want when cross-compiling.

> What does it mean? It means that you must add the root package folder to `CMAKE_FIND_ROOT_PATH`. But by doing this you may also make tools (in `<path>/bin`) of host context discoverable, and they may be found by `find_program()` before executables of build context.

Not if you set `CMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER`, which is the common use case when cross-compiling.

> If you think a little bit about this, you'll see that you have no other choice than populating `CMAKE_FIND_ROOT_PATH` with root package folders of requirements AND build requirements. 

No, this is not the correct conclusion. They _should_ stay separate, and `CMAKE_FIND_ROOT_PATH` and `CMAKE_FIND_ROOT_PATH_MODE_*` are exactly the tools that CMake provides to allow you to keep them separate.

> Actually `CMAKE_FIND_ROOT_PATH_MODE_PROGRAM` set to `ONLY` even breaks the discovery of Ninja.

Which is why you usually don't see people setting `CMAKE_FIND_ROOT_PATH_MODE_PROGRAM=ONLY` when cross-compiling :)

---

### How to reproduce it

Tested on Linux, you can find a reproducible version with Docker here:
Script: https://github.com/tttapa/conan-find-mode-bug/blob/main/.github/workflows/test.yml  
Output: https://github.com/tttapa/conan-find-mode-bug/actions/runs/9197591352/job/25298402017

**conanfile.txt**
```text
[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
```

**toolchain.cmake**
```cmake
# System information
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "x86_64")

# Search path configuration
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# These are the only places where CMake is allowed to look for libraries etc.
set(CMAKE_FIND_ROOT_PATH ${CMAKE_CURRENT_LIST_DIR}/find_root)
set(CMAKE_SYSROOT ${CMAKE_CURRENT_LIST_DIR}/sysroot)
```

**CMakeLists.txt**
```cmake
cmake_minimum_required(VERSION 3.20)
project(conan_find_mode)

set(CMAKE_FIND_DEBUG_MODE On)
# libreadline.so is in /usr/lib/x86_64-linux-gnu on the build system (not in the sysroot)
find_library(LIBREADLINE "libreadline.so")
if (LIBREADLINE)
    message(SEND_ERROR "Should not have found this library: ${LIBREADLINE}")
endif()
```

---
Let's first build this project using only CMake:
```sh
cmake -B build-cmake -S . --toolchain toolchain.cmake
```
This works as expected, `libreadline.so` is not found, because it does not exist in the (empty) sysroot.  
In the output, you'll see that CMake only searched the allowed locations: the _host_ system's sysroot, and the directories explicitly allowed by `CMAKE_FIND_ROOT_PATH`.

Now using Conan:
```sh
conan install . -c tools.cmake.cmaketoolchain:user_toolchain="[\"$PWD/toolchain.cmake\"]" -c tools.build.cross_building:cross_build=true
cmake --preset conan-release
```
This fails. In the output, you can see that CMake is looking in folders like `/usr/lib` on the _build_ system. Eventually, it finds the file in `/usr/lib/x86_64-linux-gnu/libreadline.so`. If you're cross-compiling, this file is not likely to be compatible with your _host_ system (e.g. different architecture, different glibc version, different ABI, different compilation flags, etc.), and the resulting binaries are now broken.

[question] Is IMPORTED_LOCATION missing for conan_package_library_targets?
### What is your question?

I am not sure if this a bug but in conan_package_library_targets or if I am missing something
https://github.com/conan-io/conan/blob/develop2/conan/tools/cmake/cmakedeps/templates/macros.py 

line 86 an imported target is generated
line 89 specifies its IMPORTED_LOCATION_RELEASE

But per CMP0111  an imported target always needs to define its IMPORTED_LOCATION, why is it not set?

Now I am getting a warning in my case due to cmake_minimum_required being smaller then 3.19
```
CMake Warning (dev) at 'file' (get_target_property):
  Policy CMP0111 is not set: An imported target missing its location property
  fails during generation.  Run "cmake --help-policy CMP0111" for policy
  details.  Use the cmake_policy command to set the policy and suppress this
  warning.

  IMPORTED_LOCATION not set for imported target
  "CONAN_LIB::package_library_RELEASE".
```


### Have you read the CONTRIBUTING guide?

- [x] I've read the CONTRIBUTING guide
[question] CMakeDeps and inter-package dependencies when using shared libraries
### What is your question?

Hi!

I ran into a problem with `CMakeDeps` generator when shared libraries are used and the consuming project has a unit-test-like application. Trying to describe the situation as briefly as I could, but I have to dive deep. This might be due to my misunderstanding of the advanced dependency handling, but I try to do my best.

So let's consider the following things:
* conan/2 is used: 2.7
* every library is used as shared (`*:shared=True`)
* the dependency graph is the following:
   ```mermaid
   graph LR;
   rest{{deps. of log4cxx}};
   game-->engine;
   engine-->log4cxx;
   log4cxx-->rest;
   ```
  Names borrowed from here: https://www.youtube.com/watch?v=kKGglzm5ous . `math` substituted with `log4cxx` to have some more dependencies.

Everything works correctly as described in the aforementioned video until I add a unit test to the `engine` package, just like that:

`engine/CMakeLists.txt`:
```CMake
cmake_minimum_required(VERSION 3.15)
project(engine CXX)

include(CTest)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_VERBOSE_MAKEFILE ON)

find_package(log4cxx REQUIRED CONFIG)

add_library(engine src/engine.cpp)
target_include_directories(engine PUBLIC include)

target_link_libraries(engine PRIVATE log4cxx)

set_target_properties(engine PROPERTIES PUBLIC_HEADER "include/engine.h")
install(TARGETS engine)

if (BUILD_TESTING)
  add_subdirectory(test)
endif()
```

`engine/test/CMakeLists.txt`:
```CMake
add_executable(engine_test
  test_main.cpp)

target_link_libraries(engine_test
  PRIVATE engine )

add_test(NAME engine_test
  COMMAND engine_test )
```

So, `engine` depends privately on `log4cxx` and `engine_test` depends on `engine`, in turn.
At this point when I try to compile the whole engine package, the link step of `engine_test` fails:
```
/usr/bin/c++ -m64 -O3 -DNDEBUG -m64 CMakeFiles/engine_test.dir/test_main.cpp.o -o engine_test  -Wl,-rpath,/home/user/some/path/engine/build/Release ../libengine.so 
/usr/lib/gcc/x86_64-pc-linux-gnu/7.5.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libaprutil-1.so.0, needed by /home/user/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so.15, not found (try using -rpath or -rpath-link)
/usr/lib/gcc/x86_64-pc-linux-gnu/7.5.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libapr-1.so.0, needed by /home/user/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so.15, not found (try using -rpath or -rpath-link)
/usr/lib/gcc/x86_64-pc-linux-gnu/7.5.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libiconv.so.2, needed by /home/user/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so.15, not found (try using -rpath or -rpath-link)
/usr/lib/gcc/x86_64-pc-linux-gnu/7.5.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libcharset.so.1, needed by /home/user/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so.15, not found (try using -rpath or -rpath-link)
/usr/lib/gcc/x86_64-pc-linux-gnu/7.5.0/../../../../x86_64-pc-linux-gnu/bin/ld: /home/user/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so.15: undefined reference to `apr_socket_connect'
...
```
Interestingly `liblog4cxx.so.15` is found but its dependencies not. The linker command line lacks here the library paths (`-L`)  (and RPATH definitions (`-Wl,--rpath`)) of the transitive dependencies of `engine`, however they were present when `engine` library was built:
```
/usr/bin/c++ -fPIC -m64 -O3 -DNDEBUG -m64 -shared -Wl,-soname,libengine.so -o libengine.so CMakeFiles/engine.dir/src/engine.cpp.o   -L/home/nbukuli/.conan2/p/b/log4c3762b28bed3ae/p/lib  -L/home/nbukuli/.conan2/p/apr-u46962cbae52f2/p/lib  -L/home/nbukuli/.conan2/p/apr-u46962cbae52f2/
p/lib/apr-util-1  -L/home/nbukuli/.conan2/p/apr544b7ac059c68/p/lib  -L/home/nbukuli/.conan2/p/libic63a94c7c34484/p/lib  -L/home/nbukuli/.conan2/p/b/expat439bcb6038711/p/lib  -Wl,-rpath,/home/nbukuli/.conan2/p/b/log4c3762b28bed3ae/p/lib:/home/nbukuli/.conan2/p/apr-u46962cbae52f2/p/li
b:/home/nbukuli/.conan2/p/apr-u46962cbae52f2/p/lib/apr-util-1:/home/nbukuli/.conan2/p/apr544b7ac059c68/p/lib:/home/nbukuli/.conan2/p/libic63a94c7c34484/p/lib:/home/nbukuli/.conan2/p/b/expat439bcb6038711/p/lib: /home/nbukuli/.conan2/p/b/log4c3762b28bed3ae/p/lib/liblog4cxx.so -lm 
```
When `engine` is built its dependencies are all come from the config files generated by `CMakeDeps` however dependencies of `engine_test` handled internally by CMake.

Everything works well, if `*:shared=False`, because in that case every static library is listed in the linker commandline when linking `engine_test`.

This issue might be related to this one: https://github.com/conan-io/conan/issues/16911

What do I wrong? If it is possible, I try to use modern CMake and rely on `target_link_libraries` with local targets in this case. I suppose a workaround could be written, where I query all the link-time dependencies of `engine` and apply them to `engine_test` but I try to avoid that. 

Any guidance will be highly appreciated. Unfortunately I cannot find corresponding points in the documentation.
Thank you in advance!

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide
[feature] `CONAN_RUNTIME_LIB_DIRS` for CMakeDeps
### What is your suggestion?

Hi! I'm adding a feature to automatically install conan runtimes in a cmake library aminya/project_options#279. Since the usage of conan is optional, the repo chooses to use cmake-conan. However, `CONAN_RUNTIME_LIB_DIRS` is set by CMakeToolchain while [cmake-conan could only supports CMakeDeps](https://github.com/conan-io/cmake-conan?tab=readme-ov-file#known-limitations-with-conan-20), so I couldn't install runtimes when using cmake-conan.

I would like to have some way to collect `CONAN_RUNTIME_LIB_DIRS` when only CMakeDeps is specified.

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide
[bug] find frameworks path is cached in cmake and not invalidated when dependency updates
### Describe the bug

this code from cmakedeps_macros.cmake has nasty bug
```
macro(conan_find_apple_frameworks FRAMEWORKS_FOUND FRAMEWORKS FRAMEWORKS_DIRS)
    if(APPLE)
        foreach(_FRAMEWORK ${FRAMEWORKS})
            # https://cmake.org/pipermail/cmake-developers/2017-August/030199.html
            find_library(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND NAMES ${_FRAMEWORK} PATHS ${FRAMEWORKS_DIRS} CMAKE_FIND_ROOT_PATH_BOTH)
            if(CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND)
                list(APPEND ${FRAMEWORKS_FOUND} ${CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND})
                message(VERBOSE "Framework found! ${FRAMEWORKS_FOUND}")
            else()
                message(FATAL_ERROR "Framework library ${_FRAMEWORK} not found in paths: ${FRAMEWORKS_DIRS}")
            endif()
        endforeach()
    endif()
endmacro()
```
It caches CONAN_FRAMEWORK_${_FRAMEWORK}_FOUND variable and after conanfile is updated with the new version cmake still uses old cached framework.

This is CMakeDeps generator, conan 1.64. I suppose conan v2 has similar issue, but I didn't check





### How to reproduce it

_No response_


Discussion:
Things that become possible:
- Create `xxx_EXECUTABLE` cmake variables
- Create IMPORTED executable targets in cmake: `CONAN_PKG::xxx` + `xxx::xxx`

A potential issue on Macos is the requirement to set `DYLD_LIBRARY_PATH` in the same call. See https://github.com/conan-io/conan-center-index/pull/1179#issuecomment-621339628.
Hi. I'm not opposed to adding a `cpp_info.exes` field to the package information (probably it is needed), but we need to be very cautious about adding variables and targets. 

Usually (always?) in the `CMakeLists.txt` files we use these executables from the requirements (`protoc`, `doxygen`,...) to execute something in the process of building, that is, the executable works in the _build_ machine while we are generating binaries for the _host_ machine.

Take the well-know `protobuf/protoc` example and this graph as a reference:

![image](https://user-images.githubusercontent.com/1406456/85670222-fa726b00-b6c0-11ea-88a5-1ee206bc0283.png)

Here, the `CMakeLists.txt` of `my_pkg` will contain something as follows:

**CMakeLists.txt**
```cmake
project(my_pkg)

find_package(protobuf)  # Provides targets 'protobuf::libprotobuf' and proposed 'protobuf::protoc'

protobuf_generate_cpp(....)  # <-- Here we want to use protoc
add_library(my_pkg ...)
target_link_libraries(my_pkg protobuf::libprotobuf)
```

It is clear that our library `my_pkg` want to link with the target `protobuf::libprotobuf` provided by `find_package(protobuf)`, that is the library that has been compiled for the _host_ machine and it is available via the `Findprotobuf.cmake` file that Conan has generated.

But, the `protoc` executable we need here is not the one from the `Findprotobuf.cmake` (that belongs to the _host_ context, may not run in this _build_ machine), **the `protoc` we want belong to the _build_ context**, it is in a different package and we don't have `Findprotobuf-build-context.cmake` for it! We can use and run that `protoc` only because Conan injected the PATH to that executable in the environment before running CMake.

* `protobuf::protoc` won't ever contain the executable we want in this scenario, which is probably the same scenario as others with Java, Python, Doxygen,... executables. 
   We could hack Conan to offer the `protoc` from the _build_ context via the target  created with the `FindXXXX.cmake` that belongs to the _host_ context. But, IMHO, that is too hacky.
* Using just `protoc`, not a target but the name of the executable, delegates on Conan the job of adding to the PATH the proper executable, which is always the one from the _build_ context.

**IMO we should encourage raw executables over targets (`protoc` over `protobuf::protoc`) in `CMakeLists.txt`, otherwise we might be blocking cross-building scenarios.**

---

There are two challenges with this approach:
 * how to provide those executables and manage the `DYLD_....` Macos SIP problem. 
 * how to populate CMake variables like `JAVA_EXECUTABLE`, `PROTOC_EXECUTABLE`,... we can just assign them to the name of the executable:
   ```
   set(JAVA_EXECUTABLE java)
   set(PROTOC_EXECUTABLE java)
   ```

About the problem with shared libraries (it is not only Macos and SIP, the problem still exists for the rest of OS), I'm still thinking about how to deal with it. Some ideas, but I need to make up my mind before sharing them. 
BTW, my last approach requires `cpp_info.exes` to list the executables. My long paragraph was only about how to deal with them inside CMake, not about the initial proposal of this issue. 😉 
Another use case of that is automoc/autouic/autorcc of Qt. Currently it is not possible to use automoc with conan qt recipes and cmake_find_package(_multi) generator.
Automoc needs a target like Qt5::moc that points to  the moc.exe.
Adding executable components to the tree would avoid adding executable-only requirements to libraries.
e.g. let's assume a package provides a library and an executable.
This packages also requires 2 dependencies: one is used by the library and the other is used by the executable.
Right now, both dependencies need to be listed as requirement for the library.
```python
def package_info(self):
    self.cpp_info.components["lib"].libs = ["library"]
    self.cpp_info.components["lib"].requires = ["libdep::libdep", "exedep::exedep"]
```
Even though the `exedep::exedep` requirement is only used by the executable.
When executable components would be introduced, this could be expressed in code as:
```python
def package_info(self):
    self.cpp_info.components["lib"].libs = ["library"]
    self.cpp_info.components["lib"].requires = ["libdep::libdep"]
    self.cpp_info.components["exe"].executable = "program"
    self.cpp_info.components["exe"].requires = ["lib", "exedep::exedep"]
```

Hi! Qt is a really good example and a challenging one for the cross-building scenario. First step will be to add the executables to the `cpp_info`, but then we need to understand how to work with them from within CMake. This is the same scenario as `protoc`.

The problem with these scenarios arises when we enter the cross-building with the two contexts: _host_ and _build_. If we are cross-building to ARM a package that depends on Qt, we want:
 * `find_package(Qt)` to find the libraries suitable for ARM
 * but we want `Qt::moc` to be the executable that runs in your _build_ machine.

Here, libraries and the `moc` executable come from completely different packages. The native building is just a concrete scenario of the general cross-building one.

The consequence of this is that you shouldn't be using `Qt::moc` inside the `CMakeLists.txt` because it won't be the executable you want. You should use `moc.exe` and the environment outside CMake should be responsible of adding to the PATH the `moc.exe` that is in your graph as a `build_requires`.
If only moc.exe is in PATH, automoc will not work. automoc needs a target called Qt5::moc
I've been having a quick look to the Qt docs and to Google. I've found this [question in Stackoverflow](https://stackoverflow.com/questions/39075040/cmake-cmake-automoc-in-cross-compilation) (_"CMake CMAKE_AUTOMOC in cross compilation"_) with the answer I'm copy/pasting here for reference:

> I finally found the solution thanks to this post: https://stackoverflow.com/questions/36570791/how-can-i-use-cmakes-automoc-feature-with-a-custom-qt-package. As I assumed the `QT_MOC_EXECUTABLE` isn't use directly by `AUTOMOC`.
>
>Before first qt `find_package` following lines must be added:
>
>   ```
>    set(QT_MOC_EXECUTABLE /usr/bin/moc)
>    add_executable(Qt5::moc IMPORTED)
>    set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})
>    ```
>
>The issue here was that not only the variable `QT_MOC_EXECUTABLE` has to be set to proper value but finally the automoc uses just `Qt5:moc` target which must be declared before any qt package will be included in `CMakeList.txt` file.
>
>This same issue is with other qt tools so more generic option will be:  
>
>    ```
>    file(GLOB Qt_bin /usr/bin)
>    find_program(QT_MOC_EXECUTABLE qt_moc moc PATHS ${Qt_bin})
>    add_executable(Qt5::moc IMPORTED)
>    set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})
>    ```

One cannot use the `Qt5::moc` provided by the package in a general scenario. I still don't know how we can handle this situation in Conan, the recipe for Qt is WIP in ConanCenter, and next major Conan version will use the two profiles as the default way to work. By that time (or before), we need to have answered these questions.
Somehow related to https://github.com/conan-io/conan-center-index/pull/2740/files#r481107458
also: https://github.com/conan-io/conan/issues/7444
@jgsogo Ignoring the various Qt specific variables (which should be handled by build_modules), I guess I don't really see Conan having the same issue as Qt's builtin cmake scripts. They only have (and can assume) the single distribution of Qt for those scripts, so it makes sense that they don't work for cross compilation -- although thankfully that seems to be easily worked around with a toolchain per the stack overflow post.

I guess the way I see it working for conan is that the generated cmake scripts would have the library targets from the requires and the executable targets from the build_requires. If a package has a common require and build_require (e.g. Qt), these two would have to be merged. Of course this needs something like #7324 so that you don't pull an executable's potentially conflicting library requirements into cmake.

I don't really know how capable other generators are at handling executables, so I'm not really sure what is needed to be considered there.

Also, as a note with Qt: to cross-compile Qt, you need Qt on the build system, i.e. Qt is a build_requires of Qt when cross-compiling. I don't know if conan will handle this at the moment, although I see no reason why conan shouldn't properly handle this (once the build and host graphs are disjoint).
Hi, @ohanar , thanks for your comments.

> I guess the way I see it working for conan is that the generated cmake scripts would have the library targets from the requires and the executable targets from the build_requires

Yes, this would be a way to go, merging two different nodes (the one from the build-requires and the one from the requires) into a single generated `FindXXXX.cmake` file. This can be very challenging (of course not before a new graph model for Conan 2.0), but still, it has some drawbacks: executables from _host_ might be used by an [emulator to run testing](https://cmake.org/cmake/help/v3.15/variable/CMAKE_CROSSCOMPILING_EMULATOR.html) (I haven't checked if it works with targets, but it should), so not always these targets can refer to the _build_ ones.

Then I step back and think if it is those CMake's functions/macros the ones that are broken, and CMake targets should always be the artifacts from the _host_ context and those functions should never use them to run `protoc` or any executable. Cmake would need something else, those scripts should try to find the executable somehow (in the PATH) first and then fallback to the target defined inside the library only if it is not a cross-compiling scenario. I'm not sure if here we are trying to workaround something _broken_ in 3rd party scripts... instead of patching those scripts to do the right thing.
FYI, here is a POC of executables imported targets in geographiclib recipe, working with conan 1.32.0 https://github.com/conan-io/conan-center-index/pull/4295/commits/815254d31f7f345688a7d6c18e58c8c6b2146cd0
There is another use case that might be valid for this cpp_info new model, the COM objects from @thorntonryan 

https://github.com/conan-io/conan/pull/11601#issuecomment-1243880002

> Importantly the consuming application doesn't link directly against these DLLs. Instead, COM objects are [created](https://docs.microsoft.com/en-us/windows/win32/learnwin32/creating-an-object-in-com) in a variety of ways and can come from within the same process, a different process, or even a different computer entirely. Ordinarily the COM servers are registered on a machine using regsvr32 and the consuming application loads them at runtime via COM machinery. Registration free techniques also exist for consumers to leverage.

> Fortunately, our needs are simple. We really just need a CMake target that knows where these DLLs live, that way we can feed them into other custom CMake tooling that produces language projections (i.e. C++ header files) for our COM libraries based on the interface definitions (i.e. type library) embedded inside the DLLs.

> Prior to CMakeDeps, we were creating our own IMPORTED targets for these COM servers and using IMPORTED_LOCATION to describe where the DLLs sat on disk. This way we had a CMake target that knew where the files were.

> But since CMakeDeps doesn't really have a way to model COM servers, when the resulting CMake targets are created, they don't know where these DLLs live, and so we have to work a little harder to set custom properties that tell us their location.

> I'm honestly not sure what's the best approach to take. I transitioned off my CMakeDeps spike back to cmake generator, but IIRC CMakeDeps is producing INTERFACE targets instead of IMPORTED ones. And we have some questions about correct usage of [reserved CMake properties](https://discourse.cmake.org/t/question-about-reserved-cmake-properties/6104) like INTERFACE_* or IMPORTED_*.

> I'm assuming that however you model exes will result in a CMake target that knows where that exe sits on disk, that way you can use the CMake target in CMake commands, etc. If so that's exactly the sort of thing we're looking to do with our COM servers.
[@jgsogo said..](https://github.com/conan-io/conan/issues/7240#issuecomment-649290533)
> IMO we should encourage raw executables over targets (`protoc` over `protobuf::protoc`) in `CMakeLists.txt`, otherwise we might be blocking cross-building scenarios.

## Not considering cross compilation

Stepping away from the cross compilation problem where the build and host profiles are different for a second, how would this work for a more vanilla use case, where a package _only_ distributes an executable? The use case I have in mind in particular is `sphinx-build`, when used to generate documentation - example in https://github.com/conan-io/conan/pull/11601.

Using the target, an exemplar of what I've been using is:

```cmake
find_package(sphinx REQUIRED)

# Sphinx configuration
set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR})
set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx)
set(SPHINX_INDEX_FILE ${SPHINX_BUILD}/index.html)

add_custom_command(
  OUTPUT ${SPHINX_INDEX_FILE}
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/index.rst
  COMMAND sphinx::sphinx-build -b html ${SPHINX_SOURCE} ${SPHINX_BUILD}
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  COMMENT "Generating documentation with Sphinx")
```

With your proposal, without using the cmake target, the following change is made:

```diff
-   COMMAND sphinx::sphinx-build -b html ${SPHINX_SOURCE} ${SPHINX_BUILD}
+  COMMAND sphinx-build -b html ${SPHINX_SOURCE} ${SPHINX_BUILD}
```

Do you see any danger here that an ambiguity has been introduced as to the necessity/purpose of the `find_package(sphinx)` directive?

To be explicit about what that ambiguity is:
* Without using the target, it's not obvious that the path to `sphinx-build` is being influenced by the `find_package(...)` directive
* This is no longer notionally conan-agnostic in the sense that it deviates from the idiom of using imported targets for executables

## Considering Cross Compilation

Coming back to the problem of cross compilation, as you say, the only executable we would ever be interested in here would be the executable exported in the build environment. Wouldn't it then make sense to:
* Exclude any export of executable targets when `mypkg-config.cmake` is being generated for a recipe in the host profile - i.e. **do not export `mypkg::exe`** when the recipe is in the host profile
* Export executable targets as `IMPORT` targets to `mypkg-build-config.cmake` (or similar) when the package is in the build profile - i.e. **do export `mypkg::exe`** when the recipe is in the build profile
* Perform a query in `mypkg-config.cmake` (generated in the host profile) to `include` the build `-config.cmake` file:

```cmake
include(${CMAKE_CURRENT_LIST_DIR}/mypkg-build-config.cmake)
```
where the contents of `mypkg-build-config.cmake` is something approximating:

```
if(NOT TARGET mypkg::exe)
    add_executable(mypkg::exe IMPORTED)
    set_target_properties(mypkg::exe PROPERTIES IMPORTED_LOCATION /home/user/.conan/data/mypkg/0.1.0/_/_/package/<package id>/bin/mypkg_exe)
endif()
```

Then, the exe target `mypkg::exe` would only exist when a package is used in the build context, not solely in the host context.

This appears to be the pattern that's already being used for different `build_type` values, so it would be consistent with the current approach, just adding the additional dimension of build vs host profile rather than just build type.

I can't think of a use case for including an executable in the host context, but _if_ it were needed, that could also be accounted for by making it a component property or something, where you have to choose _either_ build or host context, which would switch which `mypkg-{,build-}config.cmake` it's generated in. Alternatively, perhaps it could make it into the new requirements modelling:

```python
def requirements(self):
    # default exes=False, this indicates that exes should be 
    # available in host context
    self.requires("protobuf/x.y.z", exes=True) 

def build_requirements(self):
    # default exes=True. Validation would need to occur
    # to ensure that only one profile has exes=True for each
    # package required in both
    self.tool_requires("protobuf/x.y.z", exes=False) 
```

Perhaps this is what you were trying to get at in your comments above and I just misunderstood. Regardless, I think that this would be a reasonable first step to modelling these executable requirements, even if it's not perfect. Having an implementation modelling build executables would help us more readily evaluate the importance of modelling executables in the host context. This can be an iterative process - we don't need to have a perfect solution before we do anything. We don't need perfect to get in the way of useful.

## User interface

I think, as a user, using the target is a much more preferable interface to hoping that conan injects the `PATH` correctly behind the scenes so that the program name resolves correctly. Using the target is much more traceable way of ensuring that there won't be any conflict with system executables, and is generally the way that CMake expects executables to be used, particularly because of the way it resolves/substitutes paths when executable targets are used with `add_custom_command`.
@jcar87 @memsharded @lasote how is this going? Any updates to share?
@memsharded is this on your horizon/roadmap at all?
What is the current status of this? In the absence of this feature, what is the current best practice for supplying package_info for an executable?
@peakschris the thing is that this model hasn't been prioritized because for the majority of cases, it is not necessary.

Conan is already automatically adding dependencies packages ``bindirs`` from ``tools_requires`` to the PATH, LD_LIBRARY_PATH, etc, as necessary. So it is not necessary to do anything specific to use those executables from consumers, a normal ``self.run("mydep_exe")`` will work, or even if ``mydep_exe`` is ran inside a build script, it will still work. 


@memsharded ok, I can see that.

My case is I'm using Bazel to consume conan packages, and bazel requires executables to be wrapped in a sh_binary rule before they are used in the toolchain. E.g:

```
sh_binary(
    name = "flatc.exe",
    srcs = ["bin/flatc.exe"],
    visibility = ["//visibility:public"],
)
```

The bazel/conan integration already creates wrapper rules for each library. I would guess that it would need some metadata for each binary in order to allow it to create these wrapper rules for executables.


Quick question: if not using ``check_c_source_compiles()``, but just building a normal library or executable that ``target_link_libraries()`` the openssl targets, does it work?

> Quick question: if not using `check_c_source_compiles()`, but just building a normal library or executable that `target_link_libraries()` the openssl targets, does it work?

Yes
From what I see in https://cmake.org/cmake/help/latest/module/CheckCSourceCompiles.html, ``check_c_source_compiles()`` executes as ``try_compile()``, which is not the same context as the main project, and it requires to pass ``CMAKE_REQUIRED_INCLUDES, CMAKE_REQUIRED_LIBRARIES`` etc, but not the targets, so it could be related. No idea why it would work with some generators like Ninja and not the others. Ninja with the VS compiler (cl.exe) works fine? I assume that the above failure is with standard CMake "Visual Studio" generator?
The failure is only with the standard CMake "Visual Studio" generator, running manually the cmake project configured by conan with `-G "Ninja"` fix the issue.
related issue: https://github.com/conan-io/conan/issues/12180
More or less all CMake macros in https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html#utility-modules like `check_c_source_compiles`, `check_cxx_source_compiles`, `check_symbols_exists`, `check_cxx_symbols_exists`, `check_function_exists`, `check_include_file` etc are broken with `<name>_LIBRARIES` variables created by CMakeDeps.
I've experienced the same in the following context:
* I've tried to make the recipe of libssh2 conan-2 compatible, it depends on OpenSSL
* There is a `check_function_exists` call in the CMake code of libssh2, where we command cmake to link to `openssl::openssl`.
* `openssl::openssl` depends on `OpenSSL::SSL` , `OpenSSL::SSL` depends on "micro target" `CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE` in turn
* The targets `openssl::openssl`, `OpenSSL::SSL` are `INTERFACE IMPORTED`
* The target `CONAN_LIB::openssl_OpenSSL_SSL_libssl_RELEASE` is `UNKNOWN IMPORTED`
* The `check_function_exists` calls `try_compile`, what supports `INTERFACE IMPORTED` targets to link against, but it does not suport `UNKNOWN IMPORTED` targets. (cmake command line option `--debug-trycompile` is useful here)

The `CONAN_LIB:XXX` micro targets are defined in the function `conan_package_library_targets` in the generated file `cmakedeps_macros.cmake` somewhat like this:

```
function(conan_package_library_targets libraries package_libdir deps_target out_libraries_target config_suffix package_name)
    set(_out_libraries_target "")

    foreach(_LIBRARY_NAME ${libraries})
        find_library(CONAN_FOUND_LIBRARY NAMES ${_LIBRARY_NAME} PATHS ${package_libdir}
                     NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
        if(CONAN_FOUND_LIBRARY)
            message(VERBOSE "Conan: Library ${_LIBRARY_NAME} found ${CONAN_FOUND_LIBRARY}")

            # Create a micro-target for each lib/a found
            # Allow only some characters for the target name
            string(REGEX REPLACE "[^A-Za-z0-9.+_-]" "_" _LIBRARY_NAME ${_LIBRARY_NAME})
            set(_LIB_NAME CONAN_LIB::${package_name}_${_LIBRARY_NAME}${config_suffix})
            if(NOT TARGET ${_LIB_NAME})
                # Create a micro-target for each lib/a found
                add_library(${_LIB_NAME} UNKNOWN IMPORTED)
            endif()
           # .....
endfunction()
```

If I change the library type to `INTERFACE IMPORTED` like this:
`add_library(${_LIB_NAME} INTERFACE IMPORTED)`
then `try_compile` properly "memoizes" this micro target, as well as `OpenSSL::SSL`, `OpenSSL::Crypto` and `openssl::openssl`, and it succeeds, so `check_function_exists` succeeds as well.

`try_compile` creates a temporary CMake project (again, `--debug-trycompile` helps), what contains a `cmTC-<XXX>Targets.cmake` file. In this file cmake memoizes all `INTERFACE IMPORTED` dependencies from the calling context, transitively.

Is it possible to define these micro-targets as `INTERFACE IMPORTED` libraries or it wrecks something else? 
I see this being pushed along the 1.x track of releases, but I wanted to report that this is happening with 2.0.14 as well. It's basically blocking us from being able to use OpenSSL as a dependency via conan unfortunately, which also blocks a number of other libraries (such as libcurl):

```
CMake Error at C:/<>/build/CMakeFiles/CMakeScratch/TryCompile-ncuco8/cmTC_33fd1Targets.cmake:42 (set_target_properties):
  The link interface of target "OpenSSL::SSL" contains:

    CONAN_LIB::openssl_OpenSSL_SSL_libssld_DEBUG

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.

Call Stack (most recent call first):
  C:/<>/build/CMakeFiles/CMakeScratch/TryCompile-ncuco8/CMakeLists.txt:18 (include)
```
Should also mention: I ran into this issue while working on a Git recipe, due to this I am unable to use the provided CMake file.

similar issue as https://github.com/conan-io/conan/issues/12012
The CMake documentation specifies that _targets_ are actually a valid input for anything that relies on `try_compile`, including `check_symbol_exists`. Docs here: https://cmake.org/cmake/help/latest/command/try_compile.html#options

The problem here is that the targets generated by `CMakeDeps` _require_ a build type to be set (`CMAKE_BUILD_TYPE` for  single config generators) - but the temporary CMake project that is _created_ by `try_compile`, does not have any configuration set, which causes the issues.

A possible solution is to simply tell CMake to forward the current configuration to the `try_compile` generated projects: `https://cmake.org/cmake/help/latest/variable/CMAKE_TRY_COMPILE_CONFIGURATION.html#variable:CMAKE_TRY_COMPILE_CONFIGURATION` - in a recipe this could be done via:

```
tc.cache_variables["CMAKE_TRY_COMPILE_CONFIGURATION"] = str(self.settings.build_type)
```

Alternatively, this fix in upstream CMake https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8016 might help - I believe it made it to CMake 3.26. I still need to test if it solves this particular issue, as the underlying cause has to do with the targets generated by CMakeDeps having gen-ex conditionals that depend on the build type.

I can test with dcmtk.
It doesn't seem to work. I've tested in dcmtk recipe:

- I've removed current workaround for this issue in dcmtk recipe: https://github.com/conan-io/conan-center-index/blob/master/recipes/dcmtk/all/conanfile.py#L164-L229
- And added `tc.cache_variables["CMAKE_TRY_COMPILE_CONFIGURATION"] = str(self.settings.build_type)`

But still get this error during CMake configuration (macOS x86_64/Release/all shared/apple-clang 15/CMake 3.27.7/conan 2.0.13/Ninja generator):

```
-- Looking for prototype of SSL_CTX_get0_param
CMake Error at /Users/spaceim/.conan2/p/b/dcmtk278ca8b211711/b/build/Release/CMakeFiles/CMakeTmp/CMakeLists.txt:25 (target_link_libraries):
  Target "cmTC_4d7c0" links to:

    openssl::openssl

  but the target was not found.  Possible reasons include:

    * There is a typo in the target name.
    * A find_package call is missing for an IMPORTED target.
    * An ALIAS target is missing.



CMake Error at CMake/CheckFunctionWithHeaderExists.cmake:30 (try_compile):
  Failed to generate test project build system.
Call Stack (most recent call first):
  CMake/dcmtkPrepare.cmake:671 (CHECK_FUNCTIONWITHHEADER_EXISTS)
  CMakeLists.txt:38 (include)
```
Adding `CMAKE_TRY_COMPILE_CONFIGURATION` very clearly fixed the `try_compile()` issues with OpenSSL symbol detection in https://github.com/conan-io/conan-center-index/pull/21389.

I'll be adding this workaround just in case for any recipes that make use of compilation tests with `CMAKE_REQUIRED_LIBRARIES` in the future.

Mmmhh actually it may be an issue of libzipp recipe instead. I see that linker errors occur while linking `libzippp_shared_test` executable to `libzippp`, and this part may not have been properly fixed to link to CMake target.
I re-open because looking at CMakeLists, it shouldn't have failed anyway. libzippp target builds fine, but when this target is linked into libzippp_shared_test, I guess something is not properly defined in libzip::zip target and therefore CMake doesn't understand that it must define `-rpath-link` with path to openssl since it's a dependency of libzip::zip.
I have just tested and it works.

There might be something else you have on your side that you are not reporting, for example `` cmake -G "Ninja"``, and Ninja generator is not used by default, so I guess you have some other configuration there that could be affecting (the Ninja thing in particular seems to be working fine here, but it is just a sign that there could be other factors.
Indeed, my global.conf is:

```
tools.cmake.cmaketoolchain:generator=Ninja
tools.info.package_id:confs=["tools.build:cflags", "tools.build:cxxflags", "tools.build:defines", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]
```
@memsharded there is a good chance that you can't reproduce this issue if the same openssl so version is installed on your Linux distribution.
I see a similar issue in a recipe not merged yet in conan center.

On Linux with this profile:

```
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++11
build_type=Release
```

You have to ckeckout first https://github.com/conan-io/conan-center-index/pull/16355 and call `conan create --version 1.9.2 -o "*:shared=True" -tf "" -b missing`
Then checkout https://github.com/conan-io/conan-center-index/pull/16356 and call `conan create . --version 2.0 -o "*:shared=True" -tf "" -b missing`

You should see these errors (since it's related to link errors to `coin-osi`, you have less chance to inaverdently not reproduce the issue):

<details><summary>log</summary>

```
[154/228] Linking CXX executable Linux-x86_64-Release/openMVG_main_SfMInit_ImageListing
FAILED: Linux-x86_64-Release/openMVG_main_SfMInit_ImageListing
: && /usr/bin/g++-12 -m64 -O3 -m64    -rdynamic software/SfM/CMakeFiles/openMVG_main_SfMInit_ImageListing.dir/main_SfMInit_ImageListing.cpp.o -o Linux-x86_64-Release/openMVG_main_SfMInit_ImageListing -L/home/spaceim/.conan2/p/coin-3845f169e96b1/p/lib   -L/home/spaceim/.conan2/p/flann85ffc349c0928/p/lib   -L/home/spaceim/.conan2/p/lz4866193c7de915/p/lib -Wl,-rpath,/home/spaceim/.conan2/p/coin-3845f169e96b1/p/lib:/home/spaceim/.conan2/p/flann85ffc349c0928/p/lib:/home/spaceim/.conan2/p/lz4866193c7de915/p/lib:/home/spaceim/.conan2/p/t/openmd7aa827f21e26/b/build/Release/Linux-x86_64-Release:  Linux-x86_64-Release/libopenMVG_sfm.so.2.0  Linux-x86_64-Release/libopenMVG_exif.so  Linux-x86_64-Release/libopenMVG_system.so.2.0  Linux-x86_64-Release/libopenMVG_image.so.2.0  Linux-x86_64-Release/libopenMVG_geometry.so.2.0  /home/spaceim/.conan2/p/coin-3845f169e96b1/p/lib/libemon.so  Linux-x86_64-Release/libopenMVG_matching.so.2.0  Linux-x86_64-Release/libopenMVG_features.so.2.0  Linux-x86_64-Release/libopenMVG_stlplus.so  /home/spaceim/.conan2/p/flann85ffc349c0928/p/lib/libflann_cpp.so  /home/spaceim/.conan2/p/lz4866193c7de915/p/lib/liblz4.so  Linux-x86_64-Release/libopenMVG_multiview.so.2.0  Linux-x86_64-Release/libopenMVG_numeric.so.2.0  -Wl,-rpath-link,/home/spaceim/.conan2/p/t/openmd7aa827f21e26/b/build/Release/Linux-x86_64-Release && :
/usr/bin/ld: warning: libOsi.so.1, needed by /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setColName(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::reducedCostFix(double, bool)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::ub() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::activateRowCutDebugger(double const*, bool)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getNumIntegers() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getRowNames[abi:cxx11]()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::deleteColNames(int, int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::writeLpNative(_IO_FILE*, char const* const*, char const* const*, double, int, int, double, bool) const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getColNames[abi:cxx11]()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getObjName[abi:cxx11](unsigned int) const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getStrictColSolution()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::setRow(int, int const*, double const*, bool)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::row() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getObjValue() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::OsiRowCut()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getFractionalIndices(double) const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::deleteBranchingInfo(int, int const*)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setRowNames(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, int, int, int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::~OsiSolverInterface()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `typeinfo for OsiSOS'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::dfltRowColName[abi:cxx11](char, int, unsigned int) const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::deleteRowNames(int, int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::findIntegers(bool)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::setLb(double)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::lb() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::restoreBaseModel(int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setInitialData()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::OsiSolverInterface()'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::writeMpsNative(char const*, char const**, char const**, int, int, double, int, CoinSet const*) const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiRowCut::setUb(double)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `typeinfo for OsiObject'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::OsiSolverInterface(OsiSolverInterface const&)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setRowName(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::readGMPL(char const*, char const*)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `typeinfo for OsiSolverInterface'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::operator=(OsiSolverInterface const&)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSOS::OsiSOS(OsiSolverInterface const*, int, int const*, double const*, int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setColNames(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, int, int, int)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::setObjCoeffSet(int const*, int const*, double const*)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::newLanguage(CoinMessages::Language)'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::getApplicationData() const'
/usr/bin/ld: /home/spaceim/.conan2/p/coin-68aeb962954a5/p/lib/libOsiClp.so.1: undefined reference to `OsiSolverInterface::activateRowCutDebugger(char const*)'
collect2: error: ld returned 1 exit status
[161/228] Building CXX object software/SfM/clustering/domSetLibrary/CMakeFiles/domset.dir/domset.cc.o
ninja: build stopped: subcommand failed.
```

</details>
I suspect the same issue in https://github.com/conan-io/conan-center-index/pull/16208#issuecomment-1488524143
> I see a similar issue in a recipe not merged yet in conan center.
> 
> On Linux with this profile:
> 
> ```
> [settings]
> os=Linux
> arch=x86_64
> compiler=gcc
> compiler.version=12
> compiler.libcxx=libstdc++11
> build_type=Release
> ```
> 
> You have to ckeckout first [conan-io/conan-center-index#16355](https://github.com/conan-io/conan-center-index/pull/16355) and call `conan create --version 1.9.2 -o "*:shared=True" -tf "" -b missing` Then checkout [conan-io/conan-center-index#16356](https://github.com/conan-io/conan-center-index/pull/16356) and call `conan create . --version 2.0 -o "*:shared=True" -tf "" -b missing`
> 
> You should see these errors (since it's related to link errors to `coin-osi`, you have less chance to inaverdently not reproduce the issue):
> 
> log

And indeed build of OpenMVG executables fails in c3i for "Linux all shared" because transitive shared libs don't seem to be added to -rpath-link: https://c3i.jfrog.io/c3i/misc-v2/logs/pr/16356/13-linux-gcc/openmvg/2.0//420b80fc6515bf813bb6636821a1a154a4010d07-build.txt

The common logic I see in these libraries is that:
- they depend on an external `foo` library (let's call its CMake imported target `foo::foo`) provided by conan which itself has private external dependencies.
- an internal library target `libA` links privately to imported target `foo::foo` with `target_link_libraries(libA PRIVATE foo::foo)`. It works fine.
- then an executable `execA` links to `libA` with `target_link_libraries(execA PRIVATE libA)`. For some reason, CMake doesn't generate linker commands with -rpath-link to private dependencies of `foo`, therefore in libfoo.so linker can't find  external symbols.
Same issue in test package of opencv: https://github.com/conan-io/conan-center-index/pull/16678#issuecomment-1508460965
@memsharded any chance that conan can track this issue? We have several repro cases in conan-center: opencv & openmvg. opencv recipe has an ugly workaround (protobuf libs are marked transitive, while they should not be).
I'd need some updated repro case, please, it seems the linked ones are already closed or outdated.

Also, investigating these things over ConanCenter recipes takes a lot more of time, that we usually don't have. Is not that we don't want to track it, is simply that we don't have more hours in the day, so they fall through the cracks. The chance to be able to address issues that are reported with simple ``conan new cmake_lib`` templates is a couple of orders of magnitude higher.
You can't reproduce with `conan new cmake_lib`. It's a more complex case involving transitive dependencies, components, maybe specific usage of symbols in libs etc
I'll try to create a minimal repro case, but it's not trivial. OpenCV issue is reproducible if you take current recipe, remove transivite_libs=True in self.requires(protobuf) and run test package on Linux when all libs are shared.
I think it's related to https://github.com/conan-io/conan/pull/13010#discussion_r1091019217, which points out that current conan implementation is fragile.
@memsharded Here is a minimal reproducible example: https://github.com/SpaceIm/conan_issue_13560. Instructions in README (3 `conan create` to run).
Thanks for putting the repro case together.

I have checked it, and it seems this would work changing this:

```diff
--- a/libC_issue13560/CMakeLists.txt
+++ b/libC_issue13560/CMakeLists.txt
@@ -4,7 +4,7 @@ project(libC_issue13560 LANGUAGES CXX)
 find_package(libb_issue13560 REQUIRED CONFIG)

 add_library(libC_issue13560 libC_issue13560.cpp)
-target_link_libraries(libC_issue13560 PRIVATE libb_issue13560::libb_issue13560)
+target_link_libraries(libC_issue13560 PUBLIC libb_issue13560::libb_issue13560)

 add_executable(execC_issue_13560 execC_issue13560.cpp)
 target_link_libraries(execC_issue_13560 PRIVATE libC_issue13560
```
It is not expected that you can link the executable with the dependencies correctly if you make libC->libB PRIVATE.
I've pushed a new commit (https://github.com/SpaceIm/conan_issue_13560/commit/c43456f8e7578fe5ff1f228b2ce78d7408822b37) which add an option in order to package flavors of libs with state of the art CMake config files, `cmake_find_mode` set to `"none"`, and `cpp_info.builddirs` set to folder of CMake config file. It works fine in this case, so there is something wrong in CMakeDeps.

```
[ 25%] Building CXX object CMakeFiles/libC_issue13560.dir/libC_issue13560.cpp.o
/usr/bin/g++-12 -DlibC_issue13560_EXPORTS -isystem /home/spaceim/.conan2/p/libb_27335799c51cc/p/include -m64 -O3 -DNDEBUG -std=c++20 -fPIC -MD -MT CMakeFiles/libC_issue13560.dir/libC_issue13560.cpp.o -MF CMakeFiles/libC_issue13560.dir/libC_issue13560.cpp.o.d -o CMakeFiles/libC_issue13560.dir/libC_issue13560.cpp.o -c /home/spaceim/.conan2/p/t/libc_147870e29a469/b/libC_issue13560.cpp
[ 50%] Linking CXX shared library liblibC_issue13560.so
/usr/bin/cmake -E cmake_link_script CMakeFiles/libC_issue13560.dir/link.txt --verbose=1
/usr/bin/g++-12 -fPIC -m64 -O3 -DNDEBUG -m64 -shared -Wl,-soname,liblibC_issue13560.so -o liblibC_issue13560.so CMakeFiles/libC_issue13560.dir/libC_issue13560.cpp.o  -Wl,-rpath,/home/spaceim/.conan2/p/libb_27335799c51cc/p/lib:/home/spaceim/.conan2/p/liba_4dd8731d25a2d/p/lib: /home/spaceim/.conan2/p/libb_27335799c51cc/p/lib/liblibB_issue13560.so -Wl,-rpath-link,/home/spaceim/.conan2/p/liba_4dd8731d25a2d/p/lib
gmake[2]: Leaving directory '/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release'
[ 50%] Built target libC_issue13560
/usr/bin/gmake  -f CMakeFiles/execC_issue_13560.dir/build.make CMakeFiles/execC_issue_13560.dir/depend
gmake[2]: Entering directory '/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release'
cd /home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/spaceim/.conan2/p/t/libc_147870e29a469/b /home/spaceim/.conan2/p/t/libc_147870e29a469/b /home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release /home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release /home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release/CMakeFiles/execC_issue_13560.dir/DependInfo.cmake --color=
gmake[2]: Leaving directory '/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release'
/usr/bin/gmake  -f CMakeFiles/execC_issue_13560.dir/build.make CMakeFiles/execC_issue_13560.dir/build
gmake[2]: Entering directory '/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release'
[ 75%] Building CXX object CMakeFiles/execC_issue_13560.dir/execC_issue13560.cpp.o
/usr/bin/g++-12   -m64 -O3 -DNDEBUG -std=c++20 -MD -MT CMakeFiles/execC_issue_13560.dir/execC_issue13560.cpp.o -MF CMakeFiles/execC_issue_13560.dir/execC_issue13560.cpp.o.d -o CMakeFiles/execC_issue_13560.dir/execC_issue13560.cpp.o -c /home/spaceim/.conan2/p/t/libc_147870e29a469/b/execC_issue13560.cpp
[100%] Linking CXX executable execC_issue_13560
/usr/bin/cmake -E cmake_link_script CMakeFiles/execC_issue_13560.dir/link.txt --verbose=1
/usr/bin/g++-12 -m64 -O3 -DNDEBUG -m64 CMakeFiles/execC_issue_13560.dir/execC_issue13560.cpp.o -o execC_issue_13560  -Wl,-rpath,/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release:/home/spaceim/.conan2/p/libb_27335799c51cc/p/lib:/home/spaceim/.conan2/p/liba_4dd8731d25a2d/p/lib: liblibC_issue13560.so -Wl,-rpath-link,/home/spaceim/.conan2/p/libb_27335799c51cc/p/lib:/home/spaceim/.conan2/p/liba_4dd8731d25a2d/p/lib
gmake[2]: Leaving directory '/home/spaceim/.conan2/p/t/libc_147870e29a469/b/build/Release'
[100%] Built target execC_issue_13560
```

Here is the relevant content which might differ from files generated by CMakeDeps. Specifically the `IMPORTED_LINK_DEPENDENT_LIBRARIES_*` is missing in conan source code... (see https://cmake.org/cmake/help/latest/prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES.html):

libA_issue13560Targets-release.cmake

```cmake
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Import target "libA_issue13560::libA_issue13560" for configuration "Release"
set_property(TARGET libA_issue13560::libA_issue13560 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(libA_issue13560::libA_issue13560 PROPERTIES
  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/liblibA_issue13560.so"
  IMPORTED_SONAME_RELEASE "liblibA_issue13560.so"
  )

list(APPEND _cmake_import_check_targets libA_issue13560::libA_issue13560 )
list(APPEND _cmake_import_check_files_for_libA_issue13560::libA_issue13560 "${_IMPORT_PREFIX}/lib/liblibA_issue13560.so" )

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
```

libB_issue13560Targets-release.cmake

```cmake
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Import target "libB_issue13560::libB_issue13560" for configuration "Release"
set_property(TARGET libB_issue13560::libB_issue13560 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(libB_issue13560::libB_issue13560 PROPERTIES
  IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE "libA_issue13560::libA_issue13560"
  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/liblibB_issue13560.so"
  IMPORTED_SONAME_RELEASE "liblibB_issue13560.so"
  )

list(APPEND _cmake_import_check_targets libB_issue13560::libB_issue13560 )
list(APPEND _cmake_import_check_files_for_libB_issue13560::libB_issue13560 "${_IMPORT_PREFIX}/lib/liblibB_issue13560.so" )

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
```


It is a known issue that Conan doesn't have the full information to define IMPORTED things in ``CMakeDeps``.
This will require some time to fix, probably some new features and a new optin for new ``CMakeDeps`` internal implementation. 

As there is a relatively easy workaround defining the ``target_link_libraries(PUBLIC)``, moving this to 2.X, to be done when working on https://github.com/conan-io/conan/issues/13018
Ok, thanks.

> As there is a relatively easy workaround defining the target_link_libraries(PUBLIC), moving this to 2.X, to be done when working on https://github.com/conan-io/conan/issues/13018

It's not an easy workaround when you have to patch CML forever. An easy workaround is to inject VirtualRunEnv into build scope.
Here is a summary I made, hoping it can help to improve `CMakeDeps`:

# CMake config file

## Context

- We have two libs: libA and libB, where libB may depend on libA. We are interesting to the content of state-of-the-art CMake config file of libB generated in install tree by `install(EXPORT ...)`.

- libB is a C++ library (it leads to `IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"` property when libB is `STATIC`, but except of that the result would be the same for a C library). It's worth noting that conan doesn't add this property, therefore several recipes propagate `stdcpp_library()` in system libs if shared=False as a workaround (this workaround can be a problem for folks who want to link to static C++ standard library).

- libB has an interface definition `FOO`, and interface compile feature `cxx_std_11` (doesn't really matter to model link between libA & libB, but it shows how it's translated in a CMake config file. Note that conan has no concept of interface compile feature. Interface definition would basically be `cpp_info.defines` in libb recipe)

## Matrix

- libA [`TYPE`](https://cmake.org/cmake/help/latest/prop_tgt/TYPE.html):

  - `INTERFACE_LIBRARY`
  - `STATIC_LIBRARY`
  - `SHARED_LIBRARY`

- libB [`TYPE`](https://cmake.org/cmake/help/latest/prop_tgt/TYPE.html):

  - `INTERFACE_LIBRARY`
  - `STATIC_LIBRARY`
  - `SHARED_LIBRARY`
- libA and libB relationship:

  - libB doesn't depend on libA
  - libB depends on libA:
    - if libB is `INTERFACE` TYPE, libA can't be anything else than an `INTERFACE` dependency of libB
    - otherwise:
      - libA is a `PUBLIC` dependency of libB
      - libA is a `PRIVATE` dependency of libB

## Results

1. INTERFACE libB

   1.1. No dependency

   ```cmake
   # Config invariant
   add_library(libB::libB INTERFACE IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
   )
   ```

   2.1. Depends on INTERFACE or STATIC or SHARED libA

   ```cmake
   # Config invariant
   add_library(libB::libB INTERFACE IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
       INTERFACE_LINK_LIBRARIES "libA::libA"
   )
   ```

2. STATIC libB

   2.1. No dependency

   ```cmake
   # Config invariant
   add_library(libB::libB STATIC IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
       IMPORTED_LOCATION_RELEASE "<path/to/libB/static_file>"
   )
   ```

   2.2. Depends on INTERFACE or STATIC or SHARED libA (PRIVATE)

   ```cmake
   # Config invariant
   add_library(libB::libB STATIC IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
       INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:libA::libA>"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
       IMPORTED_LOCATION_RELEASE "<path/to/libB/static_file>"
   )
   ```

   2.3. Depends on INTERFACE or STATIC or SHARED libA (PUBLIC)

   ```cmake
   # Config invariant
   add_library(libB::libB STATIC IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
       INTERFACE_LINK_LIBRARIES "libA::libA"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
       IMPORTED_LOCATION_RELEASE "<path/to/libB/static_file>"
   )
   ```

3. SHARED libB

   3.1. No dependency or depends on INTERFACE or STATIC libA (PRIVATE)

   ```cmake
   # Config invariant
   add_library(libB::libB SHARED IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LOCATION_RELEASE "<path/to/libB/dll_or_so_or_dylib>"
       # if Windows
       IMPORTED_IMPLIB_RELEASE "<path/to/libB/import_lib_of_dll>"
       # if not Windows
       IMPORTED_SONAME_RELEASE "<@rpath/libB.dylib if Apple else libB.so>"
   )
   ```

   3.2. Depends on SHARED libA (PRIVATE)

   ```cmake
   # Config invariant
   add_library(libB::libB SHARED IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE "libA::libA"
       IMPORTED_LOCATION_RELEASE "<path/to/libB/dll_or_so_or_dylib>"
       # if Windows
       IMPORTED_IMPLIB_RELEASE "<path/to/libB/import_lib_of_dll>"
       # if not Windows
       IMPORTED_SONAME_RELEASE "<@rpath/libB.dylib if Apple else libB.so>"
   )
   ```

   3.3. Depends on INTERFACE or STATIC or SHARED libA (PUBLIC)

   ```cmake
   # Config invariant
   add_library(libB::libB SHARED IMPORTED)
   set_target_properties(libB::libB PROPERTIES
       INTERFACE_COMPILE_DEFINITIONS "FOO"
       INTERFACE_COMPILE_FEATURES "cxx_std_11"
       INTERFACE_INCLUDE_DIRECTORIES "<path/to/libB/includedir>"
       INTERFACE_LINK_LIBRARIES "libA::libA"
   )
   
   # Config specific
   set_property(TARGET libB::libB APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
   set_target_properties(libB::libB PROPERTIES
       IMPORTED_LOCATION_RELEASE "<path/to/libB/dll_or_so_or_dylib>"
       # if Windows
       IMPORTED_IMPLIB_RELEASE "<path/to/libB/import_lib_of_dll>"
       # if not Windows
       IMPORTED_SONAME_RELEASE "<@rpath/libB.dylib if Apple else libB.so>"
   )
   ```
@memsharded It may be a coincidence, but another similarity is that dependencies which seem to trigger this issue in some recipes depending on them, have `cmake_find_mode` set to `both` (freetype, libtiff, protobuf).

Hi @ilya-lavrenov 

Thanks for reporting. I think this is a known issue, would be a duplicated of https://github.com/conan-io/conan/issues/12654. I'd recommended closing this issue as duplicated and centralized discussion in the other one.

In short: this is a limitation of the available information in the ``cpp_info`` of the dependencies, for shared libraries, as well as the ``CMakeDeps`` target creation. There is pending a new model and ``CMakeDeps`` implementation for the 2.X roadmap.
Hi @memsharded 

I might be mistaken, but in the linked issue it is mainly about the `IMPORTED_LOCATION_<CONFIG>` , which is from my point of view already solved by the `${config_suffix}` in the version of the file posted by @ilya-lavrenov 
```
set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION${config_suffix} ${CONAN_FOUND_LIBRARY})
```
But what I am lacking as well is the `IMPORTED_CONFIGURATIONS` property, such that it is possible in user CMake code to first query the available configurations and then ask for the respective imported location. One example could look like [this](https://github.com/ros/catkin/blob/noetic-devel/cmake/catkin_libraries.cmake#L150), which looks like a reasonable logic for me to resolve imported targets.

A possible patch could look like this:
```
string(REGEX_REPLACE "^_" "" config_tmp ${config_suffix})
string(TOUPPER ${config_tmp} config)
set_target_properties(${_LIB_NAME}
  PROPERTIES
    IMPORTED_LOCATION${config_suffix} ${CONAN_FOUND_LIBRARY}
    IMPORTED_CONFIGURATIONS ${config}
)
```
There are surely various ways to write this in a nicer way (e.g. by not having `_` as part of the `config_suffix`), however I hope the snippet shows the intention and as far as I can see it should be also sufficiently explicit to not disturb any other use-cases (but my range of vision is unfortunately still very short for `conan` :laughing: ).
The missing IMPORTED_CONFIGURATIONS is leading to CMP0111 for me as explained in https://github.com/conan-io/conan/issues/16688
I created a PR #16705 in order to (hopefully) solve this issue. Following the contribution guide I want to ask @conan-io/barbarians to "queue" this issue (although I have to admit, I don't exactly know what this means in this context).
@marlamb regarding your comment that some tools like ``catkin`` is requiring this, maybe you want to be aware that we are working in a ros2 integration (cc @danimtb), with rosdep & colcon, not catkin
@memsharded that sounds great, I really appreciate!

Indeed the lifetime of `catkin` ends soon with the latest distros still supporting it running out of support (e.g. Ubuntu 20.04 next year). I just took it as an example of a logic that independent of the example looks is a valid CMake logic, that should be supported by `conan`.



Hi @tttapa 

Thanks for your report.

Can you please clarify what Conan version are you using?

Conan 2 sets only:
```cmake
        {% if build_paths %}
        # The explicitly defined "builddirs" of "host" context dependencies must be in PREFIX_PATH
        list(PREPEND CMAKE_PREFIX_PATH {{ build_paths }})
        {% endif %}
        {% if cmake_program_path %}
        list(PREPEND CMAKE_PROGRAM_PATH {{ cmake_program_path }})
        {% endif %}
```
from the build context, should this 2 variables  CMAKE_PREFIX_PATH  or CMAKE_PROGRAM_PATH  make the ``find_library()`` find a library in the build context?
Hi, I'm using version 2.3.1.

At first sight, the code you posted looks fine, the problematic lines are further down:

https://github.com/conan-io/conan/blob/95da083793960b74f362a0db6323df37e31e58e9/conan/tools/cmake/toolchain/blocks.py#L484-L502

Looking at the git blame, the last change to this bit of code was two years ago in 861170cdf2959942828f6db33c488c1b823522c2.
If I remember correctly, if `CMAKE_FIND_ROOT_PATH_MODE_{LIBRARY,INCLUDE,PACKAGE}` is set to `ONLY`, and there is a `CMAKE_SYSROOT` defined, none of the calls to `find_package`/`find_library`/`find_program` will work to locate anything provided by Conan - the entire search path, incl. `CMAKE_PREFIX_PATH` and so on,  will be re-rooted to the sysroot), and none of the relevant locations will actually be considered. 

> If a user explicitly sets CMAKE_FIND_ROOT_PATH_MODE_{LIBRARY,INCLUDE,PACKAGE}=ONLY in their toolchain file, it is often for good reasons, and IMHO silently changing those values inside of Conan's toolchain file is not an acceptable solution.

I could agree that if the variable is already defined with an `ONLY`, we could warn - either honour it and expect CMake to not find anything provided by conan (the user can provide their own toolchain to work that out if they wish), or warn the user to set it to both.

The only case where I could see this working properly is when the only package provided by conan is the sysroot itself, and the sysroot contains everything and no individual libraries are provided as conan packages.

The provided example is fine and valid, but in the situation described, both are an error for `find_library(LIBREADLINE "libreadline.so")` 
* if it is not in the sysroot, error out early (the desired outcome)
* if it found in the build machine, it will error out late (and attempt a link against the wrong one)

Obviously I can see how erroring out early is much preferable, as it would point you to arrive at the solution sooner - but once the underlying problem is addressed (`libreadline.so` is present in the sysroot), it _will_ work correctly even with the current Conan behaviour.

> If I remember correctly, if `CMAKE_FIND_ROOT_PATH_MODE_{LIBRARY,INCLUDE,PACKAGE}` is set to `ONLY`, and there is a `CMAKE_SYSROOT` defined, none of the calls to `find_package`/`find_library`/`find_program` will work to locate anything provided by Conan - the entire search path, incl. `CMAKE_PREFIX_PATH` and so on, will be re-rooted to the sysroot), and none of the relevant locations will actually be considered.

This is true, but only because Conan does not currently set `CMAKE_FIND_ROOT_PATH`.

> The provided example is fine and valid, but in the situation described, both are an error for `find_library(LIBREADLINE "libreadline.so")`
> 
> * if it is not in the sysroot, error out early (the desired outcome)
> * if it found in the build machine, it will error out late (and attempt a link against the wrong one)

No, this is not a given. For example, I'm in a situation where I'm cross-compiling with build=x86_64-linux-gnu and host=x86_64-linux-gnu, but they're different systems with different Linux distributions, different toolchains, and different versions of glibc etc. Even though it may happen to link without errors, linking to binaries from the build system will still result in binaries that do not run once deployed on the host system. Or even worse: it may appear to run correctly in most cases, but ABI incompatibilities or ODR violations cause it to crash sporadically or make it exploitable to bad actors.

Second, when cross-compiling, one often prepares a sysroot with specific versions of packages. If for some reason, CMake is unable to find the intended package in the sysroot (e.g. because of a typo in the paths provided by the user), or it is unable to find the Conan-provided package, CMake should should fail, not silently link to a random version of the package it picked up in a `/opt/side-projects/thirdparty/libfoo-master` folder that happened to be in the build system's `PATH`.

adding before or after line 89
```
set_target_properties(${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${CONAN_FOUND_LIBRARY} IMPORTED_NO_SONAME ${no_soname_mode})
```
Fixes the issue.

I guess this means IMPORTED_LOCATION needs to be set for any IMPORTED target, and setting its _CONFIG specification does not cancel the need to set it? Or am I missing a method of choosing the IMPORTED_CONFIGURATION?

Edit: this seems to be related to https://github.com/conan-io/conan/issues/14606

With conan 2.0.4 it is working, seems this was changed in
https://github.com/conan-io/conan/commit/113cf5a2875ff3f9e77981aa178772090f4680f4

Some remarks in the connected issue https://github.com/conan-io/conan/issues/13504 seem to be wrong on linux, like

"The right thing is to not set IMPORTED_LOCATION at all.

Instead IMPORTED_LOCATION_DEBUG or IMPORTED_LOCATION_RELEASE shall be set to the Library for LIBRARY targets and to the dll (or so) for a shared library. For the latter IMPORTED_IMPLIB_DEBUG or IMPORTED_IMPLIB_RELEASE has to be set to the library. IMPORTED_LOCATION and IMPORTED_IMPLIB will then be automatically determined by cmake."

This is not happening, but cmake complains about IMPORTED_LOCATION being undefined.

13504 is about windows but it seems to create a problem on Linux, could this be due to single-target generator on linux and multi-target-generator on windows?
You misread the explanation of [CMP0111](https://cmake.org/cmake/help/latest/policy/CMP0111.html) in the CMake documentation. To quote (emphasis mine):

> Imported Targets for library files and executables require that their location on disk is specified in a target property such as IMPORTED_LOCATION, IMPORTED_IMPLIB, **or a per-configuration equivalent.**

If configuration-specific locations are set, IMPORTED_LOCATION doesn't have to be set.

I don't know why you're getting the CMake warning, it might be due to a conan bug, but setting IMPORTED_LOCATION isn't the correct fix even if it is a conan bug.


**"or a per-configuration equivalent."** this seems to be only true under certain conditions. 

After some testing I observed cmake won't throw CMP0111 when

1) When IMPORTED_LOCATION is set as explained above. 

2) If the available CONFIGURATIONS_TYPES are set, above line 89
```
set_property(TARGET ${_LIB_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS <config>)
```
As explained in https://github.com/conan-io/conan/issues/14606

Following this it seems only when a target has its IMPORTED_CONFIGURATIONS property set will cmake accept IMPORTED_LOCATION_CONFIG instead of the configuration-less IMPORTED_LOCATION, otherwise one is getting CMP0111












Patch:
diff --git a/conan/cps/cps.py b/conan/cps/cps.py
index 67007d8570a..621a387ce27 100644
--- a/conan/cps/cps.py
+++ b/conan/cps/cps.py
@@ -85,7 +85,7 @@ def from_cpp_info(cpp_info, pkg_type, libname=None):
             cps_comp.type = CPSComponentType.INTERFACE
             return cps_comp
 
-        cpp_info.deduce_cps(pkg_type)
+        cpp_info.deduce_locations(pkg_type)
         cps_comp.type = CPSComponentType.from_conan(cpp_info.type)
         cps_comp.location = cpp_info.location
         cps_comp.link_location = cpp_info.link_location
diff --git a/conan/tools/cmake/__init__.py b/conan/tools/cmake/__init__.py
index d4123be7493..73c8a835b08 100644
--- a/conan/tools/cmake/__init__.py
+++ b/conan/tools/cmake/__init__.py
@@ -1,4 +1,14 @@
 from conan.tools.cmake.toolchain.toolchain import CMakeToolchain
 from conan.tools.cmake.cmake import CMake
-from conan.tools.cmake.cmakedeps.cmakedeps import CMakeDeps
 from conan.tools.cmake.layout import cmake_layout
+
+
+def CMakeDeps(conanfile):  # noqa
+    if conanfile.conf.get("tools.cmake.cmakedeps:new", choices=["will_break_next"]):
+        from conan.tools.cmake.cmakedeps2.cmakedeps import CMakeDeps2
+        conanfile.output.warning("Using the new CMakeDeps generator, behind the "
+                                 "'tools.cmake.cmakedeps:new' gate conf. This conf will change"
+                                 "next release, breaking, so use it only for testing and dev")
+        return CMakeDeps2(conanfile)
+    from conan.tools.cmake.cmakedeps.cmakedeps import CMakeDeps as _CMakeDeps
+    return _CMakeDeps(conanfile)
diff --git a/conan/tools/cmake/cmakedeps2/__init__.py b/conan/tools/cmake/cmakedeps2/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/conan/tools/cmake/cmakedeps2/cmakedeps.py b/conan/tools/cmake/cmakedeps2/cmakedeps.py
new file mode 100644
index 00000000000..b92e8276ecb
--- /dev/null
+++ b/conan/tools/cmake/cmakedeps2/cmakedeps.py
@@ -0,0 +1,211 @@
+import os
+import re
+import textwrap
+
+from jinja2 import Template
+
+from conan.internal import check_duplicated_generator
+from conan.tools.cmake.cmakedeps2.config import ConfigTemplate2
+from conan.tools.cmake.cmakedeps2.config_version import ConfigVersionTemplate2
+from conan.tools.cmake.cmakedeps2.target_configuration import TargetConfigurationTemplate2
+from conan.tools.cmake.cmakedeps2.targets import TargetsTemplate2
+from conan.tools.files import save
+from conan.errors import ConanException
+from conans.model.dependencies import get_transitive_requires
+from conans.util.files import load
+
+FIND_MODE_MODULE = "module"
+FIND_MODE_CONFIG = "config"
+FIND_MODE_NONE = "none"
+FIND_MODE_BOTH = "both"
+
+
+class CMakeDeps2:
+
+    def __init__(self, conanfile):
+        self._conanfile = conanfile
+        self.configuration = str(self._conanfile.settings.build_type)
+
+        # These are just for legacy compatibility, but not use at al
+        self.build_context_activated = []
+        self.build_context_build_modules = []
+        self.build_context_suffix = {}
+        # Enable/Disable checking if a component target exists or not
+        self.check_components_exist = False
+
+        self._properties = {}
+
+    def generate(self):
+        check_duplicated_generator(self, self._conanfile)
+        # Current directory is the generators_folder
+        generator_files = self._content()
+        for generator_file, content in generator_files.items():
+            save(self._conanfile, generator_file, content)
+        _PathGenerator(self, self._conanfile).generate()
+
+    def _content(self):
+        host_req = self._conanfile.dependencies.host
+        build_req = self._conanfile.dependencies.direct_build
+        test_req = self._conanfile.dependencies.test
+
+        # Iterate all the transitive requires
+        ret = {}
+        for require, dep in list(host_req.items()) + list(build_req.items()) + list(test_req.items()):
+            cmake_find_mode = self.get_property("cmake_find_mode", dep)
+            cmake_find_mode = cmake_find_mode or FIND_MODE_CONFIG
+            cmake_find_mode = cmake_find_mode.lower()
+            if cmake_find_mode == FIND_MODE_NONE:
+                continue
+
+            config = ConfigTemplate2(self, dep)
+            ret[config.filename] = config.content()
+            config_version = ConfigVersionTemplate2(self, dep)
+            ret[config_version.filename] = config_version.content()
+
+            targets = TargetsTemplate2(self, dep)
+            ret[targets.filename] = targets.content()
+            target_configuration = TargetConfigurationTemplate2(self, dep, require)
+            ret[target_configuration.filename] = target_configuration.content()
+        return ret
+
+    def set_property(self, dep, prop, value, build_context=False):
+        """
+        Using this method you can overwrite the :ref:`property<CMakeDeps Properties>` values set by
+        the Conan recipes from the consumer.
+
+        :param dep: Name of the dependency to set the :ref:`property<CMakeDeps Properties>`. For
+         components use the syntax: ``dep_name::component_name``.
+        :param prop: Name of the :ref:`property<CMakeDeps Properties>`.
+        :param value: Value of the property. Use ``None`` to invalidate any value set by the
+         upstream recipe.
+        :param build_context: Set to ``True`` if you want to set the property for a dependency that
+         belongs to the build context (``False`` by default).
+        """
+        build_suffix = "&build" if build_context else ""
+        self._properties.setdefault(f"{dep}{build_suffix}", {}).update({prop: value})
+
+    def get_property(self, prop, dep, comp_name=None, check_type=None):
+        dep_name = dep.ref.name
+        build_suffix = "&build" if dep.context == "build" else ""
+        dep_comp = f"{str(dep_name)}::{comp_name}" if comp_name else f"{str(dep_name)}"
+        try:
+            value = self._properties[f"{dep_comp}{build_suffix}"][prop]
+            if check_type is not None and not isinstance(value, check_type):
+                raise ConanException(f'The expected type for {prop} is "{check_type.__name__}", '
+                                     f'but "{type(value).__name__}" was found')
+            return value
+        except KeyError:
+            # Here we are not using the cpp_info = deduce_cpp_info(dep) because it is not
+            # necessary for the properties
+            return dep.cpp_info.get_property(prop, check_type=check_type) if not comp_name \
+                else dep.cpp_info.components[comp_name].get_property(prop, check_type=check_type)
+
+    def get_cmake_filename(self, dep, module_mode=None):
+        """Get the name of the file for the find_package(XXX)"""
+        # This is used by CMakeDeps to determine:
+        # - The filename to generate (XXX-config.cmake or FindXXX.cmake)
+        # - The name of the defined XXX_DIR variables
+        # - The name of transitive dependencies for calls to find_dependency
+        if module_mode and self._get_find_mode(dep) in [FIND_MODE_MODULE, FIND_MODE_BOTH]:
+            ret = self.get_property("cmake_module_file_name", dep)
+            if ret:
+                return ret
+        ret = self.get_property("cmake_file_name", dep)
+        return ret or dep.ref.name
+
+    def _get_find_mode(self, dep):
+        """
+        :param dep: requirement
+        :return: "none" or "config" or "module" or "both" or "config" when not set
+        """
+        tmp = self.get_property("cmake_find_mode", dep)
+        if tmp is None:
+            return "config"
+        return tmp.lower()
+
+    def get_transitive_requires(self, conanfile):
+        # Prepared to filter transitive tool-requires with visible=True
+        return get_transitive_requires(self._conanfile, conanfile)
+
+
+class _PathGenerator:
+    _conan_cmakedeps_paths = "conan_cmakedeps_paths.cmake"
+
+    def __init__(self, cmakedeps, conanfile):
+        self._conanfile = conanfile
+        self._cmakedeps = cmakedeps
+
+    def generate(self):
+        template = textwrap.dedent("""\
+            {% for pkg_name, folder in pkg_paths.items() %}
+            set({{pkg_name}}_DIR "{{folder}}")
+            {% endfor %}
+            {% if host_runtime_dirs %}
+            set(CONAN_RUNTIME_LIB_DIRS {{ host_runtime_dirs }} )
+            {% endif %}
+            """)
+
+        host_req = self._conanfile.dependencies.host
+        build_req = self._conanfile.dependencies.direct_build
+        test_req = self._conanfile.dependencies.test
+
+        # gen_folder = self._conanfile.generators_folder.replace("\\", "/")
+        # if not, test_cmake_add_subdirectory test fails
+        # content.append('set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)')
+        pkg_paths = {}
+        for req, dep in list(host_req.items()) + list(build_req.items()) + list(test_req.items()):
+            cmake_find_mode = self._cmakedeps.get_property("cmake_find_mode", dep)
+            cmake_find_mode = cmake_find_mode or FIND_MODE_CONFIG
+            cmake_find_mode = cmake_find_mode.lower()
+
+            pkg_name = self._cmakedeps.get_cmake_filename(dep)
+            # https://cmake.org/cmake/help/v3.22/guide/using-dependencies/index.html
+            if cmake_find_mode == FIND_MODE_NONE:
+                try:
+                    # This is irrespective of the components, it should be in the root cpp_info
+                    # To define the location of the pkg-config.cmake file
+                    build_dir = dep.cpp_info.builddirs[0]
+                except IndexError:
+                    build_dir = dep.package_folder
+                pkg_folder = build_dir.replace("\\", "/") if build_dir else None
+                if pkg_folder:
+                    config_file = ConfigTemplate2(self._cmakedeps, dep).filename
+                    if os.path.isfile(os.path.join(pkg_folder, config_file)):
+                        pkg_paths[pkg_name] = pkg_folder
+                continue
+
+            # If CMakeDeps generated, the folder is this one
+            # content.append(f'set({pkg_name}_ROOT "{gen_folder}")')
+            pkg_paths[pkg_name] = "${CMAKE_CURRENT_LIST_DIR}"
+
+        context = {"host_runtime_dirs": self._get_host_runtime_dirs(),
+                   "pkg_paths": pkg_paths}
+        content = Template(template, trim_blocks=True, lstrip_blocks=True).render(context)
+        save(self._conanfile, self._conan_cmakedeps_paths, content)
+
+    def _get_host_runtime_dirs(self):
+        host_runtime_dirs = {}
+
+        # Get the previous configuration
+        if os.path.exists(self._conan_cmakedeps_paths):
+            existing_toolchain = load(self._conan_cmakedeps_paths)
+            pattern_lib_dirs = r"set\(CONAN_RUNTIME_LIB_DIRS ([^)]*)\)"
+            variable_match = re.search(pattern_lib_dirs, existing_toolchain)
+            if variable_match:
+                capture = variable_match.group(1)
+                matches = re.findall(r'"\$<\$<CONFIG:([A-Za-z]*)>:([^>]*)>"', capture)
+                for config, paths in matches:
+                    host_runtime_dirs.setdefault(config, []).append(paths)
+
+        is_win = self._conanfile.settings.get_safe("os") == "Windows"
+        for req in self._conanfile.dependencies.host.values():
+            config = req.settings.get_safe("build_type", self._cmakedeps.configuration)
+            aggregated_cppinfo = req.cpp_info.aggregated_components()
+            runtime_dirs = aggregated_cppinfo.bindirs if is_win else aggregated_cppinfo.libdirs
+            for d in runtime_dirs:
+                d = d.replace("\\", "/")
+                existing = host_runtime_dirs.setdefault(config, [])
+                if d not in existing:
+                    existing.append(d)
+
+        return ' '.join(f'"$<$<CONFIG:{c}>:{i}>"' for c, v in host_runtime_dirs.items() for i in v)
diff --git a/conan/tools/cmake/cmakedeps2/config.py b/conan/tools/cmake/cmakedeps2/config.py
new file mode 100644
index 00000000000..459d3b42171
--- /dev/null
+++ b/conan/tools/cmake/cmakedeps2/config.py
@@ -0,0 +1,61 @@
+import textwrap
+
+import jinja2
+from jinja2 import Template
+
+
+class ConfigTemplate2:
+    """
+    FooConfig.cmake
+    foo-config.cmake
+    """
+    def __init__(self, cmakedeps, conanfile):
+        self._cmakedeps = cmakedeps
+        self._conanfile = conanfile
+
+    def content(self):
+        t = Template(self._template, trim_blocks=True, lstrip_blocks=True,
+                     undefined=jinja2.StrictUndefined)
+        return t.render(self._context)
+
+    @property
+    def filename(self):
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        return f"{f}-config.cmake" if f == f.lower() else f"{f}Config.cmake"
+
+    @property
+    def _context(self):
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        targets_include = f"{f}Targets.cmake"
+        pkg_name = self._conanfile.ref.name
+        build_modules_paths = self._cmakedeps.get_property("cmake_build_modules", self._conanfile,
+                                                           check_type=list) or []
+        # FIXME: Proper escaping of paths for CMake and relativization
+        # FIXME: build_module_paths coming from last config only
+        build_modules_paths = [f.replace("\\", "/") for f in build_modules_paths]
+        return {"pkg_name": pkg_name,
+                "targets_include_file": targets_include,
+                "build_modules_paths": build_modules_paths}
+
+    @property
+    def _template(self):
+        return textwrap.dedent("""\
+        # Requires CMake > 3.15
+        if(${CMAKE_VERSION} VERSION_LESS "3.15")
+            message(FATAL_ERROR "The 'CMakeDeps' generator only works with CMake >= 3.15")
+        endif()
+
+        include(${CMAKE_CURRENT_LIST_DIR}/{{ targets_include_file }})
+
+        get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+        if(NOT isMultiConfig AND NOT CMAKE_BUILD_TYPE)
+           message(FATAL_ERROR "Please, set the CMAKE_BUILD_TYPE variable when calling to CMake "
+                               "adding the '-DCMAKE_BUILD_TYPE=<build_type>' argument.")
+        endif()
+
+        # build_modules_paths comes from last configuration only
+        {% for build_module in build_modules_paths %}
+        message(STATUS "Conan: Including build module from '{{build_module}}'")
+        include("{{ build_module }}")
+        {% endfor %}
+        """)
diff --git a/conan/tools/cmake/cmakedeps2/config_version.py b/conan/tools/cmake/cmakedeps2/config_version.py
new file mode 100644
index 00000000000..4a3212ba21c
--- /dev/null
+++ b/conan/tools/cmake/cmakedeps2/config_version.py
@@ -0,0 +1,102 @@
+import textwrap
+
+import jinja2
+from jinja2 import Template
+
+from conan.errors import ConanException
+
+
+class ConfigVersionTemplate2:
+    """
+    foo-config-version.cmake
+    """
+    def __init__(self, cmakedeps, conanfile):
+        self._cmakedeps = cmakedeps
+        self._conanfile = conanfile
+
+    def content(self):
+        t = Template(self._template, trim_blocks=True, lstrip_blocks=True,
+                     undefined=jinja2.StrictUndefined)
+        return t.render(self._context)
+
+    @property
+    def filename(self):
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        return  f"{f}-config-version.cmake" if f == f.lower() else f"{f}ConfigVersion.cmake"
+
+    @property
+    def _context(self):
+        policy = self._cmakedeps.get_property("cmake_config_version_compat", self._conanfile)
+        if policy is None:
+            policy = "SameMajorVersion"
+        if policy not in ("AnyNewerVersion", "SameMajorVersion", "SameMinorVersion", "ExactVersion"):
+            raise ConanException(f"Unknown cmake_config_version_compat={policy} in {self._conanfile}")
+        version = self._cmakedeps.get_property("system_package_version", self._conanfile)
+        version = version or self._conanfile.ref.version
+        return {"version": version,
+                "policy": policy}
+
+    @property
+    def _template(self):
+        # https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
+        # This will be at XXX-config-version.cmake
+        # AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion
+        ret = textwrap.dedent("""\
+            set(PACKAGE_VERSION "{{ version }}")
+
+            if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
+                set(PACKAGE_VERSION_COMPATIBLE FALSE)
+            else()
+                {% if policy == "AnyNewerVersion" %}
+                set(PACKAGE_VERSION_COMPATIBLE TRUE)
+                {% elif policy == "SameMajorVersion" %}
+                if("{{ version }}" MATCHES "^([0-9]+)\\\\.")
+                    set(CVF_VERSION_MAJOR {{ '${CMAKE_MATCH_1}' }})
+                else()
+                    set(CVF_VERSION_MAJOR "{{ version }}")
+                endif()
+
+                if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
+                    set(PACKAGE_VERSION_COMPATIBLE TRUE)
+                else()
+                    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+                endif()
+                {% elif policy == "SameMinorVersion" %}
+                if("{{ version }}" MATCHES "^([0-9]+)\\.([0-9]+)")
+                    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
+                    set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
+                else()
+                    set(CVF_VERSION_MAJOR "{{ version }}")
+                    set(CVF_VERSION_MINOR "")
+                endif()
+                if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND
+                    (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR))
+                  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+                else()
+                  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+                endif()
+                {% elif policy == "ExactVersion" %}
+                if("{{ version }}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
+                    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
+                    set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
+                    set(CVF_VERSION_MINOR "${CMAKE_MATCH_3}")
+                else()
+                    set(CVF_VERSION_MAJOR "{{ version }}")
+                    set(CVF_VERSION_MINOR "")
+                    set(CVF_VERSION_PATCH "")
+                endif()
+                if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND
+                    (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR) AND
+                    (PACKAGE_FIND_VERSION_PATCH STREQUAL CVF_VERSION_PATCH))
+                  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+                else()
+                  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+                endif()
+                {% endif %}
+
+                if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
+                    set(PACKAGE_VERSION_EXACT TRUE)
+                endif()
+            endif()
+            """)
+        return ret
diff --git a/conan/tools/cmake/cmakedeps2/target_configuration.py b/conan/tools/cmake/cmakedeps2/target_configuration.py
new file mode 100644
index 00000000000..5d8c2150413
--- /dev/null
+++ b/conan/tools/cmake/cmakedeps2/target_configuration.py
@@ -0,0 +1,384 @@
+import os
+import textwrap
+
+import jinja2
+from jinja2 import Template
+
+from conan.errors import ConanException
+from conans.client.graph.graph import CONTEXT_BUILD, CONTEXT_HOST
+from conans.model.pkg_type import PackageType
+
+
+class TargetConfigurationTemplate2:
+    """
+    FooTarget-release.cmake
+    """
+    def __init__(self, cmakedeps, conanfile, require):
+        self._cmakedeps = cmakedeps
+        self._conanfile = conanfile  # The dependency conanfile, not the consumer one
+        self._require = require
+
+    def content(self):
+        t = Template(self._template, trim_blocks=True, lstrip_blocks=True,
+                     undefined=jinja2.StrictUndefined)
+        return t.render(self._context)
+
+    @property
+    def filename(self):
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        # Fallback to consumer configuration if it doesn't have build_type
+        config = self._conanfile.settings.get_safe("build_type", self._cmakedeps.configuration)
+        config = (config or "none").lower()
+        build = "Build" if self._conanfile.context == CONTEXT_BUILD else ""
+        return f"{f}-Targets{build}-{config}.cmake"
+
+    def _requires(self, info, components):
+        result = []
+        requires = info.parsed_requires()
+        pkg_name = self._conanfile.ref.name
+        transitive_reqs = self._cmakedeps.get_transitive_requires(self._conanfile)
+        if not requires and not components:  # global cpp_info without components definition
+            # require the pkgname::pkgname base (user defined) or INTERFACE base target
+            return [f"{d.ref.name}::{d.ref.name}" for d in transitive_reqs.values()]
+
+        for required_pkg, required_comp in requires:
+            if required_pkg is None:  # Points to a component of same package
+                dep_comp = components.get(required_comp)
+                assert dep_comp, f"Component {required_comp} not found in {self._conanfile}"
+                dep_target = self._cmakedeps.get_property("cmake_target_name", self._conanfile,
+                                                          required_comp)
+                dep_target = dep_target or f"{pkg_name}::{required_comp}"
+                result.append(dep_target)
+            else:  # Different package
+                try:
+                    dep = transitive_reqs[required_pkg]
+                except KeyError:  # The transitive dep might have been skipped
+                    pass
+                else:
+                    # To check if the component exist, it is ok to use the standard cpp_info
+                    # No need to use the cpp_info = deduce_cpp_info(dep)
+                    dep_comp = dep.cpp_info.components.get(required_comp)
+                    if dep_comp is None:
+                        # It must be the interface pkgname::pkgname target
+                        assert required_pkg == required_comp
+                        comp = None
+                    else:
+                        comp = required_comp
+                    dep_target = self._cmakedeps.get_property("cmake_target_name", dep, comp)
+                    dep_target = dep_target or f"{required_pkg}::{required_comp}"
+                    result.append(dep_target)
+        return result
+
+    @property
+    def _context(self):
+        cpp_info = self._conanfile.cpp_info.deduce_full_cpp_info(self._conanfile)
+        pkg_name = self._conanfile.ref.name
+        # fallback to consumer configuration if it doesn't have build_type
+        config = self._conanfile.settings.get_safe("build_type", self._cmakedeps.configuration)
+        config = config.upper() if config else None
+        pkg_folder = self._conanfile.package_folder.replace("\\", "/")
+        config_folder = f"_{config}" if config else ""
+        build = "_BUILD" if self._conanfile.context == CONTEXT_BUILD else ""
+        pkg_folder_var = f"{pkg_name}_PACKAGE_FOLDER{config_folder}{build}"
+
+        libs = {}
+        # The BUILD context does not generate libraries targets atm
+        if self._conanfile.context == CONTEXT_HOST:
+            libs = self._get_libs(cpp_info, pkg_name, pkg_folder, pkg_folder_var)
+            self._add_root_lib_target(libs, pkg_name, cpp_info)
+        exes = self._get_exes(cpp_info, pkg_name, pkg_folder, pkg_folder_var)
+
+        prefixes = self._cmakedeps.get_property("cmake_additional_variables_prefixes",
+                                                self._conanfile, check_type=list) or []
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        prefixes = [f] + prefixes
+        include_dirs = definitions = libraries = None
+        if not self._require.build:  # To add global variables for try_compile and legacy
+            aggregated_cppinfo = cpp_info.aggregated_components()
+            # FIXME: Proper escaping of paths for CMake and relativization
+            include_dirs = ";".join(i.replace("\\", "/") for i in aggregated_cppinfo.includedirs)
+            definitions = ""
+            root_target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile)
+            libraries = root_target_name or f"{pkg_name}::{pkg_name}"
+
+        # TODO: Missing find_modes
+        dependencies = self._get_dependencies()
+        return {"dependencies": dependencies,
+                "pkg_folder": pkg_folder,
+                "pkg_folder_var": pkg_folder_var,
+                "config": config,
+                "exes": exes,
+                "libs": libs,
+                "context": self._conanfile.context,
+                # Extra global variables
+                "additional_variables_prefixes": prefixes,
+                "version": self._conanfile.ref.version,
+                "include_dirs": include_dirs,
+                "definitions": definitions,
+                "libraries": libraries
+                }
+
+    def _get_libs(self, cpp_info, pkg_name, pkg_folder, pkg_folder_var) -> dict:
+        libs = {}
+        if cpp_info.has_components:
+            for name, component in cpp_info.components.items():
+                target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile,
+                                                           name)
+                target_name = target_name or f"{pkg_name}::{name}"
+                target = self._get_cmake_lib(component, cpp_info.components, pkg_folder,
+                                             pkg_folder_var)
+                if target is not None:
+                    libs[target_name] = target
+        else:
+            target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile)
+            target_name = target_name or f"{pkg_name}::{pkg_name}"
+            target = self._get_cmake_lib(cpp_info, None, pkg_folder, pkg_folder_var)
+            if target is not None:
+                libs[target_name] = target
+        return libs
+
+    def _get_cmake_lib(self, info, components, pkg_folder, pkg_folder_var):
+        if info.exe or not (info.includedirs or info.libs):
+            return
+
+        includedirs = ";".join(self._path(i, pkg_folder, pkg_folder_var)
+                               for i in info.includedirs) if info.includedirs else ""
+        requires = " ".join(self._requires(info, components))
+        defines = " ".join(info.defines)
+        # TODO: Missing escaping?
+        # TODO: Missing link language
+        # FIXME: Filter by lib traits!!!!!
+        if not self._require.headers:  # If not depending on headers, paths and
+            includedirs = defines = None
+        system_libs = " ".join(info.system_libs)
+        target = {"type": "INTERFACE",
+                  "includedirs": includedirs,
+                  "defines": defines,
+                  "requires": requires,
+                  "cxxflags": " ".join(info.cxxflags),
+                  "cflags": " ".join(info.cflags),
+                  "sharedlinkflags": " ".join(info.sharedlinkflags),
+                  "exelinkflags": " ".join(info.exelinkflags),
+                  "system_libs": system_libs}
+
+        if info.frameworks:
+            self._conanfile.output.warning("frameworks not supported yet in new CMakeDeps generator")
+
+        if info.libs:
+            if len(info.libs) != 1:
+                raise ConanException(f"New CMakeDeps only allows 1 lib per component:\n"
+                                     f"{self._conanfile}: {info.libs}")
+            assert info.location, "info.location missing for .libs, it should have been deduced"
+            location = self._path(info.location, pkg_folder, pkg_folder_var)
+            link_location = self._path(info.link_location, pkg_folder, pkg_folder_var) \
+                if info.link_location else None
+            lib_type = "SHARED" if info.type is PackageType.SHARED else \
+                "STATIC" if info.type is PackageType.STATIC else None
+            assert lib_type, f"Unknown package type {info.type}"
+            target["type"] = lib_type
+            target["location"] = location
+            target["link_location"] = link_location
+            link_languages = info.languages or self._conanfile.languages or []
+            link_languages = ["CXX" if c == "C++" else c for c in link_languages]
+            target["link_languages"] = link_languages
+
+        return target
+
+    def _add_root_lib_target(self, libs, pkg_name, cpp_info):
+        """
+        Addd a new pkgname::pkgname INTERFACE target that depends on default_components or
+        on all other library targets (not exes)
+        It will not be added if there exists already a pkgname::pkgname target.
+        """
+        root_target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile)
+        root_target_name = root_target_name or f"{pkg_name}::{pkg_name}"
+        if libs and root_target_name not in libs:
+            # Add a generic interface target for the package depending on the others
+            if cpp_info.default_components is not None:
+                all_requires = []
+                for defaultc in cpp_info.default_components:
+                    target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile,
+                                                               defaultc)
+                    comp_name = target_name or f"{pkg_name}::{defaultc}"
+                    all_requires.append(comp_name)
+                all_requires = " ".join(all_requires)
+            else:
+                all_requires = " ".join(libs.keys())
+            libs[root_target_name] = {"type": "INTERFACE",
+                                      "requires": all_requires}
+
+    def _get_exes(self, cpp_info, pkg_name, pkg_folder, pkg_folder_var):
+        exes = {}
+
+        if cpp_info.has_components:
+            assert not cpp_info.exe, "Package has components and exe"
+            assert not cpp_info.libs, "Package has components and libs"
+            for name, comp in cpp_info.components.items():
+                if comp.exe or comp.type is PackageType.APP:
+                    target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile,
+                                                               name)
+                    target = target_name or f"{pkg_name}::{name}"
+                    exe_location = self._path(comp.location, pkg_folder, pkg_folder_var)
+                    exes[target] = exe_location
+        else:
+            if cpp_info.exe:
+                assert not cpp_info.libs, "Package has exe and libs"
+                assert cpp_info.location, "Package has exe and no location"
+                target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile)
+                target = target_name or f"{pkg_name}::{pkg_name}"
+                exe_location = self._path(cpp_info.location, pkg_folder, pkg_folder_var)
+                exes[target] = exe_location
+
+        return exes
+
+    def _get_dependencies(self):
+        """ transitive dependencies Filenames for find_dependency()
+        """
+        # Build requires are already filtered by the get_transitive_requires
+        transitive_reqs = self._cmakedeps.get_transitive_requires(self._conanfile)
+        # FIXME: Hardcoded CONFIG
+        ret = {self._cmakedeps.get_cmake_filename(r): "CONFIG" for r in transitive_reqs.values()}
+        return ret
+
+    @staticmethod
+    def _path(p, pkg_folder, pkg_folder_var):
+        def escape(p_):
+            return p_.replace("$", "\\$").replace('"', '\\"')
+
+        p = p.replace("\\", "/")
+        if os.path.isabs(p):
+            if p.startswith(pkg_folder):
+                rel = p[len(pkg_folder):].lstrip("/")
+                return f"${{{pkg_folder_var}}}/{escape(rel)}"
+            return escape(p)
+        return f"${{{pkg_folder_var}}}/{escape(p)}"
+
+    @staticmethod
+    def _escape_cmake_string(values):
+        return " ".join(v.replace("\\", "\\\\").replace('$', '\\$').replace('"', '\\"')
+                        for v in values)
+
+    @property
+    def _template(self):
+        # TODO: Check why not set_property instead of target_link_libraries
+        return textwrap.dedent("""\
+        {%- macro config_wrapper(config, value) -%}
+             {% if config -%}
+             $<$<CONFIG:{{config}}>:{{value}}>
+             {%- else -%}
+             {{value}}
+             {%- endif %}
+        {%- endmacro -%}
+        set({{pkg_folder_var}} "{{pkg_folder}}")
+
+        # Dependencies finding
+        include(CMakeFindDependencyMacro)
+
+        {% for dep, dep_find_mode in dependencies.items() %}
+        if(NOT {{dep}}_FOUND)
+            find_dependency({{dep}} REQUIRED {{dep_find_mode}})
+        endif()
+        {% endfor %}
+
+        ################# Libs information ##############
+        {% for lib, lib_info in libs.items() %}
+        #################### {{lib}} ####################
+        if(NOT TARGET {{ lib }})
+            message(STATUS "Conan: Target declared imported {{lib_info["type"]}} library '{{lib}}'")
+            add_library({{lib}} {{lib_info["type"]}} IMPORTED)
+        endif()
+        {% if lib_info.get("includedirs") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+                     {{config_wrapper(config, lib_info["includedirs"])}})
+        {% endif %}
+        {% if lib_info.get("defines") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS
+                     {{config_wrapper(config, lib_info["defines"])}})
+        {% endif %}
+        {% if lib_info.get("cxxflags") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS
+                     $<$<COMPILE_LANGUAGE:CXX>:{{config_wrapper(config, lib_info["cxxflags"])}}>)
+        {% endif %}
+        {% if lib_info.get("cflags") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS
+                     $<$<COMPILE_LANGUAGE:C>:{{config_wrapper(config, lib_info["cflags"])}}>)
+        {% endif %}
+        {% if lib_info.get("sharedlinkflags") %}
+        {% set linkflags = config_wrapper(config, lib_info["sharedlinkflags"]) %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_LINK_OPTIONS
+                     "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:{{linkflags}}>"
+                     "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:{{linkflags}}>")
+        {% endif %}
+        {% if lib_info.get("exelinkflags") %}
+        {% set exeflags = config_wrapper(config, lib_info["exelinkflags"]) %}
+        set_property(TARGET {{lib}} APPEND PROPERTY INTERFACE_LINK_OPTIONS
+                     "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:{{exeflags}}>")
+        {% endif %}
+
+        {% if lib_info.get("link_languages") %}
+        get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
+        {% for lang in lib_info["link_languages"] %}
+        if(NOT "{{lang}}" IN_LIST _languages)
+            message(SEND_ERROR
+                    "Target {{lib}} has {{lang}} linkage but {{lang}} not enabled in project()")
+        endif()
+        set_property(TARGET {{lib}} APPEND PROPERTY
+                     IMPORTED_LINK_INTERFACE_LANGUAGES_{{config}} {{lang}})
+        {% endfor %}
+        {% endif %}
+        {% if lib_info.get("location") %}
+        set_property(TARGET {{lib}} APPEND PROPERTY IMPORTED_CONFIGURATIONS {{config}})
+        set_target_properties({{lib}} PROPERTIES IMPORTED_LOCATION_{{config}}
+                              "{{lib_info["location"]}}")
+        {% endif %}
+        {% if lib_info.get("link_location") %}
+        set_target_properties({{lib}} PROPERTIES IMPORTED_IMPLIB_{{config}}
+                              "{{lib_info["link_location"]}}")
+        {% endif %}
+        {% if lib_info.get("requires") %}
+        target_link_libraries({{lib}} INTERFACE {{lib_info["requires"]}})
+        {% endif %}
+        {% if lib_info.get("system_libs") %}
+        target_link_libraries({{lib}} INTERFACE {{lib_info["system_libs"]}})
+        {% endif %}
+
+        {% endfor %}
+
+        ################# Global variables for try compile and legacy ##############
+        {% for prefix in additional_variables_prefixes %}
+        set({{ prefix }}_VERSION_STRING "{{ version }}")
+        {% if include_dirs is not none %}
+        set({{ prefix }}_INCLUDE_DIRS "{{ include_dirs }}" )
+        set({{ prefix }}_INCLUDE_DIR "{{ include_dirs }}" )
+        {% endif %}
+        {% if libraries is not none %}
+        set({{ prefix }}_LIBRARIES {{ libraries }} )
+        {% endif %}
+        {% if definitions is not none %}
+        set({{ prefix }}_DEFINITIONS {{ definitions}} )
+        {% endif %}
+        {% endfor %}
+
+        ################# Exes information ##############
+        {% for exe, location in exes.items() %}
+        #################### {{exe}} ####################
+        if(NOT TARGET {{ exe }})
+            message(STATUS "Conan: Target declared imported executable '{{exe}}' {{context}}")
+            add_executable({{exe}} IMPORTED)
+        else()
+            get_property(_context TARGET {{exe}} PROPERTY CONAN_CONTEXT)
+            if(NOT $${_context} STREQUAL "{{context}}")
+                message(STATUS "Conan: Exe {{exe}} was already defined in ${_context}")
+                get_property(_configurations TARGET {{exe}} PROPERTY IMPORTED_CONFIGURATIONS)
+                message(STATUS "Conan: Exe {{exe}} defined configurations: ${_configurations}")
+                foreach(_config ${_configurations})
+                    set_property(TARGET {{exe}} PROPERTY IMPORTED_LOCATION_${_config})
+                endforeach()
+                set_property(TARGET {{exe}} PROPERTY IMPORTED_CONFIGURATIONS)
+            endif()
+        endif()
+        set_property(TARGET {{exe}} APPEND PROPERTY IMPORTED_CONFIGURATIONS {{config}})
+        set_target_properties({{exe}} PROPERTIES IMPORTED_LOCATION_{{config}} "{{location}}")
+        set_property(TARGET {{exe}} PROPERTY CONAN_CONTEXT "{{context}}")
+        {% endfor %}
+        """)
diff --git a/conan/tools/cmake/cmakedeps2/targets.py b/conan/tools/cmake/cmakedeps2/targets.py
new file mode 100644
index 00000000000..2b934f82502
--- /dev/null
+++ b/conan/tools/cmake/cmakedeps2/targets.py
@@ -0,0 +1,47 @@
+import textwrap
+
+import jinja2
+from jinja2 import Template
+
+
+class TargetsTemplate2:
+    """
+    FooTargets.cmake
+    """
+    def __init__(self, cmakedeps, conanfile):
+        self._cmakedeps = cmakedeps
+        self._conanfile = conanfile
+
+    def content(self):
+        t = Template(self._template, trim_blocks=True, lstrip_blocks=True,
+                     undefined=jinja2.StrictUndefined)
+        return t.render(self._context)
+
+    @property
+    def filename(self):
+        f = self._cmakedeps.get_cmake_filename(self._conanfile)
+        return f"{f}Targets.cmake"
+
+    @property
+    def _context(self):
+        filename = self._cmakedeps.get_cmake_filename(self._conanfile)
+        ret = {"ref": str(self._conanfile.ref),
+               "filename": filename}
+        return ret
+
+    @property
+    def _template(self):
+        return textwrap.dedent("""\
+            message(STATUS "Configuring Targets for {{ ref }}")
+
+            # Load information for each installed configuration.
+            file(GLOB _target_files "${CMAKE_CURRENT_LIST_DIR}/{{filename}}-Targets-*.cmake")
+            foreach(_target_file IN LISTS _target_files)
+              include("${_target_file}")
+            endforeach()
+
+            file(GLOB _build_files "${CMAKE_CURRENT_LIST_DIR}/{{filename}}-TargetsBuild-*.cmake")
+            foreach(_build_file IN LISTS _build_files)
+              include("${_build_file}")
+            endforeach()
+            """)
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index ca8a85e383b..e19b113a90f 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -520,6 +520,10 @@ def to_apple_archs(conanfile):
 class FindFiles(Block):
     template = textwrap.dedent("""\
         # Define paths to find packages, programs, libraries, etc.
+        if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/conan_cmakedeps_paths.cmake")
+          message(STATUS "Conan toolchain: Including CMakeDeps generated conan_find_paths.cmake")
+          include("${CMAKE_CURRENT_LIST_DIR}/conan_cmakedeps_paths.cmake")
+        else()
 
         {% if find_package_prefer_config %}
         set(CMAKE_FIND_PACKAGE_PREFER_CONFIG {{ find_package_prefer_config }})
@@ -578,6 +582,7 @@ class FindFiles(Block):
             set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH")
         endif()
         {% endif %}
+        endif()
     """)
 
     def _runtime_dirs_value(self, dirs):
diff --git a/conans/model/build_info.py b/conans/model/build_info.py
index 4505075e6a1..4b4ef9f334b 100644
--- a/conans/model/build_info.py
+++ b/conans/model/build_info.py
@@ -79,6 +79,8 @@ def __init__(self, set_defaults=False):
         self._sharedlinkflags = None  # linker flags
         self._exelinkflags = None  # linker flags
         self._objects = None  # linker flags
+        self._exe = None  # application executable, only 1 allowed, following CPS
+        self._languages = None
 
         self._sysroot = None
         self._requires = None
@@ -119,9 +121,11 @@ def serialize(self):
             "sysroot": self._sysroot,
             "requires": self._requires,
             "properties": self._properties,
+            "exe": self._exe,  # single exe, incompatible with libs
             "type": self._type,
             "location": self._location,
-            "link_location": self._link_location
+            "link_location": self._link_location,
+            "languages": self._languages
         }
 
     @staticmethod
@@ -131,6 +135,14 @@ def deserialize(contents):
             setattr(result, f"_{field}", value)
         return result
 
+    def clone(self):
+        # Necessary below for exploding a cpp_info.libs = [lib1, lib2] into components
+        result = _Component()
+        for k, v in vars(self).items():
+            if k.startswith("_"):
+                setattr(result, k, copy.copy(v))
+        return result
+
     @property
     def includedirs(self):
         if self._includedirs is None:
@@ -258,6 +270,14 @@ def libs(self):
     def libs(self, value):
         self._libs = value
 
+    @property
+    def exe(self):
+        return self._exe
+
+    @exe.setter
+    def exe(self, value):
+        self._exe = value
+
     @property
     def type(self):
         return self._type
@@ -282,6 +302,14 @@ def link_location(self):
     def link_location(self, value):
         self._link_location = value
 
+    @property
+    def languages(self):
+        return self._languages
+
+    @languages.setter
+    def languages(self, value):
+        self._languages = value
+
     @property
     def defines(self):
         if self._defines is None:
@@ -453,7 +481,9 @@ def relocate(el):
     def parsed_requires(self):
         return [r.split("::", 1) if "::" in r else (None, r) for r in self.requires]
 
-    def deduce_cps(self, pkg_type):
+    def deduce_locations(self, pkg_type):
+        if self._exe:   # exe is a new field, it should have the correct location
+            return
         if self._location or self._link_location:
             if self._type is None or self._type is PackageType.HEADER:
                 raise ConanException("Incorrect cpp_info defining location without type or header")
@@ -461,13 +491,16 @@ def deduce_cps(self, pkg_type):
         if self._type not in [None, PackageType.SHARED, PackageType.STATIC, PackageType.APP]:
             return
 
-        # Recipe didn't specify things, need to auto deduce
-        libdirs = [x.replace("\\", "/") for x in self.libdirs]
-        bindirs = [x.replace("\\", "/") for x in self.bindirs]
+        if len(self.libs) == 0:
+            return
 
         if len(self.libs) != 1:
             raise ConanException("More than 1 library defined in cpp_info.libs, cannot deduce CPS")
 
+        # Recipe didn't specify things, need to auto deduce
+        libdirs = [x.replace("\\", "/") for x in self.libdirs]
+        bindirs = [x.replace("\\", "/") for x in self.bindirs]
+
         # TODO: Do a better handling of pre-defined type
         libname = self.libs[0]
         static_patterns = [f"{libname}.lib", f"{libname}.a", f"lib{libname}.a"]
@@ -519,6 +552,7 @@ class CppInfo:
 
     def __init__(self, set_defaults=False):
         self.components = defaultdict(lambda: _Component(set_defaults))
+        self.default_components = None
         self._package = _Component(set_defaults)
 
     def __getattr__(self, attr):
@@ -526,19 +560,22 @@ def __getattr__(self, attr):
         return getattr(self._package, attr)
 
     def __setattr__(self, attr, value):
-        if attr in ("components", "_package", "_aggregated"):
+        if attr in ("components", "default_components", "_package", "_aggregated"):
             super(CppInfo, self).__setattr__(attr, value)
         else:
             setattr(self._package, attr, value)
 
     def serialize(self):
         ret = {"root": self._package.serialize()}
+        if self.default_components:
+            ret["default_components"] = self.default_components
         for component_name, info in self.components.items():
             ret[component_name] = info.serialize()
         return ret
 
     def deserialize(self, content):
         self._package = _Component.deserialize(content.pop("root"))
+        self.default_components = content.get("default_components")
         for component_name, info in content.items():
             self.components[component_name] = _Component.deserialize(info)
         return self
@@ -678,3 +715,37 @@ def required_components(self):
         # Then split the names
         ret = [r.split("::") if "::" in r else (None, r) for r in ret]
         return ret
+
+    def deduce_full_cpp_info(self, conanfile):
+        pkg_type = conanfile.package_type
+
+        result = CppInfo()  # clone it
+
+        if self.libs and len(self.libs) > 1:  # expand in multiple components
+            ConanOutput().warning(f"{conanfile}: The 'cpp_info.libs' contain more than 1 library. "
+                                  "Define 'cpp_info.components' instead.")
+            assert not self.components, f"{conanfile} cpp_info shouldn't have .libs and .components"
+            for lib in self.libs:
+                c = _Component()  # Do not do a full clone, we don't need the properties
+                c.type = self.type  # This should be a string
+                c.includedirs = self.includedirs
+                c.libdirs = self.libdirs
+                c.libs = [lib]
+                result.components[f"_{lib}"] = c
+
+            common = self._package.clone()
+            common.libs = []
+            common.type = str(PackageType.HEADER)  # the type of components is a string!
+            common.requires = list(result.components.keys()) + (self.requires or [])
+
+            result.components["_common"] = common
+        else:
+            result._package = self._package.clone()
+            result.default_components = self.default_components
+            result.components = {k: v.clone() for k, v in self.components.items()}
+
+        result._package.deduce_locations(pkg_type)
+        for comp in result.components.values():
+            comp.deduce_locations(pkg_type)
+
+        return result
diff --git a/conans/model/conf.py b/conans/model/conf.py
index cdbf0cb55cc..ebc41bc5885 100644
--- a/conans/model/conf.py
+++ b/conans/model/conf.py
@@ -80,6 +80,7 @@
     "tools.cmake.cmake_layout:build_folder": "(Experimental) Allow configuring the base folder of the build for local builds",
     "tools.cmake.cmake_layout:test_folder": "(Experimental) Allow configuring the base folder of the build for test_package",
     "tools.cmake:cmake_program": "Path to CMake executable",
+    "tools.cmake.cmakedeps:new": "Use the new CMakeDeps generator",
     "tools.cmake:install_strip": "Add --strip to cmake.install()",
     "tools.deployer:symlinks": "Set to False to disable deployers copying symlinks",
     "tools.files.download:retry": "Number of retries in case of failure when downloading",


Test patch:
diff --git a/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new.py b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new.py
new file mode 100644
index 00000000000..e2c3a84bea9
--- /dev/null
+++ b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new.py
@@ -0,0 +1,1104 @@
+import os
+import platform
+import re
+import textwrap
+
+import pytest
+
+from conan.test.assets.genconanfile import GenConanfile
+from conan.test.assets.sources import gen_function_h, gen_function_cpp
+from conan.test.utils.tools import TestClient
+
+
+new_value = "will_break_next"
+
+
+@pytest.mark.tool("cmake")
+class TestExes:
+    @pytest.mark.parametrize("tool_requires", [False, True])
+    def test_exe(self, tool_requires):
+        conanfile = textwrap.dedent(r"""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+
+            class Test(ConanFile):
+                name = "mytool"
+                version = "0.1"
+                package_type = "application"
+                settings = "os", "arch", "compiler", "build_type"
+                generators = "CMakeToolchain"
+                exports_sources = "*"
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+
+                def package(self):
+                    cmake = CMake(self)
+                    cmake.install()
+
+                def package_info(self):
+                    self.cpp_info.exe = "mytool"
+                    self.cpp_info.set_property("cmake_target_name", "MyTool::myexe")
+                    self.cpp_info.location = os.path.join("bin", "mytool")
+            """)
+        main = textwrap.dedent("""
+            #include <iostream>
+            #include <fstream>
+
+            int main() {
+                std::cout << "Mytool generating out.c!!!!!" << std::endl;
+                std::ofstream f("out.c");
+            }
+            """)
+        c = TestClient()
+        c.run("new cmake_exe -d name=mytool -d version=0.1")
+        c.save({"conanfile.py": conanfile,
+                "src/main.cpp": main})
+        c.run("create .")
+
+        requires = "tool_requires" if tool_requires else "requires"
+        consumer = textwrap.dedent(f"""
+            from conan import ConanFile
+            from conan.tools.cmake import CMakeDeps, CMakeToolchain, CMake, cmake_layout
+            class Consumer(ConanFile):
+                settings = "os", "compiler", "arch", "build_type"
+                {requires} = "mytool/0.1"
+
+                def generate(self):
+                    deps = CMakeDeps(self)
+                    deps.generate()
+                    tc = CMakeToolchain(self)
+                    tc.generate()
+
+                def layout(self):
+                    cmake_layout(self)
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(consumer C)
+
+            find_package(mytool)
+            add_custom_command(OUTPUT out.c COMMAND MyTool::myexe)
+            add_library(myLib out.c)
+            """)
+        c.save({"conanfile.py": consumer,
+                "CMakeLists.txt": cmake}, clean_first=True)
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported executable 'MyTool::myexe'" in c.out
+        assert "Mytool generating out.c!!!!!" in c.out
+
+    def test_exe_components(self):
+        conanfile = textwrap.dedent(r"""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+
+            class Test(ConanFile):
+                name = "mytool"
+                version = "0.1"
+                package_type = "application"
+                settings = "os", "arch", "compiler", "build_type"
+                generators = "CMakeToolchain"
+                exports_sources = "*"
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+
+                def package(self):
+                    cmake = CMake(self)
+                    cmake.install()
+
+                def package_info(self):
+                    self.cpp_info.components["my1exe"].exe = "mytool1"
+                    self.cpp_info.components["my1exe"].set_property("cmake_target_name", "MyTool::my1exe")
+                    self.cpp_info.components["my1exe"].location = os.path.join("bin", "mytool1")
+                    self.cpp_info.components["my2exe"].exe = "mytool2"
+                    self.cpp_info.components["my2exe"].set_property("cmake_target_name", "MyTool::my2exe")
+                    self.cpp_info.components["my2exe"].location = os.path.join("bin", "mytool2")
+            """)
+        main = textwrap.dedent("""
+            #include <iostream>
+            #include <fstream>
+
+            int main() {{
+                std::cout << "Mytool{number} generating out{number}.c!!!!!" << std::endl;
+                std::ofstream f("out{number}.c");
+            }}
+            """)
+        cmake = textwrap.dedent("""
+            set(CMAKE_CXX_COMPILER_WORKS 1)
+            set(CMAKE_CXX_ABI_COMPILED 1)
+            cmake_minimum_required(VERSION 3.15)
+            project(proj CXX)
+
+            add_executable(mytool1 src/main1.cpp)
+            add_executable(mytool2 src/main2.cpp)
+
+            install(TARGETS mytool1 DESTINATION "." RUNTIME DESTINATION bin)
+            install(TARGETS mytool2 DESTINATION "." RUNTIME DESTINATION bin)
+            """)
+        c = TestClient()
+        c.save({"conanfile.py": conanfile,
+                "CMakeLists.txt": cmake,
+                "src/main1.cpp": main.format(number=1),
+                "src/main2.cpp": main.format(number=2)
+                })
+        c.run("create .")
+
+        consumer = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMakeDeps, CMakeToolchain, CMake, cmake_layout
+            class Consumer(ConanFile):
+                settings = "os", "compiler", "arch", "build_type"
+                tool_requires = "mytool/0.1"
+
+                def generate(self):
+                    deps = CMakeDeps(self)
+                    deps.generate()
+                    tc = CMakeToolchain(self)
+                    tc.generate()
+                def layout(self):
+                    cmake_layout(self)
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(consumer C)
+
+            find_package(mytool)
+            add_custom_command(OUTPUT out1.c COMMAND MyTool::my1exe)
+            add_custom_command(OUTPUT out2.c COMMAND MyTool::my2exe)
+            add_library(myLib out1.c out2.c)
+            """)
+        c.save({"conanfile.py": consumer,
+                "CMakeLists.txt": cmake}, clean_first=True)
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported executable 'MyTool::my1exe'" in c.out
+        assert "Mytool1 generating out1.c!!!!!" in c.out
+        assert "Conan: Target declared imported executable 'MyTool::my2exe'" in c.out
+        assert "Mytool2 generating out2.c!!!!!" in c.out
+
+
+@pytest.mark.tool("cmake")
+class TestLibs:
+    def test_libs(self, matrix_client):
+        c = matrix_client
+        c.run("new cmake_lib -d name=app -d version=0.1 -d requires=matrix/1.0")
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::matrix'" in c.out
+
+    @pytest.mark.parametrize("shared", [False, True])
+    def test_libs_transitive(self, transitive_libraries, shared):
+        c = transitive_libraries
+        c.run("new cmake_lib -d name=app -d version=0.1 -d requires=engine/1.0")
+        shared = "-o engine/*:shared=True" if shared else ""
+        c.run(f"build . {shared} -c tools.cmake.cmakedeps:new={new_value}")
+        if shared:
+            assert "matrix::matrix" not in c.out  # It is hidden as static behind the engine
+            assert "Conan: Target declared imported SHARED library 'engine::engine'" in c.out
+        else:
+            assert "Conan: Target declared imported STATIC library 'matrix::matrix'" in c.out
+            assert "Conan: Target declared imported STATIC library 'engine::engine'" in c.out
+
+    def test_multilevel_shared(self):
+        # TODO: make this shared fixtures in conftest for multi-level shared testing
+        c = TestClient(default_server_user=True)
+        c.run("new cmake_lib -d name=matrix -d version=0.1")
+        c.run(f"create . -o *:shared=True -c tools.cmake.cmakedeps:new={new_value}")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_lib -d name=engine -d version=0.1 -d requires=matrix/0.1")
+        c.run(f"create . -o *:shared=True -c tools.cmake.cmakedeps:new={new_value}")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_lib -d name=gamelib -d version=0.1 -d requires=engine/0.1")
+        c.run(f"create . -o *:shared=True -c tools.cmake.cmakedeps:new={new_value}")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_exe -d name=game -d version=0.1 -d requires=gamelib/0.1")
+        c.run(f"create . -o *:shared=True -c tools.cmake.cmakedeps:new={new_value}")
+
+        assert "matrix/0.1: Hello World Release!"
+        assert "engine/0.1: Hello World Release!"
+        assert "gamelib/0.1: Hello World Release!"
+        assert "game/0.1: Hello World Release!"
+
+        # Make sure it works downloading to another cache
+        c.run("upload * -r=default -c")
+        c.run("remove * -c")
+
+        c2 = TestClient(servers=c.servers)
+        c2.run("new cmake_exe -d name=game -d version=0.1 -d requires=gamelib/0.1")
+        c2.run(f"create . -o *:shared=True -c tools.cmake.cmakedeps:new={new_value}")
+
+        assert "matrix/0.1: Hello World Release!"
+        assert "engine/0.1: Hello World Release!"
+        assert "gamelib/0.1: Hello World Release!"
+        assert "game/0.1: Hello World Release!"
+
+
+class TestLibsLinkageTraits:
+    def test_linkage_shared_static(self):
+        """
+        the static library is skipped
+        """
+        c = TestClient()
+        c.run("new cmake_lib -d name=matrix -d version=0.1")
+        c.run(f"create . -c tools.cmake.cmakedeps:new={new_value} -tf=")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_lib -d name=engine -d version=0.1 -d requires=matrix/0.1")
+        c.run(f"create . -o engine/*:shared=True -c tools.cmake.cmakedeps:new={new_value} -tf=")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_exe -d name=game -d version=0.1 -d requires=engine/0.1")
+        c.run(f"create . -o engine/*:shared=True -c tools.cmake.cmakedeps:new={new_value} "
+              "-c tools.compilation:verbosity=verbose")
+        assert re.search(r"Skipped binaries(\s*)matrix/0.1", c.out)
+        assert "matrix/0.1: Hello World Release!"
+        assert "engine/0.1: Hello World Release!"
+        assert "game/0.1: Hello World Release!"
+
+
+@pytest.mark.tool("cmake")
+class TestLibsComponents:
+    def test_libs_components(self, matrix_client_components):
+        """
+        explicit usage of components
+        """
+        c = matrix_client_components
+
+        # TODO: Check that find_package(.. COMPONENTS nonexisting) fails
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            # standard one, and a custom cmake_target_name one
+            target_link_libraries(app PRIVATE matrix::module MatrixHeaders)
+            """)
+        app_cpp = textwrap.dedent("""
+            #include "module.h"
+            #include "headers.h"
+            int main() { module(); headers();}
+            """)
+        c.save({"CMakeLists.txt": cmake,
+                "src/app.cpp": app_cpp})
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::vector'" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::module'" in c.out
+        if platform.system() == "Windows":
+            c.run_command(r".\build\Release\app.exe")
+            assert "Matrix headers __cplusplus: __cplusplus2014" in c.out
+
+    def test_libs_components_default(self, matrix_client_components):
+        """
+        Test that the default components are used when no component is specified
+        """
+        c = matrix_client_components
+
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+
+        app_cpp = textwrap.dedent("""
+            #include "module.h"
+            int main() { module();}
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE matrix::matrix)
+            """)
+        c.save({"src/app.cpp": app_cpp,
+                "CMakeLists.txt": cmake})
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::vector'" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::module'" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'MatrixHeaders'" in c.out
+
+    def test_libs_components_default_error(self, matrix_client_components):
+        """
+        Same as above, but it fails, because headers is not in the default components
+        """
+        c = matrix_client_components
+
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+
+        app_cpp = textwrap.dedent("""
+            #include "module.h"
+            #include "headers.h"
+            int main() { module();}
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE matrix::matrix)
+            """)
+        c.save({"src/app.cpp": app_cpp,
+                "CMakeLists.txt": cmake})
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}", assert_error=True)
+        assert "Error in build() method, line 35" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::vector'" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::module'" in c.out
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE matrix::matrix MatrixHeaders)
+            """)
+        c.save({"CMakeLists.txt": cmake})
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Running CMake.build()" in c.out  # Now it doesn't fail
+
+    def test_libs_components_transitive(self, matrix_client_components):
+        """
+        explicit usage of components
+        matrix::module -> matrix::vector
+
+        engine::bots -> engine::physix
+        engine::physix -> matrix::vector
+        engine::world -> engine::physix, matrix::module
+        """
+        c = matrix_client_components
+
+        from conan.test.assets.sources import gen_function_h
+        bots_h = gen_function_h(name="bots")
+        from conan.test.assets.sources import gen_function_cpp
+        bots_cpp = gen_function_cpp(name="bots", includes=["bots", "physix"], calls=["physix"])
+        physix_h = gen_function_h(name="physix")
+        physix_cpp = gen_function_cpp(name="physix", includes=["physix", "vector"], calls=["vector"])
+        world_h = gen_function_h(name="world")
+        world_cpp = gen_function_cpp(name="world", includes=["world", "physix", "module"],
+                                     calls=["physix", "module"])
+
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+            from conan.tools.files import copy
+
+            class Engine(ConanFile):
+              name = "engine"
+              version = "1.0"
+              settings = "os", "compiler", "build_type", "arch"
+              generators = "CMakeToolchain"
+              exports_sources = "src/*", "CMakeLists.txt"
+
+              requires = "matrix/1.0"
+              generators = "CMakeDeps", "CMakeToolchain"
+
+              def build(self):
+                  cmake = CMake(self)
+                  cmake.configure()
+                  cmake.build()
+
+              def package(self):
+                  cmake = CMake(self)
+                  cmake.install()
+
+              def package_info(self):
+                  self.cpp_info.components["bots"].libs = ["bots"]
+                  self.cpp_info.components["bots"].includedirs = ["include"]
+                  self.cpp_info.components["bots"].libdirs = ["lib"]
+                  self.cpp_info.components["bots"].requires = ["physix"]
+
+                  self.cpp_info.components["physix"].libs = ["physix"]
+                  self.cpp_info.components["physix"].includedirs = ["include"]
+                  self.cpp_info.components["physix"].libdirs = ["lib"]
+                  self.cpp_info.components["physix"].requires = ["matrix::vector"]
+
+                  self.cpp_info.components["world"].libs = ["world"]
+                  self.cpp_info.components["world"].includedirs = ["include"]
+                  self.cpp_info.components["world"].libdirs = ["lib"]
+                  self.cpp_info.components["world"].requires = ["physix", "matrix::module"]
+                  """)
+
+        cmakelists = textwrap.dedent("""
+               set(CMAKE_CXX_COMPILER_WORKS 1)
+               set(CMAKE_CXX_ABI_COMPILED 1)
+               cmake_minimum_required(VERSION 3.15)
+               project(matrix CXX)
+
+               find_package(matrix CONFIG REQUIRED)
+
+               add_library(physix src/physix.cpp)
+               add_library(bots src/bots.cpp)
+               add_library(world src/world.cpp)
+
+               target_link_libraries(physix PRIVATE matrix::vector)
+               target_link_libraries(bots PRIVATE physix)
+               target_link_libraries(world PRIVATE physix matrix::module)
+
+               set_target_properties(bots PROPERTIES PUBLIC_HEADER "src/bots.h")
+               set_target_properties(physix PROPERTIES PUBLIC_HEADER "src/physix.h")
+               set_target_properties(world PROPERTIES PUBLIC_HEADER "src/world.h")
+               install(TARGETS physix bots world)
+               """)
+        c.save({"src/physix.h": physix_h,
+                "src/physix.cpp": physix_cpp,
+                "src/bots.h": bots_h,
+                "src/bots.cpp": bots_cpp,
+                "src/world.h": world_h,
+                "src/world.cpp": world_cpp,
+                "CMakeLists.txt": cmakelists,
+                "conanfile.py": conanfile})
+        c.run("create .")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=engine/1.0")
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(engine CONFIG REQUIRED)
+
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE engine::bots)
+
+            install(TARGETS app)
+            """)
+        app_cpp = textwrap.dedent("""
+            #include "bots.h"
+            int main() { bots();}
+            """)
+        c.save({"CMakeLists.txt": cmake,
+                "src/app.cpp": app_cpp})
+        c.run(f"create . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::vector'" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::module'" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'matrix::matrix'" in c.out
+        assert "Conan: Target declared imported STATIC library 'engine::bots'" in c.out
+        assert "Conan: Target declared imported STATIC library 'engine::physix'" in c.out
+        assert "Conan: Target declared imported STATIC library 'engine::world'" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'engine::engine'" in c.out
+
+        assert "bots: Release!" in c.out
+        assert "physix: Release!" in c.out
+        assert "vector: Release!" in c.out
+
+    def test_libs_components_multilib(self):
+        """
+        cpp_info.libs = ["lib1", "lib2"]
+        """
+        c = TestClient()
+
+        from conan.test.assets.sources import gen_function_h
+        vector_h = gen_function_h(name="vector")
+        from conan.test.assets.sources import gen_function_cpp
+        vector_cpp = gen_function_cpp(name="vector", includes=["vector"])
+        module_h = gen_function_h(name="module")
+        module_cpp = gen_function_cpp(name="module", includes=["module"])
+
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+
+            class Matrix(ConanFile):
+                name = "matrix"
+                version = "1.0"
+                settings = "os", "compiler", "build_type", "arch"
+                generators = "CMakeToolchain"
+                exports_sources = "src/*", "CMakeLists.txt"
+
+                generators = "CMakeDeps", "CMakeToolchain"
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+
+                def package(self):
+                    cmake = CMake(self)
+                    cmake.install()
+
+                def package_info(self):
+                    self.cpp_info.set_property("cmake_target_name", "MyMatrix::MyMatrix")
+                    self.cpp_info.libs = ["module", "vector"]
+                  """)
+
+        cmakelists = textwrap.dedent("""
+            set(CMAKE_CXX_COMPILER_WORKS 1)
+            set(CMAKE_CXX_ABI_COMPILED 1)
+            cmake_minimum_required(VERSION 3.15)
+            project(matrix CXX)
+
+            add_library(module src/module.cpp)
+            add_library(vector src/vector.cpp)
+
+            set_target_properties(vector PROPERTIES PUBLIC_HEADER "src/vector.h")
+            set_target_properties(module PROPERTIES PUBLIC_HEADER "src/module.h")
+            install(TARGETS module vector)
+            """)
+        c.save({"src/module.h": module_h,
+                "src/module.cpp": module_cpp,
+                "src/vector.h": vector_h,
+                "src/vector.cpp": vector_cpp,
+                "CMakeLists.txt": cmakelists,
+                "conanfile.py": conanfile})
+        c.run("create .")
+
+        c.save({}, clean_first=True)
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE MyMatrix::MyMatrix)
+
+            install(TARGETS app)
+            """)
+        app_cpp = textwrap.dedent("""
+            #include "vector.h"
+            #include "module.h"
+            int main() { vector();module();}
+            """)
+        c.save({"CMakeLists.txt": cmake,
+                "src/app.cpp": app_cpp})
+        c.run(f"create . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::_vector'" in c.out
+        assert "Conan: Target declared imported STATIC library 'matrix::_module'" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'MyMatrix::MyMatrix'" in c.out
+        assert "matrix::matrix" not in c.out
+
+        assert "vector: Release!" in c.out
+        assert "module: Release!" in c.out
+        assert "vector: Release!" in c.out
+
+
+@pytest.mark.tool("cmake")
+class TestHeaders:
+    def test_header_lib(self, matrix_client):
+        c = matrix_client
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.files import copy
+            class EngineHeader(ConanFile):
+                name = "engine"
+                version = "1.0"
+                requires = "matrix/1.0"
+                exports_sources = "*.h"
+                settings = "compiler"
+                def package(self):
+                    copy(self, "*.h", src=self.source_folder, dst=self.package_folder)
+                def package_id(self):
+                    self.info.clear()
+                def package_info(self):
+                    self.cpp_info.defines = ["MY_MATRIX_HEADERS_DEFINE=1",
+                                             "MY_MATRIX_HEADERS_DEFINE2=1"]
+                    # Few flags to cover that CMakeDeps doesn't crash with them
+                    if self.settings.compiler == "msvc":
+                        self.cpp_info.cxxflags = ["/Zc:__cplusplus"]
+                        self.cpp_info.cflags = ["/Zc:__cplusplus"]
+                        self.cpp_info.system_libs = ["ws2_32"]
+                    else:
+                        self.cpp_info.system_libs = ["m", "dl"]
+                        # Just to verify CMake don't break
+                    if self.settings.compiler == "gcc":
+                        self.cpp_info.sharedlinkflags = ["-z now", "-z relro"]
+                        self.cpp_info.exelinkflags = ["-z now", "-z relro"]
+             """)
+        engine_h = textwrap.dedent("""
+            #pragma once
+            #include <iostream>
+            #include "matrix.h"
+            #ifndef MY_MATRIX_HEADERS_DEFINE
+            #error "Fatal error MY_MATRIX_HEADERS_DEFINE not defined"
+            #endif
+            #ifndef MY_MATRIX_HEADERS_DEFINE2
+            #error "Fatal error MY_MATRIX_HEADERS_DEFINE2 not defined"
+            #endif
+            void engine(){ std::cout << "Engine!" <<std::endl; matrix(); }
+            """)
+
+        c.save({"conanfile.py": conanfile,
+                "include/engine.h": engine_h})
+        c.run("create .")
+
+        app = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+            class EngineHeader(ConanFile):
+                settings = "os", "compiler", "build_type", "arch"
+                requires = "engine/1.0"
+                generators = "CMakeDeps", "CMakeToolchain"
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+             """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+            find_package(engine CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE engine::engine)
+            """)
+        c.save({"conanfile.py": app,
+                "CMakeLists.txt": cmake,
+                "src/app.cpp": gen_function_cpp(name="main", includes=["engine"], calls=["engine"])},
+               clean_first=True)
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'matrix::matrix'" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'engine::engine'" in c.out
+
+    @pytest.mark.skipif(platform.system() != "Windows", reason="Only windows")
+    def test_conditional_header(self):
+        conanfile = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.files import copy
+            class EngineHeader(ConanFile):
+                name = "engine"
+                exports_sources = "*.h"
+                def package(self):
+                    copy(self, "*.h", src=self.source_folder, dst=self.package_folder)
+                def package_info(self):
+                    self.cpp_info.defines = ["MY_MATRIX_HEADERS_{version}_DEFINE=1"]
+            """)
+        engine_h = textwrap.dedent("""
+            #pragma once
+            #include <iostream>
+
+            #ifndef MY_MATRIX_HEADERS_{version}_DEFINE
+            #error "Fatal error MY_MATRIX_HEADERS_{version}_DEFINE not defined"
+            #endif
+            void engine(){{ std::cout << "Engine {version}!" <<std::endl; }}
+            """)
+
+        c = TestClient()
+        c.save({"conanfile.py": conanfile.format(version="1_0"),
+                "include/engine.h": engine_h.format(version="1_0")})
+        c.run("create . --version=1_0")
+        c.save({"conanfile.py": conanfile.format(version="1_1"),
+                "include/engine.h": engine_h.format(version="1_1")})
+        c.run("create . --version=1_1")
+
+        app = textwrap.dedent("""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake, cmake_layout
+            class EngineHeader(ConanFile):
+                settings = "os", "compiler", "build_type", "arch"
+                generators = "CMakeDeps", "CMakeToolchain"
+                def requirements(self):
+                    v = "1_0" if self.settings.build_type == "Debug" else "1_1"
+                    self.requires(f"engine/{v}")
+                def layout(self):
+                    cmake_layout(self)
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+                    self.run(os.path.join(self.cpp.build.bindir, "app"))
+             """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+            find_package(engine CONFIG REQUIRED)
+            add_executable(app src/app.cpp)
+            target_link_libraries(app PRIVATE engine::engine)
+            """)
+        c.save({"conanfile.py": app,
+                "CMakeLists.txt": cmake,
+                "src/app.cpp": gen_function_cpp(name="main", includes=["engine"], calls=["engine"])},
+               clean_first=True)
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+        assert "engine/1_1" in c.out
+        assert "engine/1_0" not in c.out
+        assert "Conan: Target declared imported INTERFACE library 'engine::engine'" in c.out
+        assert "Engine 1_1!" in c.out
+
+        c.run(f"build . -c tools.cmake.cmakedeps:new={new_value} -s build_type=Debug")
+        assert "engine/1_1" not in c.out
+        assert "engine/1_0" in c.out
+        assert "Conan: Target declared imported INTERFACE library 'engine::engine'" in c.out
+        assert "Engine 1_0!" in c.out
+
+
+class TestToolRequires:
+    def test_tool_requires(self):
+        """ tool-requires should not define the try-compile or global variables
+        for includedirs, libraries, definitions, otherwise the build-context would
+        override the host context"""
+        c = TestClient()
+        c.save({"tool/conanfile.py": GenConanfile("tool", "0.1"),
+                "pkg/conanfile.py": GenConanfile("pkg", "0.1").with_settings("build_type")
+                                                              .with_tool_requires("tool/0.1")})
+        c.run("create tool")
+        c.run(f"install pkg -g CMakeDeps -c tools.cmake.cmakedeps:new={new_value}")
+        tool_config = c.load("pkg/tool-config.cmake")
+        assert 'set(tool_INCLUDE_DIRS' not in tool_config
+        assert 'set(tool_INCLUDE_DIR' not in tool_config
+        assert 'set(tool_LIBRARIES' not in tool_config
+
+
+@pytest.mark.tool("cmake")
+@pytest.mark.parametrize("tool_requires", [True, False])
+def test_build_modules_custom_script(tool_requires):
+    """
+    it works both as a tool_requires and as a regular requirement
+    """
+    client = TestClient()
+    conanfile = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.files import copy
+
+        class Conan(ConanFile):
+            name = "myfunctions"
+            version = "1.0"
+            exports_sources = ["*.cmake"]
+
+            def package(self):
+                copy(self, "*.cmake", self.source_folder, self.package_folder)
+
+            def package_info(self):
+                self.cpp_info.set_property("cmake_build_modules", ["myfunction.cmake"])
+        """)
+
+    myfunction = textwrap.dedent("""
+        function(myfunction)
+            message("Hello myfunction!!!!")
+        endfunction()
+        """)
+    client.save({"conanfile.py": conanfile, "myfunction.cmake": myfunction})
+    client.run("create .")
+
+    requires = "tool_requires" if tool_requires else "requires"
+    consumer = textwrap.dedent(f"""
+        from conan import ConanFile
+        from conan.tools.cmake import CMake
+
+        class Conan(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            generators = "CMakeToolchain", "CMakeDeps"
+            {requires} = "myfunctions/1.0"
+
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+        """)
+    cmakelists = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(test)
+        find_package(myfunctions CONFIG REQUIRED)
+        myfunction()
+        """)
+    client.save({"conanfile.py": consumer,
+                 "CMakeLists.txt": cmakelists},
+                clean_first=True)
+    client.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+    assert "Hello myfunction!!!!" in client.out
+
+
+@pytest.mark.tool("cmake")
+class TestProtobuf:
+
+    @pytest.fixture()
+    def protobuf(self):
+        conanfile = textwrap.dedent(r"""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake
+
+            class Protobuf(ConanFile):
+                name = "protobuf"
+                version = "0.1"
+                settings = "os", "arch", "compiler", "build_type"
+                options = {"shared": [True, False]}
+                default_options = {"shared": False}
+
+                generators = "CMakeToolchain"
+                exports_sources = "*"
+
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+
+                def package(self):
+                    cmake = CMake(self)
+                    cmake.install()
+
+                def package_info(self):
+                    self.cpp_info.set_property("cmake_file_name", "MyProtobuf")
+                    self.cpp_info.components["protobuf"].libs = ["protobuf"]
+                    self.cpp_info.components["protoc"].exe = "protoc"
+                    self.cpp_info.components["protoc"].set_property("cmake_target_name",
+                                                                    "Protobuf::Protocompile")
+                    self.cpp_info.components["protoc"].location = os.path.join("bin", "protoc")
+            """)
+        main = textwrap.dedent("""
+            #include <iostream>
+            #include <fstream>
+            #include "protobuf.h"
+
+            int main() {
+                protobuf();
+                #ifdef NDEBUG
+                std::cout << "Protoc RELEASE generating out.c!!!!!" << std::endl;
+                #else
+                std::cout << "Protoc DEBUG generating out.c!!!!!" << std::endl;
+                #endif
+                std::ofstream f("out.c");
+            }
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(protobuf CXX)
+
+            add_library(protobuf src/protobuf.cpp)
+            add_executable(protoc src/main.cpp)
+            target_link_libraries(protoc PRIVATE protobuf)
+            set_target_properties(protobuf PROPERTIES PUBLIC_HEADER "src/protobuf.h")
+
+            install(TARGETS protoc protobuf)
+            """)
+        c = TestClient()
+        c.save({"conanfile.py": conanfile,
+                "CMakeLists.txt": cmake,
+                "src/protobuf.h": gen_function_h(name="protobuf"),
+                "src/protobuf.cpp": gen_function_cpp(name="protobuf", includes=["protobuf"]),
+                "src/main.cpp": main})
+        c.run("export .")
+
+        consumer = textwrap.dedent("""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake, cmake_layout
+            class Consumer(ConanFile):
+                settings = "os", "compiler", "arch", "build_type"
+                requires = "protobuf/0.1"
+                generators = "CMakeToolchain", "CMakeDeps"
+
+                def layout(self):
+                    cmake_layout(self)
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+                    self.run(os.path.join(self.cpp.build.bindir, "myapp"))
+            """)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(consumer CXX)
+
+            find_package(MyProtobuf CONFIG REQUIRED)
+            add_custom_command(OUTPUT out.c COMMAND Protobuf::Protocompile)
+            add_executable(myapp myapp.cpp out.c)
+            target_link_libraries(myapp PRIVATE protobuf::protobuf)
+            get_target_property(imported_configs Protobuf::Protocompile IMPORTED_CONFIGURATIONS)
+            message(STATUS "Protoc imported configurations: ${imported_configs}!!!")
+            """)
+        myapp = textwrap.dedent("""
+            #include <iostream>
+            #include "protobuf.h"
+
+            int main() {
+                protobuf();
+                std::cout << "MyApp" << std::endl;
+            }
+            """)
+        c.save({"conanfile.py": consumer,
+                "CMakeLists.txt": cmake,
+                "myapp.cpp": myapp}, clean_first=True)
+        return c
+
+    def test_requires(self, protobuf):
+        c = protobuf
+        c.run(f"build . --build=missing -c tools.cmake.cmakedeps:new={new_value}")
+        assert "Conan: Target declared imported STATIC library 'protobuf::protobuf'" in c.out
+        assert "Conan: Target declared imported executable 'Protobuf::Protocompile'" in c.out
+        assert "Protoc RELEASE generating out.c!!!!!" in c.out
+        assert 'Protoc imported configurations: RELEASE!!!' in c.out
+
+    def test_both(self, protobuf):
+        consumer = textwrap.dedent("""
+            import os
+            from conan import ConanFile
+            from conan.tools.cmake import CMake, cmake_layout
+            class Consumer(ConanFile):
+                settings = "os", "compiler", "arch", "build_type"
+                requires = "protobuf/0.1"
+                tool_requires = "protobuf/0.1"
+                generators = "CMakeToolchain", "CMakeDeps"
+
+                def layout(self):
+                    cmake_layout(self)
+                def build(self):
+                    cmake = CMake(self)
+                    cmake.configure()
+                    cmake.build()
+            """)
+        c = protobuf
+        c.save({"conanfile.py": consumer})
+        c.run("build . -s:h build_type=Debug --build=missing "
+              f"-c tools.cmake.cmakedeps:new={new_value}")
+
+        assert "Conan: Target declared imported STATIC library 'protobuf::protobuf'" in c.out
+        assert "Conan: Target declared imported executable 'Protobuf::Protocompile'" in c.out
+        assert "Protoc RELEASE generating out.c!!!!!" in c.out
+        assert "protobuf: Release!" in c.out
+        assert "protobuf: Debug!" not in c.out
+        assert 'Protoc imported configurations: RELEASE!!!' in c.out
+
+        cmd = "./build/Debug/myapp" if platform.system() != "Windows" else r"build\Debug\myapp"
+        c.run_command(cmd)
+        assert "protobuf: Debug!" in c.out
+        assert "protobuf: Release!" not in c.out
+
+        c.run("build . --build=missing "
+              f"-c tools.cmake.cmakedeps:new={new_value}")
+
+        assert "Conan: Target declared imported STATIC library 'protobuf::protobuf'" in c.out
+        assert "Conan: Target declared imported executable 'Protobuf::Protocompile'" in c.out
+        assert "Protoc RELEASE generating out.c!!!!!" in c.out
+        assert "protobuf: Release!" in c.out
+        assert "protobuf: Debug!" not in c.out
+        assert 'Protoc imported configurations: RELEASE!!!' in c.out
+
+        cmd = "./build/Release/myapp" if platform.system() != "Windows" else r"build\Release\myapp"
+        c.run_command(cmd)
+        assert "protobuf: Debug!" not in c.out
+        assert "protobuf: Release!" in c.out
+
+
+@pytest.mark.tool("cmake", "3.23")
+class TestConfigs:
+    @pytest.mark.skipif(platform.system() != "Windows", reason="Only MSVC multi-conf")
+    def test_multi_config(self, matrix_client):
+        c = matrix_client
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+        c.run(f"install . -c tools.cmake.cmakedeps:new={new_value}")
+        c.run("install . -s build_type=Debug --build=missing "
+              f"-c tools.cmake.cmakedeps:new={new_value}")
+
+        c.run_command("cmake --preset conan-default")
+        c.run_command("cmake --build --preset conan-release")
+        c.run_command("cmake --build --preset conan-debug")
+
+        c.run_command("build\\Release\\app")
+        assert "matrix/1.0: Hello World Release!" in c.out
+        assert "app/0.1: Hello World Release!" in c.out
+        c.run_command("build\\Debug\\app")
+        assert "matrix/1.0: Hello World Debug!" in c.out
+        assert "app/0.1: Hello World Debug!" in c.out
+
+    def test_cross_config(self, matrix_client):
+        # Release dependencies, but compiling app in Debug
+        c = matrix_client
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+        c.run(f"install . -s &:build_type=Debug -c tools.cmake.cmakedeps:new={new_value}")
+
+        # With modern CMake > 3.26 not necessary set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+            set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
+            find_package(matrix CONFIG REQUIRED)
+
+            add_executable(app src/app.cpp src/main.cpp)
+            target_link_libraries(app PRIVATE matrix::matrix)
+            """)
+        c.save({"CMakeLists.txt": cmake})
+
+        preset = "conan-default" if platform.system() == "Windows" else "conan-debug"
+        c.run_command(f"cmake --preset {preset}")
+        c.run_command("cmake --build --preset conan-debug")
+
+        c.run_command(os.path.join("build", "Debug", "app"))
+        assert "matrix/1.0: Hello World Release!" in c.out
+        assert "app/0.1: Hello World Debug!" in c.out
+
+    @pytest.mark.skipif(platform.system() == "Windows", reason="This doesn't work in MSVC")
+    def test_cross_config_implicit(self, matrix_client):
+        # Release dependencies, but compiling app in Debug, without specifying it
+        c = matrix_client
+        c.run("new cmake_exe -d name=app -d version=0.1 -d requires=matrix/1.0")
+        c.run(f"install . -c tools.cmake.cmakedeps:new={new_value}")
+
+        # With modern CMake > 3.26 not necessary set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
+        cmake = textwrap.dedent("""
+            cmake_minimum_required(VERSION 3.15)
+            project(app CXX)
+            set(CMAKE_MAP_IMPORTED_CONFIG_DEBUG Release)
+            find_package(matrix CONFIG REQUIRED)
+
+            add_executable(app src/app.cpp src/main.cpp)
+            target_link_libraries(app PRIVATE matrix::matrix)
+            """)
+
+        c.save({"CMakeLists.txt": cmake})
+        # Now we can force the Debug build, even if dependencies are Release
+        c.run_command("cmake . -DCMAKE_BUILD_TYPE=Debug -B build "
+                      "-DCMAKE_PREFIX_PATH=build/Release/generators")
+        c.run_command("cmake --build build")
+        c.run_command("./build/app")
+        assert "matrix/1.0: Hello World Release!" in c.out
+        assert "app/0.1: Hello World Debug!" in c.out
+
+
+@pytest.mark.tool("cmake", "3.23")
+class TestCMakeTry:
+
+    def test_check_c_source_compiles(self, matrix_client):
+        """
+        https://github.com/conan-io/conan/issues/12012
+        """
+        c = matrix_client  # it brings the "matrix" package dependency pre-built
+
+        consumer = textwrap.dedent("""
+            from conan import ConanFile
+            from conan.tools.cmake import CMakeDeps
+            class PkgConan(ConanFile):
+                settings = "os", "arch", "compiler", "build_type"
+                requires = "matrix/1.0"
+                generators = "CMakeToolchain",
+                def generate(self):
+                    deps = CMakeDeps(self)
+                    deps.set_property("matrix", "cmake_additional_variables_prefixes", ["MyMatrix"])
+                    deps.generate()
+            """)
+
+        cmakelist = textwrap.dedent("""\
+            cmake_minimum_required(VERSION 3.15)
+            project(Hello LANGUAGES CXX)
+
+            find_package(matrix CONFIG REQUIRED)
+            include(CheckCXXSourceCompiles)
+
+            set(CMAKE_REQUIRED_INCLUDES ${MyMatrix_INCLUDE_DIRS})
+            set(CMAKE_REQUIRED_LIBRARIES ${MyMatrix_LIBRARIES})
+            check_cxx_source_compiles("#include <matrix.h>
+                                      int main(void) { matrix();return 0; }" IT_COMPILES)
+            """)
+
+        c.save({"conanfile.py": consumer,
+                "CMakeLists.txt": cmakelist}, clean_first=True)
+        c.run(f"install . -c tools.cmake.cmakedeps:new={new_value}")
+
+        preset = "conan-default" if platform.system() == "Windows" else "conan-release"
+        c.run_command(f"cmake --preset {preset} ")
+        assert "Performing Test IT_COMPILES - Success" in c.out
diff --git a/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_cpp_linkage.py b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_cpp_linkage.py
new file mode 100644
index 00000000000..0932a77fa35
--- /dev/null
+++ b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_cpp_linkage.py
@@ -0,0 +1,54 @@
+import platform
+import textwrap
+import pytest
+
+
+new_value = "will_break_next"
+
+
+@pytest.mark.skipif(platform.system() == "Windows", reason="Windows doesn't fail to link")
+def test_auto_cppstd(matrix_c_interface_client):
+    c = matrix_c_interface_client
+    # IMPORTANT: This must be a C and CXX CMake project!!
+    consumer = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.15)
+        project(myapp C CXX)
+
+        find_package(matrix REQUIRED)
+
+        add_executable(app app.c)
+        target_link_libraries(app PRIVATE matrix::matrix)
+        """)
+
+    conanfile = textwrap.dedent("""\
+        import os
+        from conan import ConanFile
+        from conan.tools.cmake import CMake, cmake_layout
+
+        class Recipe(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            package_type = "application"
+            generators = "CMakeToolchain", "CMakeDeps"
+            requires = "matrix/0.1"
+
+            def layout(self):
+                cmake_layout(self)
+
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+                self.run(os.path.join(self.cpp.build.bindir, "app"), env="conanrun")
+        """)
+    app = textwrap.dedent("""
+        #include "matrix.h"
+        int main(){
+            matrix();
+            return 0;
+        }
+        """)
+    c.save({"conanfile.py": conanfile,
+            "CMakeLists.txt": consumer,
+            "app.c": app}, clean_first=True)
+    c.run(f"build . -c tools.cmake.cmakedeps:new={new_value}")
+    assert "Hello Matrix!" in c.out
diff --git a/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_paths.py b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_paths.py
new file mode 100644
index 00000000000..f3c04e165f3
--- /dev/null
+++ b/test/functional/toolchains/cmake/cmakedeps/test_cmakedeps_new_paths.py
@@ -0,0 +1,97 @@
+import re
+import textwrap
+
+import pytest
+
+from conan.test.assets.genconanfile import GenConanfile
+from conan.test.utils.tools import TestClient
+
+new_value = "will_break_next"
+
+
+@pytest.fixture
+def client():
+    c = TestClient()
+    pkg = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import CMake, cmake_layout
+        import os
+        class Pkg(ConanFile):
+            settings = "build_type", "os", "arch", "compiler"
+            requires = "dep/0.1"
+            generators = "CMakeDeps", "CMakeToolchain"
+            def layout(self):  # Necessary to force config files in another location
+                cmake_layout(self)
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure(variables={"CMAKE_FIND_DEBUG_MODE": "ON"})
+       """)
+    cmake = textwrap.dedent("""
+       cmake_minimum_required(VERSION 3.15)
+       project(pkgb LANGUAGES NONE)
+       find_package(dep CONFIG REQUIRED)
+       """)
+    c.save({"dep/conanfile.py": GenConanfile("dep", "0.1"),
+            "pkg/conanfile.py": pkg,
+            "pkg/CMakeLists.txt": cmake})
+    return c
+
+
+@pytest.mark.tool("cmake")
+def test_cmake_generated(client):
+    c = client
+    c.run("create dep")
+    c.run(f"build pkg -c tools.cmake.cmakedeps:new={new_value}")
+    assert "Conan toolchain: Including CMakeDeps generated conan_find_paths.cmake" in c.out
+    assert "Conan: Target declared imported INTERFACE library 'dep::dep'" in c.out
+
+
+@pytest.mark.tool("cmake")
+def test_cmake_in_package(client):
+    c = client
+    # same, but in-package
+    dep = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.files import save
+        class Pkg(ConanFile):
+            name = "dep"
+            version = "0.1"
+
+            def package(self):
+                content = 'message(STATUS "Hello from dep dep-Config.cmake!!!!!")'
+                save(self, os.path.join(self.package_folder, "cmake", "dep-config.cmake"), content)
+            def package_info(self):
+                self.cpp_info.set_property("cmake_find_mode", "none")
+                self.cpp_info.builddirs = ["cmake"]
+        """)
+
+    c.save({"dep/conanfile.py": dep})
+    c.run("create dep")
+    c.run(f"build pkg -c tools.cmake.cmakedeps:new={new_value}")
+    assert "Conan toolchain: Including CMakeDeps generated conan_find_paths.cmake" in c.out
+    assert "Hello from dep dep-Config.cmake!!!!!" in c.out
+
+
+class TestRuntimeDirs:
+
+    def test_runtime_lib_dirs_multiconf(self):
+        client = TestClient()
+        app = GenConanfile().with_requires("dep/1.0").with_generator("CMakeDeps")\
+            .with_settings("build_type")
+        client.save({"lib/conanfile.py": GenConanfile(),
+                     "dep/conanfile.py": GenConanfile("dep").with_requires("onelib/1.0",
+                                                                           "twolib/1.0"),
+                     "app/conanfile.py": app})
+        client.run("create lib --name=onelib --version=1.0")
+        client.run("create lib --name=twolib --version=1.0")
+        client.run("create dep  --version=1.0")
+
+        client.run(f'install app -s build_type=Release -c tools.cmake.cmakedeps:new={new_value}')
+        client.run(f'install app -s build_type=Debug -c tools.cmake.cmakedeps:new={new_value}')
+
+        contents = client.load("app/conan_cmakedeps_paths.cmake")
+        pattern_lib_dirs = r"set\(CONAN_RUNTIME_LIB_DIRS ([^)]*)\)"
+        runtime_lib_dirs = re.search(pattern_lib_dirs, contents).group(1)
+        assert "<CONFIG:Release>" in runtime_lib_dirs
+        assert "<CONFIG:Debug>" in runtime_lib_dirs
diff --git a/test/functional/toolchains/conftest.py b/test/functional/toolchains/conftest.py
index e1f294b62a6..b81671e870f 100644
--- a/test/functional/toolchains/conftest.py
+++ b/test/functional/toolchains/conftest.py
@@ -1,8 +1,10 @@
 import os
 import shutil
+import textwrap
 
 import pytest
 
+from conan.test.assets.sources import gen_function_h, gen_function_cpp
 from conan.test.utils.test_files import temp_folder
 from conan.test.utils.tools import TestClient
 
@@ -48,3 +50,188 @@ def transitive_libraries(_transitive_libraries):
     c.cache_folder = os.path.join(temp_folder(), ".conan2")
     shutil.copytree(_transitive_libraries.cache_folder, c.cache_folder)
     return c
+
+
+@pytest.fixture(scope="session")
+def _matrix_client_components():
+    """
+    2 components, different than the package name
+    """
+    c = TestClient()
+    headers_h = textwrap.dedent("""
+        #include <iostream>
+        #ifndef MY_MATRIX_HEADERS_DEFINE
+        #error "Fatal error MY_MATRIX_HEADERS_DEFINE not defined"
+        #endif
+        void headers(){ std::cout << "Matrix headers: Release!" << std::endl;
+            #if __cplusplus
+            std::cout << "  Matrix headers __cplusplus: __cplusplus" << __cplusplus << std::endl;
+            #endif
+        }
+        """)
+    vector_h = gen_function_h(name="vector")
+    vector_cpp = gen_function_cpp(name="vector", includes=["vector"])
+    module_h = gen_function_h(name="module")
+    module_cpp = gen_function_cpp(name="module", includes=["module", "vector"], calls=["vector"])
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.cmake import CMake
+
+        class Matrix(ConanFile):
+            name = "matrix"
+            version = "1.0"
+            settings = "os", "compiler", "build_type", "arch"
+            generators = "CMakeToolchain"
+            exports_sources = "src/*", "CMakeLists.txt"
+
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+
+            def package(self):
+                cmake = CMake(self)
+                cmake.install()
+
+            def package_info(self):
+                self.cpp_info.default_components = ["vector", "module"]
+
+                self.cpp_info.components["headers"].includedirs = ["include/headers"]
+                self.cpp_info.components["headers"].set_property("cmake_target_name", "MatrixHeaders")
+                self.cpp_info.components["headers"].defines = ["MY_MATRIX_HEADERS_DEFINE=1"]
+                # Few flags to cover that CMakeDeps doesn't crash with them
+                if self.settings.compiler == "msvc":
+                    self.cpp_info.components["headers"].cxxflags = ["/Zc:__cplusplus"]
+                    self.cpp_info.components["headers"].cflags = ["/Zc:__cplusplus"]
+                    self.cpp_info.components["headers"].system_libs = ["ws2_32"]
+                else:
+                    self.cpp_info.components["headers"].system_libs = ["m"]
+                    # Just to verify CMake don't break
+                    self.cpp_info.sharedlinkflags = ["-z now", "-z relro"]
+                    self.cpp_info.exelinkflags = ["-z now", "-z relro"]
+
+                self.cpp_info.components["vector"].libs = ["vector"]
+                self.cpp_info.components["vector"].includedirs = ["include"]
+                self.cpp_info.components["vector"].libdirs = ["lib"]
+
+                self.cpp_info.components["module"].libs = ["module"]
+                self.cpp_info.components["module"].includedirs = ["include"]
+                self.cpp_info.components["module"].libdirs = ["lib"]
+                self.cpp_info.components["module"].requires = ["vector"]
+          """)
+
+    cmakelists = textwrap.dedent("""
+       set(CMAKE_CXX_COMPILER_WORKS 1)
+       set(CMAKE_CXX_ABI_COMPILED 1)
+       cmake_minimum_required(VERSION 3.15)
+       project(matrix CXX)
+
+       add_library(vector src/vector.cpp)
+       add_library(module src/module.cpp)
+       add_library(headers INTERFACE)
+       target_link_libraries(module PRIVATE vector)
+
+       set_target_properties(headers PROPERTIES PUBLIC_HEADER "src/headers.h")
+       set_target_properties(module PROPERTIES PUBLIC_HEADER "src/module.h")
+       set_target_properties(vector PROPERTIES PUBLIC_HEADER "src/vector.h")
+       install(TARGETS vector module)
+       install(TARGETS headers PUBLIC_HEADER DESTINATION include/headers)
+       """)
+    c.save({"src/headers.h": headers_h,
+            "src/vector.h": vector_h,
+            "src/vector.cpp": vector_cpp,
+            "src/module.h": module_h,
+            "src/module.cpp": module_cpp,
+            "CMakeLists.txt": cmakelists,
+            "conanfile.py": conanfile})
+    c.run("create .")
+    return c
+
+
+@pytest.fixture()
+def matrix_client_components(_matrix_client_components):
+    c = TestClient()
+    c.cache_folder = os.path.join(temp_folder(), ".conan2")
+    shutil.copytree(_matrix_client_components.cache_folder, c.cache_folder)
+    return c
+
+
+@pytest.fixture(scope="session")
+def _matrix_c_interface_client():
+    c = TestClient()
+    matrix_h = textwrap.dedent("""\
+        #pragma once
+        #ifdef __cplusplus
+        extern "C" {
+        #endif
+            void matrix();
+        #ifdef __cplusplus
+        }
+        #endif
+        """)
+    matrix_cpp = textwrap.dedent("""\
+        #include "matrix.h"
+        #include <iostream>
+        #include <string>
+        void matrix(){
+            std::cout<< std::string("Hello Matrix!") <<std::endl;
+        }
+        """)
+    # Having here the config.cmake code to be able to manually check what CMake generates
+    cmake = textwrap.dedent("""\
+        cmake_minimum_required(VERSION 3.15)
+        project(matrix C CXX)
+        add_library(matrix STATIC src/matrix.cpp)
+        target_include_directories(matrix PUBLIC
+          $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+          $<INSTALL_INTERFACE:include>
+        )
+        set_target_properties(matrix PROPERTIES PUBLIC_HEADER "include/matrix.h")
+        install(TARGETS matrix EXPORT matrixConfig)
+        export(TARGETS matrix
+            NAMESPACE matrix::
+            FILE "${CMAKE_CURRENT_BINARY_DIR}/matrixConfig.cmake"
+        )
+        install(EXPORT matrixConfig
+            DESTINATION "${CMAKE_INSTALL_PREFIX}/matrix/cmake"
+            NAMESPACE matrix::
+        )
+        """)
+    conanfile = textwrap.dedent("""\
+        from conan import ConanFile
+        from conan.tools.cmake import CMake, cmake_layout
+        class Recipe(ConanFile):
+            name = "matrix"
+            version = "0.1"
+            settings = "os", "compiler", "build_type", "arch"
+            package_type = "static-library"
+            generators = "CMakeToolchain"
+            exports_sources = "CMakeLists.txt", "src/*", "include/*"
+            languages = "C++"
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+            def layout(self):
+                cmake_layout(self)
+            def package(self):
+                cmake = CMake(self)
+                cmake.install()
+            def package_info(self):
+                self.cpp_info.libs = ["matrix"]
+        """)
+    c.save({"include/matrix.h": matrix_h,
+            "src/matrix.cpp": matrix_cpp,
+            "conanfile.py": conanfile,
+            "CMakeLists.txt": cmake})
+    c.run("create .")
+    return c
+
+
+@pytest.fixture()
+def matrix_c_interface_client(_matrix_c_interface_client):
+    c = TestClient()
+    c.cache_folder = os.path.join(temp_folder(), ".conan2")
+    shutil.copytree(_matrix_c_interface_client.cache_folder, c.cache_folder)
+    return c