conan-io / conan-io/conan

[feature] CMakeToolchain - emit cache_variables to cache file

Open
#19,086 16 comments 0 reactions 1 assignee Claimed by @memsharded View on GitHub
unplanned
Dominant language
Python
Stars
9.5k
Forks
1.1k
Avg merge
3d 32m
Merged PRs (30d)
18

Description

### What is your suggestion?

I manage a chain of C++ projects that build using CMake. One of them has a primary build flow that uses Conan as the build frontend, using the CMakeToolchain generator, where the build instructions are along the lines of:
```
conan install -pr ...
cmake --preset
cmake --build --preset
```

That works fine for them in isolation, but they are a dependency of another project, and most of our development now has to go between these two projects. For a smoother development workflow, I would like to integrate these projects through a CMake `FetchContent` dependency from the parent project.

This should be straightforward. Run `conan_install` at or before configure time from the parent project, and then include the subproject. However, they use the Conan CMakeToolchain's `cache_variables` field to populate information, and that data _only_ lives in the conan-generated CMake presets file. This presets file is not usable when including the project as a sub-build (since a preset may only be selected by the top-level project).

To fix this, I propose conan generate a [CMake Cache File](https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-C) containing the variables specified by `cache_variables`. As long as this file exists and is at a predictable location, the parent project can [`include`](https://cmake.org/cmake/help/latest/command/include.html) that file to supply those variables to the subproject.

Currently I am able to do this locally via the following addition to the subproject's `conanfile.py`:
```python
# Duplicate the toolchain cmake variables into a separate CMake file so it is reusable.
cmakeData = "# Generated file containing all CMake cache variables from Conan toolchain.\n"

for key, value in tc.cache_variables.items():
cmakeData += f"set({key} \"{value}\" CACHE STRING \"{key} from conan toolchain\")\n"

cache_file_path = Path("ConanCMakeOpts.cmake")
cache_file_path.write_text(cmakeData)
print("conanfile.py: Generated ConanCMakeOpts.cmake")
```

### Have you read the CONTRIBUTING guide?

- [x] I've read the CONTRIBUTING guide

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.