conan-io / docs

conan.io reStructuredText documentation
http://docs.conan.io
MIT License
110 stars 361 forks source link

[bug] CMakeDeps throws error for package(s) defined as platform_requires #3908

Open kambala-decapitator opened 3 days ago

kambala-decapitator commented 3 days ago

Describe the bug

macOS 14.7, Conan 2.9.2, apple-clang 15

I declared some libs as platform_requires (Apple OSs have them preinstalled in the system), everything built fine. But at the final moment when CMakeDeps starts its work it throws an error:

ERROR: Error in generator 'CMakeDeps': error generating context for 'ffmpeg/7.0.1': ffmpeg/7.0.1: component 'avcodec' required 'zlib::zlib', but 'zlib' is not a direct dependency

Also, had to tune a few other recipes a bit that they don't throw an error when trying to access the platform_requires libs from self.dependencies, see here. Is it to be considered a bug or should be adjusted on a recipe basis?

Previously in Conan v1 I wrote wrapper recipes for these libs and there was no such issue. Oh, actually I faced one issue that resembles the self.dependencies one described above for which I provided a PR https://github.com/conan-io/conan-center-index/pull/23478, but no issues with CMakeDeps.

P.S. Also asked this on Slack

P.P.S. One more example of such error, but no full log at hand at the moment:

ERROR: sdl_mixer/2.8.0: Error in generate() method, line 227
    deps.generate()
    ConanException: error generating context for 'openssl/3.3.2': openssl/3.3.2: component 'crypto' required 'zlib::zlib', but 'zlib' is not a direct dependency

How to reproduce it

conanfile.txt

[requires]
ffmpeg/7.0.1

[generators]
CMakeToolchain
CMakeDeps

Build profile (basically the detected one):

[settings]
arch=x86_64
build_type=Release
compiler=apple-clang
compiler.cppstd=gnu17
compiler.libcxx=libc++
compiler.version=15
os=Macos

[platform_tool_requires]
cmake/3.31.0
ninja/1.12.1

Host profile: same as build (used include) with the addition of

[platform_requires]
bzip2/1.0.8
libiconv/1.17
sqlite3/3.47.0
zlib/1.2.11

Command used:

conan install . -pr:b default -pr:h 'default copy' -of 1 -b missing

Full log: log.txt.zip

memsharded commented 3 days ago

Hi @kambala-decapitator

This is not a bug, this is expected. Please have a look to: https://blog.conan.io/2024/02/20/Conan-2-graph-features.html

The [platform_requires] can only be used in those cases where a fully transparent replacement can happen. If some dependency references them explicitly, then it is not possible to do it. This is why [platform_requires] are unlikely to work in many cases, and for most cases the platform can only be done for [platform_tool_requires] like CMake.

For other cases, it is necessary to use [replace_requires] and use a system wrapper recipe that provides the same interface, so it can be used as a replacement.

kambala-decapitator commented 2 days ago

Thank you for the explanation! I wish docs communicated the limitations better, as its unclear that one is likely to face issues with this feature.

If I understand correctly, a perfect use case for platform_requires is when you have full control over the recipes used, can freely edit/adjust what you want. Which is not the case with CCI-provided recipes.

Also, had to tune a few other recipes a bit that they don't throw an error when trying to access the platform_requires libs from self.dependencies, see here. Is it to be considered a bug or should be adjusted on a recipe basis?

now, to my understanding, this is also something that the wrapper recipe should take care of instead of editing CCI recipes.

For other cases, it is necessary to use [replace_requires] and use a system wrapper recipe that provides the same interface, so it can be used as a replacement.

what would be the recommendation to name such recipes? zlib@system like in the blog post or something like zlib@mycompany/system? If I recall correctly, using channel portion isn't recommended in v2.

memsharded commented 2 days ago

Thank you for the explanation! I wish docs communicated the limitations better, as its unclear that one is likely to face issues with this feature.

Yes, that is true, it was more thorougly explained in the blog post, but the docs are a bit scarce here, lets try to complete them a bit more

If I understand correctly, a perfect use case for platform_requires is when you have full control over the recipes used, can freely edit/adjust what you want. Which is not the case with CCI-provided recipes.

Yes, not the case for many recipes in CCI (many other recipes in CCI might actually work). The key is that it cannot be used if other recipes does a explicit reference to it, to its components, or the like. If a recipe has only the self.requires("pkg/version"), and standard generators usage like CMakeDeps, and the system pkg can be found with find_package() in the system transparently, it can be done. If the consumer recipes reference the package, or its components explicitly, then it cannot be done.

now, to my understanding, this is also something that the wrapper recipe should take care of instead of editing CCI recipes.

Yes

what would be the recommendation to name such recipes? zlib@system like in the blog post or something like zlib@mycompany/system? If I recall correctly, using channel portion isn't recommended in v2.

Channel is not recommended as a variable/stage dynamic qualifier to represent a variable maturity or stage in the process. It can be safely used as kind of an immutable/invariant namespace to differentiate things. For ConanCenter like packages we usually don't recommend using user part, but for this case it seems that both zlib/version@system or zlib/version@company/system would be ok.

kambala-decapitator commented 2 days ago

Thank you very much! Now all is clear.

Should I close the issue or you'd like to keep it open until docs are improved?

memsharded commented 2 days ago

Lets move it to docs repo