Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[develop2] Using cmake-conan with custom presets creates chicken and egg situation #685

Open
Lewi97 opened this issue Feb 19, 2025 · 1 comment
Assignees

Comments

@Lewi97
Copy link

Lewi97 commented Feb 19, 2025

Hi,

I have been using Conan for awhile with my own presets by following this article on the documentation, however I now want to switch to using cmake-conan out of convenience. Configuring my project with CMake now doesn't work with the prior recommended workflow.

As per the guide, my presets all inherit the Conan generated presets:

[...]
"include": ["./ConanPresets.json"],
"configurePresets": [
  {
    "name": "my-preset",
    "generator": "Ninja",
    "inherits": "conan-debug",
[...]

This configures correctly when conan install is called before invoking cmake. When using cmake-conan however it doesn't configure because to configure my project my preset needs to be valid which it is not because ./ConanPresets.json does not exist yet, for ./ConanPresets.json to exist the project needs to configure which requires... my preset to be valid. Kind of a chicken and egg situation.

How can I remedy this situation?

Using cmake-conan@commit c22bbf0
Using conan==2.12.2
Using cmake version 3.30.3
Using conanfile.py with content:

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout


class fooRecipe(ConanFile):
    name = "foo"
    version = "1.0"

    settings = "os", "compiler", "build_type", "arch"

    def requirements(self):
        self.requires("fmt/11.1.3")

    def layout(self):
        cmake_layout(self)

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.user_presets_path = "ConanPresets.json"
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()
@memsharded memsharded self-assigned this Feb 19, 2025
@memsharded
Copy link
Member

Hi @Lewi97

Thanks for your questions.

however I now want to switch to using cmake-conan out of convenience

I'd like to start by challenging this a bit. I am not a big fan of cmake-conan, and having CMake as a driver to call Conan for installing dependencies. Separation of concerns is good, understanding and properly using the tooling is good, being explicit is good. Sometimes yet another layer of abstraction is not that great.

The flows with conan install + cmake presets are in general the suggested ones because it is in general the overall more convenient. The cmake-conan integration exists for the extreme cases of organizations with many developers that would react negatively to any change in their processes or tools. But for regular developers the conan install + cmake can be better.

The cmake-conan integration has some limitations, due to the fact that once CMake is driving the build, it is difficult to implement some more behaviors that can be easily provided by a CMake toolchain+presets approach. One common case is injecting env-vars like PATH from tool_requires into the build, which cannot be done with cmake-conan. A very obvious example is the dependency to cmake itself via tool_requires.
Some of these limitations might be improved, and we are working on the new incubating CMakeDeps generator that will be leveraged by the cmake-conan to do some of these tasks now impossible.

Still, inheriting from "include": ["./ConanPresets.json"], Conan presets will always be impossible by this approach. As ConanPresets.json is generated by Conan, and Conan is not called at all until the first find_package() is called, it is impossible for Conan to provide this file for the presets. So for cmake-conan to work, Conan has to be completely dropped from the presets.

Totally a chicken-and-egg situation as you said, which is not solvable, unless you fully drop the ConanPresets.json inheritance, and you can live with some of the limitations of the CMake-driven approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants