# Unexpected interactions between \`CMAKE\_SYSROOT\` and \`CMAKE\_FIND\_ROOT\_PATH\_MODE\_PACKAGE\`

**URL:** <https://discourse.cmake.org/t/unexpected-interactions-between-cmake-sysroot-and-cmake-find-root-path-mode-package/7893>\
**Category:** Code\
**Created:** [April 12, 2023, 6:43pm UTC](https://discourse.cmake.org/t/unexpected-interactions-between-cmake-sysroot-and-cmake-find-root-path-mode-package/7893 "2023-04-12T18:43:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![PieterP](https://discourse.cmake.org/user_avatar/discourse.cmake.org/pieterp/32/5184_2.png) [@PieterP](https://discourse.cmake.org/u/PieterP)\
**Post date:** [April 12, 2023, 6:43pm UTC](https://discourse.cmake.org/t/unexpected-interactions-between-cmake-sysroot-and-cmake-find-root-path-mode-package/7893/1 "2023-04-12T18:43:09Z")

</div>

**TL;DR** : Why does leaving `CMAKE_SYSROOT` unset in a toolchain file cause CMake to ignore `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY` and allow `find_package` to search `CMAKE_PREFIX_PATH` anyway?

**Context** : I’m playing around with cross-compilation using the Conan package manager.  
Conan writes `packagename-config.cmake` files for all dependencies in a build directory, and then provides a CMake toolchain file that adds this build directory to `CMAKE_PREFIX_PATH`, so that `find_package()` picks up the `config.cmake` files generated by Conan. So far, so good.

**Unexpected observation #1** :  
However, when cross-compiling, I use the following in my toolchain file, to avoid accidentally picking up packages from the machine I’m building on:

```cmake
set(CMAKE_SYSTEM_NAME "Linux")
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)

```

The strange thing is that CMake still picks up Conan’s packages, even though they are only available in `CMAKE_PREFIX_PATH`, which I would expect to be skipped during cross-compilation.  
It seems that the Conan devs rely on this themselves, though, for example in these tests: [conan/test\_cmaketoolchain\_paths.py at d66a3c00ef66947ec8c9e0b2bfba69cfcdce7387 · conan-io/conan · GitHub](https://github.com/conan-io/conan/blob/d66a3c00ef66947ec8c9e0b2bfba69cfcdce7387/conans/test/functional/toolchains/cmake/test_cmaketoolchain_paths.py#L178)

**Unexpected observation #2** :  
However, when also setting `CMAKE_SYSROOT` in the toolchain file, suddenly, `find_package` no longer considers the Conan `config.cmake` files in `CMAKE_PREFIX_PATH`. This seems to me the expected behavior, but it is unexpected to me that simply setting `CMAKE_SYSROOT` changes the behavior of `find_package` for `CMAKE_PREFIX_PATH`.

As a consequence, cross-compilation using Conan is broken when both `CMAKE_SYSROOT` and `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY` are set in the user’s toolchain file.

When editing the toolchain file generated by Conan, replacing `CMAKE_PREFIX_PATH` to `CMAKE_FIND_ROOT_PATH`, it picks up the Conan `config.cmake` files again, as expected.

**Some final questions** :

- Should the Conan devs consider setting `CMAKE_FIND_ROOT_PATH` instead of `CMAKE_PREFIX_PATH` to make sure CMake locates the `config.cmake` files it generated?
- The [_Mastering CMake_ chapter on cross-compilation](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html) does not set `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY`. Why not? Is it ever acceptable to select packages from the build machine when cross-compiling? (Ignoring cases where the user explicitly allows it at the `find_package` call site, e.g. when they know that the package is header-only.)

* * *

**Files to reproduce** :

> **The following files can be used to reproduce the problem, without using Conan.**
>
> **_CMakeLists.txt_**
> 
> ```cmake
> cmake_minimum_required(VERSION 3.20)
> project(cmake-prefix-tests)
> 
> list(PREPEND CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/packages)
> # list(PREPEND CMAKE_FIND_ROOT_PATH ${PROJECT_SOURCE_DIR}/packages)
> find_package(mypackage REQUIRED)
> 
> ```
> 
> **_packages/mypackage-config.cmake_**
> 
> ```cmake
> message(STATUS "FOUND: ${CMAKE_CURRENT_LIST_FILE}")
> 
> ```
> 
> **_toolchainA.cmake_**
> 
> ```cmake
> set(CMAKE_SYSTEM_NAME Linux)
> set(CMAKE_C_COMPILER cc)
> # set(CMAKE_SYSROOT "${CMAKE_CURRENT_LIST_DIR}/sysroot")
> 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)
> 
> ```
> 
> **_toolchainB.cmake_**
> 
> ```cmake
> set(CMAKE_SYSTEM_NAME Linux)
> set(CMAKE_C_COMPILER cc)
> set(CMAKE_SYSROOT "${CMAKE_CURRENT_LIST_DIR}/sysroot")
> 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)
> 
> ```
> 
> ```sh
> $ rm -rf build; cmake -S. -Bbuild --toolchain toolchainA.cmake
> -- FOUND: /home/.../packages/mypackage-config.cmake
> 
> $ rm -rf build; cmake -S. -Bbuild --toolchain toolchainB.cmake
> Could not find a package configuration file provided by "mypackage" with
> any of the following names:
> 
> mypackageConfig.cmake
> mypackage-config.cmake
> 
> ```

---

<div class="post-metadata">

**Author:** ![PieterP](https://discourse.cmake.org/user_avatar/discourse.cmake.org/pieterp/32/5184_2.png) [@PieterP](https://discourse.cmake.org/u/PieterP)\
**Post date:** [November 14, 2023, 7:40pm UTC](https://discourse.cmake.org/t/unexpected-interactions-between-cmake-sysroot-and-cmake-find-root-path-mode-package/7893/2 "2023-11-14T19:40:02Z")

</div>

> [@PieterP](#):
>
> **TL;DR** : Why does leaving `CMAKE_SYSROOT` unset in a toolchain file cause CMake to ignore `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY` and allow `find_package` to search `CMAKE_PREFIX_PATH` anyway?  
> …
> 
> Should the Conan devs consider setting `CMAKE_FIND_ROOT_PATH` instead of `CMAKE_PREFIX_PATH` to make sure CMake locates the `config.cmake` files it generated?

Is there anyone who has an answer to these questions?
