Skip to content

Remove cpp_info.config multi-configuration definition #21

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

Merged

Conversation

memsharded
Copy link
Member

This PR proposes to remove the cpp_info multi-configuration definition that can be used in package_info() as:

self.cpp_info.release.libs = ["my_library"]
self.cpp_info.debug.libs = ["my_library_d"]

It makes packages more bloated, inefficient, unsecure and fragile. The 1 configuration per binary package model works very well, and this feature is largely unsupported by many build systems, so it seems there is evidence that this is not a commonly used feature.


  • Upvote 👍 or downvote 👎 to show acceptance or not to the proposal (other reactions will be ignored)
    • Please, use 👀 to acknowledge you've read it, but it doesn't affect your workflow
  • Comment and reviews to suggest changes to all (or part) of the proposal.

@DoDoENT
Copy link

DoDoENT commented Mar 15, 2021

I wasn't even aware that this feature exists in Conan, yet once I had the need for such a feature, but I found a different solution.

Notably, the package in question had a lot of headers and not many binaries (similar to boost) and I wanted to optimize for storage space, unzip duration and download time in order to avoid downloading and unzipping headers for each and every combination of OS, compiler, arch and build type.

The solution was to split the package into two packages - one containing only the headers and marked as "header-only" and another containing only the libs that depend on the first one. Thus, the headers were downloaded and unzipped once and the packages containing the binaries were pretty much lightweight.

@memsharded, if you like that solution, feel free to add it to the Migration plan part of the proposal. 😊

The only downside of the solution was the need to always release both packages simultaneously (not a big deal, especially when done by the CI) and to ensure that there is no version mismatch between the package containing the binaries and the package containing the headers (a bit tricky, but could be done).

@a4z
Copy link

a4z commented Mar 15, 2021

since I never used that I am fine with removing it

however, I do not think that this feature is largely unsupported by many build systems,

XCode, VS Studio, njnia , and also CMake have support for that, and for sure some others I do not know about

@puetzk
Copy link

puetzk commented Mar 15, 2021

I agree. This is something that many CMake generators do support well, at least for consumer usage, but since approximately no conan recipes do the current conan feature is more confusion than value. If there was a way to instead resolve the recipes, then choose more than one package_id by (by varying settings.build_type), and put together more than one IMPORTED_LOCATION_<CONFIG> property in the targets generated by cmake_multi, or cmake_find_package_multi, that would be a nice quality-of-life improvement for these multi-config generators. But the support in cpp_info is not very useful, since very few build systems actually produce multiple binaries in a single build as needed to have a recipe package things this way.

@kenfred
Copy link

kenfred commented Mar 15, 2021

I agree with @a4z and @puetzk. We would love more consistent support for multi-configuration. Many of our users are used to generating VS solutions and switching between configs. It was a hard sell to tell them to generate different builds for the different configs.

That being said, since we were never satisfied with the multi-config support of conan, we abandoned it and reluctantly standardized on single-config builds. If we it can't be supported well, then perhaps removing support in conan as a "lowest common denominator" solution is warranted. However, our developers would prefer great mutli-config support, if it can be done.

@puetzk
Copy link

puetzk commented Mar 15, 2021

I like enforcing 1 configuration per binary package_id. I'd be happy to see dependency graph/generator support for scenarios where you might more than one binary package_id chosen per recipe (e.g. cross-compiler usage where you want to use tools from --profile:build and libs/headers from --profile:host, or release/debug in multi-configuration CMake generators. But those are orthogonal to ditching this in the producer side.

@a4z
Copy link

a4z commented Mar 15, 2021

If include and library search locations update for configurations, then on the end user side multi config should still work fine.
and afaik conan supports that already and it works fine.
Just packages them self should not pack debug and release libs into the same package, and that is a good idea, imho. at least, this is how I understand that pr.

@uboot
Copy link

uboot commented Mar 16, 2021

Similar to what @kenfred told our environment was very used to multi-configuration Visual Studio solutions. But with the introduction of Conan we dropped multi-configuration support. Now we usually generate Visual Studio solutions (from CMake) which support either debug or release builds. My impression is that solid multi-configuration support implies a lot of complexity on the Conan side which is not worth the benefit. So I will upvote this proposal.

@memsharded
Copy link
Member Author

Just to clarify: the fact that this proposal removes multi-config definitions in packages, doesn't imply that we will not keep working in multi-configuration support on the consumer side. The current CMakeDeps and MSBuildDeps generators, that are aimed to be the canonical integrations are multi-config, and further efforts will be made on them to improve the multi-config experience on such consumer side.

@mpusz
Copy link

mpusz commented Mar 16, 2021

The current CMakeDeps and MSBuildDeps generators, that are aimed to be the canonical integrations are multi-config

I just want to confirm that CMakeDeps works great with Ninja Multi-Config already.

@jmarrec
Copy link

jmarrec commented Mar 16, 2021

I may be misunderstanding this, could you clarify something for me please?

Let's say I make a recipe for an upstream lib (eg, zlib or whatever), and by default that project will build a libzlib.dll in Release and a libzlib_d.dll in Debug (not saying zlib does, this is hypothetical). How do I deal with this? Do I need to create a patch for the existing "upstream" source project so that it will always call it libzlib.dll?

@memsharded
Copy link
Member Author

@jmarrec

Let's say I make a recipe for an upstream lib (eg, zlib or whatever), and by default that project will build a libzlib.dll in Release and a libzlib_d.dll in Debug (not saying zlib does, this is hypothetical). How do I deal with this? Do I need to create a patch for the existing "upstream" source project so that it will always call it libzlib.dll?

No, you will have to do nothing. The zlib recipe will typically contain:

def package_info(self):
     suffix = "d" if self.settings.build_type == "Debug" else ""
     self.cpp_info.libs = ["libzlib{}".format(suffix)]

With that you will be able to create both Debug and Release packages, with the usual:

conan create . -s build_type=Debug
conan create . -s build_type=Release

Then upload the recipe with those 2 binaries, and use them later. When you are using the Debug one, the libzlibd will appear in your builds and when you are using the Release one the libzlib will be the one used. But they are managed as 2 different binaries, each one with its own package_id, not as a single package with 1 package_id and containing both libzlibd and libzlib, which is the confusing pattern that makes those packages difficult to use.

Please let me know if this explains it, thanks!

@jmarrec
Copy link

jmarrec commented Mar 16, 2021

@memsharded Ok thank you for the explanation, it has cleared out my concerns.

@memsharded
Copy link
Member Author

As proposed and described in the document, it seems that this feature is not used and its value more than questionable. Lets remove it.

@memsharded memsharded merged commit 451cdb8 into conan-io:main Apr 6, 2021
@memsharded memsharded deleted the proposal/remove_cpp_info_configs branch April 6, 2021 18:10
@ssrobins
Copy link

ssrobins commented May 23, 2021

@memsharded Disappointed to see this going away. It was a bit painful to set up packages with multiple configs, but you couldn't beat the convenience of being able to change build configs in Visual Studio/Xcode and have it 'just work'. I've even set up conan install to run inside CMake so the end user had very little Conan-specific workflows to think about.

If one conan install command could still stage all the build config variants for a given package version, that would keep those workflows intact. Conan knows the build_type and any specific settings that go along with it. Wouldn't that be enough information to generate the CMake variables that set up the config-specific lib names and paths?

Until this is possible, please bring back self.cpp_info.debug.libs/self.cpp_info.release.libs, it's vital to simple multi-config CMake workflows which, with the addition of Ninja Multi-Config, encompasses any platform, desktop, mobile, and beyond.

@memsharded
Copy link
Member Author

Hi @ssrobins

The thing is that it is still possible to change build configs in VisualStudio/XCode IDE and have everything working. The new conan.tools.cmake.CMakeDeps and conan.tools.microsoft.MSBuildDeps which will be the standard integrations in Conan 2.0 are already multi-config, not only for the standard "Release/Debug...", but they both also allow custom user configurations (typical ReleaseDLL config that many people have for example in Visual).

So the only inconvenience is that you should call 2 (or more) conan install commands, to get the binaries that you want. Still, we consider the scalability, performance, and maintainability of this approach to be a very good trade-off for the difficulties, as you said it: "it was a bit painful to set-up packages with multiple configs".

@ssrobins
Copy link

Good to know, @memsharded, thanks. Any end-to-end examples of CMakeDeps? I followed this doc to make the conanfile.py changes, but I'm not sure what to put in the consuming CMakeLists.txt file. For the cmake generator, I had this:

include(conanbuildinfo.cmake)
conan_basic_setup(TARGETS)

But conanbuildinfo.cmake is no longer generated. It's now generating a bunch of other .cmake files, but they seem to only reference the dependent package in my package. I thought maybe I'm supposed to keep using cmake in addition to CMakeDeps, but I didn't see anything in conanbuildinfo.cmake connecting the two sets of files.

@memsharded
Copy link
Member Author

@ssrobins

For CMakeDeps, the integration is via find_package(), no need to add anything extra to your CMakeLists. The generated conan_toolchain.cmake file will contain the CMAKE_MODULE_PATH pointing to the folder where the CMakeDeps generator generates the xxxx-config.cmake scripts.

The cmake generator will no longer be necessary, will be removed in Conan 2.0.

@ssrobins
Copy link

@memsharded

Do I have to explicitly call find_package() for each dependent package? Or is there an option to automatically call find_package() on all packages listed in the def requirements(self) of my app's conanfile.py?

I have no find_package() commands in my app's CMake, I've been directly using the CMake targets from conan_basic_setup(TARGETS). After all, why 'find' the package when Conan knows exactly where it is? :)

Anyway, thanks for your time, I'll keep poking at the Conan 2.0 conversion when I have time...

@memsharded
Copy link
Member Author

Do I have to explicitly call find_package() for each dependent package?

Only for your direct dependencies. Transitive dependencies are managed within the direct one.

I have no find_package() commands in my app's CMake, I've been directly using the CMake targets from conan_basic_setup(TARGETS). After all, why 'find' the package when Conan knows exactly where it is? :)

This was our rationale back in Conan first release, and the reason we went with our cmake generator as the proposed integration with CMake. But the community has been pushing heavily towards a more cmake-idiomatic integration, i.e. the find_package() one, with the objective that their CMakeLists.txt should be as agnostic about Conan as possible. Automatically creating a conan-something.cmake file that calls automatically every direct find_package() should be quite straightforward in Conan 2.0 for users that want that behavior, but it is likely it will not be initially built-in.

Anyway, thanks for your time, I'll keep poking at the Conan 2.0 conversion when I have time...

You are welcome, and great, feedback is very welcome, so thanks to you!

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

Successfully merging this pull request may close these issues.

9 participants