Repository: conan-io/conan

Issue:
[bug] find_package can't find config files if cross compilation/2 profiles 
<!--
  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 Catalina
  * Compiler+version: AppleClang 12
  * Conan version: 1.38.0
  * Python version: 3.9.6

### Steps to reproduce (Include if Applicable)

- clone conan-center-index
- in recipes/re2/all: `conan create . re2/20210601 -pr:b profile_build -pr:h profile_host` (profile_build and profile_host must be different, otherwise it works).
- You can test all recipes where test package relies on cmake_find_package_multi, it will fail.

example of profiles on macOS:

profile_build:

```
[settings]
os=Macos
arch=x86_64
compiler=apple-clang
compiler.version=12.0
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]
```


profile_host:

```
[settings]
os=iOS
os.version=12.0
arch=x86_64
compiler=apple-clang
compiler.version=12.0
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]
```

### Logs (Executed commands with output) (Include/Attach if Applicable)

<!--
  Your log content should be related to the bug description, it can be:
  - Conan command output
  - Server output (Artifactory, conan_server)
-->

```
re2/20210601 (test package): Calling build()
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - 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: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: called by CMake conan helper
-- Conan: Adjusting output directories
-- Conan: Using cmake targets configuration
-- Library re2 found /Users/spaceim/.conan/data/re2/20210601/_/_/package/5839e36f8f9b4a19c6ebf23cc2d929e50f6634a3/lib/libre2.a
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Conan: C++ stdlib: libc++
CMake Error at CMakeLists.txt:7 (find_package):
  Could not find a package configuration file provided by "re2" with any of
  the following names:

    re2Config.cmake
    re2-config.cmake

  Add the installation prefix of "re2" to CMAKE_PREFIX_PATH or set "re2_DIR"
  to a directory containing one of the above files.  If "re2" provides a
  separate development package or SDK, be sure it has been installed.


-- Configuring incomplete, errors occurred!
See also "/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47/CMakeFiles/CMakeOutput.log".
ERROR: re2/20210601 (test package): Error in build() method, line 11
	cmake.configure()
	ConanException: Error 1 while executing cd '/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47' && cmake -G "Ninja" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_OSX_SYSROOT="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.2.sdk" -DCMAKE_SYSTEM_NAME="iOS" -DCMAKE_SYSTEM_VERSION="12.0" -DCMAKE_OSX_DEPLOYMENT_TARGET="12.0" -DCONAN_IN_LOCAL_CACHE="OFF" -DCONAN_COMPILER="apple-clang" -DCONAN_COMPILER_VERSION="12.0" -DCONAN_CXX_FLAGS="-m64" -DCONAN_SHARED_LINKER_FLAGS="-m64" -DCONAN_C_FLAGS="-m64" -DCONAN_LIBCXX="libc++" -DCMAKE_INSTALL_PREFIX="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47/package" -DCMAKE_INSTALL_BINDIR="bin" -DCMAKE_INSTALL_SBINDIR="bin" -DCMAKE_INSTALL_LIBEXECDIR="bin" -DCMAKE_INSTALL_LIBDIR="lib" -DCMAKE_INSTALL_INCLUDEDIR="include" -DCMAKE_INSTALL_OLDINCLUDEDIR="include" -DCMAKE_INSTALL_DATAROOTDIR="share" -DCMAKE_PREFIX_PATH="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47" -DCMAKE_MODULE_PATH="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47" -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY="ON" -DCONAN_EXPORTED="1" -Wno-dev '/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package'
c
```

Is it related to CMake helper? conan_basic_setup()? I don't know. From what I saw, `CMAKE_PREFIX_PATH` and `CMAKE_MODULE_PATH` are properly set, and `re2-config.cmake` is located in build folder of test package.
If I replace in test package `cmake_find_package_multi` by `cmake_find_package`, and `find_package(re2 REQUIRED CONFIG)` by `find_package(re2 REQUIRED)`, it works.
This is a simple example, but this issue breaks cross compilation of several more complex CCI recipes where CMake configuration of the lib itself relies on discovery of CMake config files generated by `cmake_find_package_multi` (I've seen this issue in `libgeotiff` originally, after fixing cross compilation issues of its (transitive) dependencies like proj, sqlite3 or jbig).


Discussion:
I have tried with Windows and Linux (I don't have a Mac), and even when the profile host and profile build are different (I tried compiling for 32 bits), it works.

Someone else that could try in OSX->iOS, please?

@SpaceIm it would be good to know if this is a 1.38 regression, and it used to work in 1.37 or also failing in previous Conan versions.
I don't know for older versions of conan, I'll try.
I've tried with conan 1.35.0, 1.36.0 and 1.37.0, it fails with the same error.
Thanks for the detailed report, I could reproduce the error on Macos, I'll try to investigate further what could be the issue.
I think this issue was solved for OSX in the CMakeToolchain by @lasote, adding the XXX_DIR variable to packages for OSX exclusively.
Hi, yes, the new `CMakeToolchain` already solves this issue. With the old cmake generators you will need a workaround.
You can add `set(re2_DIR ${CMAKE_BINARY_DIR})` in the `CMakeLists.txt` file after the `conan_basic_setup()` call.

Edit: The root cause is that CMake only search the Macos folders when crossbuilding. Another weird and unexpected behavior to be honest.
I have closed without merging https://github.com/conan-io/conan/pull/9250, this is solved in the new CMakeToolchain, fixing it in the old ones is complicated and risky, it only applies to one very specific scenario (OSX and cross-build) and a workaround is relatively straightforward. Thanks all!
@memsharded When you say "new CMakeToolchain", you refer to CMakeDeps?

FYI, this issue breaks several build of CCI recipes, and many test_package, so it prevents CCI to add a configuration for iOS. CCI can't use CMakeDeps for the moment, and some recipes must model Find AND config files because they are different (like protobuf).
> @memsharded When you say "new CMakeToolchain", you refer to CMakeDeps?

No, it is included in the ``find_paths`` block of ``CMakeToolchain``. This is not about the deps itself, but where to locate the ``xxx-config.cmake`` files generated by Conan.


> FYI, this issue breaks several build of CCI recipes, and many test_package, so it prevents CCI to add a configuration for iOS. 

How can it break the build, if CCI is not cross-building and not using 2 profiles? It is not intended to add iOS as a configuration to ConanCenter.

> CCI can't use CMakeDeps for the moment, and some recipes must model Find AND config files because they are different (like protobuf).

It will also be possible to use CMakeDeps and CMakeToolchain in ConanCenter very soon.
@memsharded It's true that CCI doesn't build binaries for iOS currently, but @jgsogo may add this profile https://github.com/conan-io/conan-center-index/pull/6045#issuecomment-878944765. So yes it doesn't break CI of CCI, but it might break consumers using others profiles. It's not because CI of CCI doesn't test those profiles, that CCI recipes shouldn't support them.

Here is a simple fix in `cmake` generator (prepend build_modules paths of requirements + `CMAKE_CURRENT_LIST_DIR` to `CONAN_CMAKE_FIND_ROOT_PATH` in `conanbuildinfo.cmake`): https://github.com/conan-io/conan-center-index/pull/6315#issuecomment-879323254
Hi! This kind of addition/fixes/enhancements would be very valuable from the point of view of conan-center-index. Right now we are building Macos/armv8 using two profiles (cross-building from regular Macos) and we have fixed many recipes, not because now it works for this new configuration, but because in the way we have removed legacy and improve their quality for other configurations.

Right now we are receiving **a lot of PRs related to iOS**, some of them adding support and some **others just fixing things that were working but some PR broke** (I've broken several recipes for other configurations while trying to add support for M1). It translates into many more PRs and more burden on some people that are really taking care of `conan-center-index` and recipe quality. It happens for iOS, but also for Android and Linux/ARM. If we don't test a configuration, someone will break it.

Gathering feedback from the community, we feel that it would be very valuable to add some of these configurations to ensure that the recipes are not broken when we fix something (M1, iOS, Android, Conan v2,...). [The plan](https://github.com/conan-io/conan-center-index/issues/4761) is to stop generating some of the current configurations following the lead of the [new docker images](https://github.com/conan-io/conan-docker-tools/pull/271) and the data about most used configurations that we are starting to collect... and use that spare capacity to build other configurations that will be much more valuable.

It will take time to provide this capability in ConanCenter, I'm not sure if by that time all the new CMakeDeps/CMakeToolchain will be fully available and stable. Anyway, the sooner we can have the right recipes for these configurations, the better, that way contributors can work on consumer recipes, otherwise whenever we find one of these blockers, we cannot work on dependents... and it really takes time to progress on the graph of dependencies.


Just to mention that the fact that `CONAN_CMAKE_FIND_ROOT_PATH` is not properly set in `conanbuildinfo.cmake` doesn't break only `find_package()` of config files, but things like `find_library()` or `find_path()`, or targets defined by `pkg_check_modules()`, making some libraries very hard to package for iOS.

`set(re2_DIR ${CMAKE_BINARY_DIR})` is a workaround to find config files only, but ti doesn't help when we package libraries using a custom Find module file calling `find_library()` and `find_path()`. Moreover, I'm not sure it's a good idea to add more complexity in CCI recipes just for one configuration.

Here are several CCI recipes whose build is broken (not only test package) due to this issue:
- grpc
- ignition-math
- libgeotiff
- libmysqlclient
- libnghttp2
- redis-plus-plus
- tesseract
- vcglib
@memsharded Sorry to bother you, but I have a fix that I've tested locally with several recipes in native and cross-build scenario:

```patch
--- a/conans/client/generators/cmake_common.py
+++ b/conans/client/generators/cmake_common.py
@@ -108,6 +108,7 @@ set(CONAN_FRAMEWORKS_FOUND{build_type} "")  # Will be filled later
 set(CONAN_DEFINES{build_type} {deps.defines} ${{CONAN_DEFINES{build_type}}})
 set(CONAN_BUILD_MODULES_PATHS{build_type} {deps.build_modules_paths} ${{CONAN_BUILD_MODULES_PATHS{build_type}}})
 set(CONAN_CMAKE_MODULE_PATH{build_type} {deps.build_paths} ${{CONAN_CMAKE_MODULE_PATH{build_type}}})
+set(CONAN_CMAKE_FIND_ROOT_PATH{build_type} {deps.build_paths} ${{CMAKE_CURRENT_LIST_DIR}} ${{CONAN_CMAKE_FIND_ROOT_PATH{build_type}}})
 
 set(CONAN_CXX_FLAGS{build_type} "{deps.cxxflags} ${{CONAN_CXX_FLAGS{build_type}}}")
 set(CONAN_SHARED_LINKER_FLAGS{build_type} "{deps.sharedlinkflags} ${{CONAN_SHARED_LINKER_FLAGS{build_type}}}")
```

Would you consider a PR for this issue?
After more experimentations, the less fragile solution I've found is:

```patch
--- a/conans/client/generators/cmake_common.py
+++ b/conans/client/generators/cmake_common.py
@@ -108,6 +108,7 @@ set(CONAN_FRAMEWORKS_FOUND{build_type} "")  # Will be filled later
 set(CONAN_DEFINES{build_type} {deps.defines} ${{CONAN_DEFINES{build_type}}})
 set(CONAN_BUILD_MODULES_PATHS{build_type} {deps.build_modules_paths} ${{CONAN_BUILD_MODULES_PATHS{build_type}}})
 set(CONAN_CMAKE_MODULE_PATH{build_type} {deps.build_paths} ${{CONAN_CMAKE_MODULE_PATH{build_type}}})
+set(CONAN_CMAKE_FIND_ROOT_PATH{build_type} ${{CMAKE_CURRENT_LIST_DIR}} ${{CONAN_CMAKE_FIND_ROOT_PATH{build_type}}})
 
 set(CONAN_CXX_FLAGS{build_type} "{deps.cxxflags} ${{CONAN_CXX_FLAGS{build_type}}}")
 set(CONAN_SHARED_LINKER_FLAGS{build_type} "{deps.sharedlinkflags} ${{CONAN_SHARED_LINKER_FLAGS{build_type}}}")
```

${{CMAKE_CURRENT_LIST_DIR}} => for conan generated config files

{deps.build_paths} can't be added, because it would put executables paths of host context in `CMAKE_FIND_ROOT_PATH`. It's important for recipes where the same dependency is in `requirements()` dans `build_requirements()` (for example protobuf), to avoid `find_program` to find executables of host context.

But `find_library()` and `find_path()` still fail if host is iOS/tvOS/watchOS (and I guess it will be the same in conan v2).

`opencv` recipe in CCI is a good example. In some module files, it uses `find_library()` and `find_path()` for libwebp and openexr, and it can't find libs and headers if iOS/tvOS/watchOS.
If you add {deps.build_paths} in `CONAN_CMAKE_FIND_ROOT_PATH`, it can find libs and headers of libwebp and openexr, but find the wrong protobuf executable (host context instead of build context).
If you add rootpath of libwebp and openexr only to `CONAN_CMAKE_FIND_ROOT_PATH`, it succeeds.
Another solution:

`conanbuildinfo.cmake` (or maybe `CMake` helper) could just force these variables to a consistent value:

```cmake
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) # for find_library()
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) # for find_file() and find_path()
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) # for find_package()
# maybe also CMAKE_FIND_ROOT_PATH_MODE_PROGRAM?
```

Problems appear when they are automatically set to `ONLY` by CMake (which seems to be the case when you cross-compile to iOS, but for example when I cross-compile from Macos x86-64 to Macos armv8, I don't have any issue, so I don't even know how CMake set the default values of these variables).

https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html#variables-that-change-behavior

Resolving patch:
diff --git a/conans/client/build/cmake.py b/conans/client/build/cmake.py
--- a/conans/client/build/cmake.py
+++ b/conans/client/build/cmake.py
@@ -5,7 +5,6 @@
 
 from six import StringIO  # Python 2 and 3 compatible
 
-
 from conans.client import tools
 from conans.client.build import defs_to_string, join_arguments
 from conans.client.build.cmake_flags import CMakeDefinitionsBuilder, \
@@ -78,6 +77,14 @@ def __init__(self, conanfile, generator=None, cmake_system_name=True,
 
         self.definitions["CONAN_EXPORTED"] = "1"
 
+        if hasattr(self._conanfile, 'settings_build'):
+            # https://github.com/conan-io/conan/issues/9202
+            if self._conanfile.settings_build.get_safe("os") == "Macos" and \
+               self._conanfile.settings.get_safe("os") == "iOS":
+                self.definitions["CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"] = "BOTH"
+                self.definitions["CMAKE_FIND_ROOT_PATH_MODE_LIBRARY"] = "BOTH"
+                self.definitions["CMAKE_FIND_ROOT_PATH_MODE_PACKAGE"] = "BOTH"
+
         self.toolset = toolset or get_toolset(self._settings, self.generator)
         self.build_dir = None
         self.msbuild_verbosity = os.getenv("CONAN_MSBUILD_VERBOSITY") or msbuild_verbosity


Test patch:
diff --git a/conans/test/functional/build_helpers/cmake_ios_cross_build_test.py b/conans/test/functional/build_helpers/cmake_ios_cross_build_test.py
new file mode 100644
--- /dev/null
+++ b/conans/test/functional/build_helpers/cmake_ios_cross_build_test.py
@@ -0,0 +1,73 @@
+import platform
+import textwrap
+
+import pytest
+
+from conans.test.utils.tools import TestClient
+
+
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Only for Apple")
+@pytest.mark.tool_cmake
+def test_cross_build_test_package():
+    # https://github.com/conan-io/conan/issues/9202
+    profile_build = textwrap.dedent("""
+        [settings]
+        os=Macos
+        arch=x86_64
+        compiler=apple-clang
+        compiler.version=12.0
+        compiler.libcxx=libc++
+        build_type=Release
+        [options]
+        [build_requires]
+        [env]
+    """)
+
+    profile_host = textwrap.dedent("""
+        [settings]
+        os=iOS
+        os.version=12.0
+        arch=x86_64
+        compiler=apple-clang
+        compiler.version=12.0
+        compiler.libcxx=libc++
+        build_type=Release
+        [options]
+        [build_requires]
+        [env]
+    """)
+
+    test_cmakelist = textwrap.dedent("""
+        cmake_minimum_required(VERSION 3.1)
+        project(PackageTest CXX)
+        include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+        conan_basic_setup(TARGETS)
+        find_package(hello REQUIRED CONFIG)
+        add_executable(example example.cpp)
+        target_link_libraries(example hello::hello)
+        set_property(TARGET example PROPERTY CXX_STANDARD 11)
+    """)
+
+    test_conanfile = textwrap.dedent("""
+        import os
+        from conans import ConanFile, CMake, tools
+        class HelloTestConan(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            generators = "cmake", "cmake_find_package_multi"
+            def build(self):
+                cmake = CMake(self)
+                cmake.configure()
+                cmake.build()
+            def test(self):
+                if not tools.cross_building(self):
+                    os.chdir("bin")
+                    self.run(".%sexample" % os.sep)
+    """)
+
+    client = TestClient()
+    client.run("new hello/0.1 -t")
+    client.save({"profile_build": profile_build,
+                 "profile_host": profile_host,
+                 "./test_package/conanfile.py": test_conanfile,
+                 "./test_package/CMakeLists.txt": test_cmakelist})
+    client.run("create . -pr:b profile_build -pr:h profile_host")