conan-io / cmake-conan

CMake wrapper for conan C and C++ package manager

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[develop2] How to correctly use in context of dependencies used with FetchContent?

fklebert opened this issue Β· comments

I have a question on how to use cmake-conan in context of two repos that have a dependency.
In the original repo I have a conanfile.txt with

[requires]
openssl/1.1.1t
keychain/1.2.1
spdlog/1.11.0
pybind11/2.10.4

[generators]
CMakeDeps

[options]
openssl*:shared=True

I am successfully building it by simply adding

cmake_minimum_required(VERSION 3.24)
# Add conan 2.0 support
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/conan-provider.cmake)

to my top-level CMakeLists.txt.

Now I wanted to include this repo as a dependency in another repo via CMake's FetchContent, like so:

if (NOT TARGET zswag)
        FetchContent_Declare(zswag
                GIT_REPOSITORY "https://github.com/ndsev/zswag.git"
                GIT_TAG        "less-submodules-introduce-conan"
                GIT_SHALLOW    ON)
        FetchContent_MakeAvailable(zswag)
endif()

(probably using it as submodule would be a similar issue)

I only got this working by adding all the needed conan packages of the dependency also to my local repo's conanfile.txt.
Is that the envisioned way to do it, or am I doing something wrong?

commented

Hi @fklebert

Thanks for your question.

Is that the envisioned way to do it, or am I doing something wrong?

No, that is not the envisioned way to do it, but as you are using a package manager, use the package manager πŸ™‚ :

The recommended approach would be to create a Conan package out of your project. Convert your conanfile.txt to a full conanfile.py and conan create . your package, it will create something like zswag/1.0, and now the consumer can install it by adding it to their conanfile.txt requirements, and then no need to add all the transitive dependencies to the consumer project. Also this will take care of any other potential issue like version conflicts (if you have more than one project, and if you follow the same approach and have 2 FetchContent, the transitive dependencies will collide)

OK, got it. πŸ˜„
I was kind of expecting that answer, which of course totally makes sense.
The background of this question is that in case you are maintaining two projects and have to make changes to both (local and dependency) to realize a new feature, is there a good way to deal with that? In the old days we used submodules, made the change locally and then often forgot to correctly push the dependency. πŸ˜‰
With FetchContent (which is kind of middle ground between submodules and package manager IMHO) we simply point to the feature/dev branch and are fine when later in the process we can nail it to a version tag with the last commit of a PR. I did not really find a neat way to do the same when using conan.
I assume in that case I would need to always re-create packages, eventually re-deploy them, etc. Or is there a smart way of doing this, that I am not aware of?

commented

The background of this question is that in case you are maintaining two projects and have to make changes to both (local and dependency) to realize a new feature, is there a good way to deal with that? In the old days we used submodules, made the change locally and then often forgot to correctly push the dependency.

yes, there is. We have the editable feature (similar to python pip one), that allows you to put both the dependency and the consumer in user space, so changes are immediately apply to the other. Please check:

The missing orchestrator so far is the workspaces, which will be a 2.X roadmap thing that we will resume work on it when possible.

Thanks for providing the links. Exactly what I was looking for πŸ‘