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

[question] Static dependencies #9902

Open
1 task
w3sip opened this issue Oct 28, 2021 · 10 comments
Open
1 task

[question] Static dependencies #9902

w3sip opened this issue Oct 28, 2021 · 10 comments
Assignees

Comments

@w3sip
Copy link

w3sip commented Oct 28, 2021

When we started with Conan, the understanding we developed is that if dependency is only needed during build (but not necessarily for the CI/build environment), this dependency was referenced via build_requires, and if that dependency is used during runtime, it is referenced via requires.

The documentation for 1.41.0 is pretty explicit in disproving this believe. And that makes sense in context of cross-building. However, how do we deal with requirements that are not necessary downstream?

For example, lets consider a scenario, where my shared library libfoo links with static zlib. libbar then depends on libfoo, but, as a transitive dependency, zlib package will be downloaded anytime during conan install for libbar. Is there a way to prevent this, and indicate that a particular requires dependency should not be visible to consumers of the recipe using it?

@memsharded
Copy link
Member

One of the main problems with build_requires is that they cannot affect the package_id of the consumers, by definition. So that is a very bad situation for a shared library that depends on a static library regarding the re-build, build-order, CI, etc. As it is not that typical to mix shared-static, and build-systems can also filter what they are linking, it might be better to use regular requires.

Furthermore, Conan 2.0 will explicitly model these relations, and will avoid propagating the linkage requirement downstream, automatically.

@w3sip
Copy link
Author

w3sip commented Oct 28, 2021

I've just discovered the private parameter to requires -- sounds like it does what I'd expect in this case? If so, would 2.0 preserve this?

@memsharded
Copy link
Member

private in 1.X should probably be used only in extreme case, where there is absolutely no other alternative, as they have their limitations too. Yes, 2.0 will have a way more advanced graph model, you can read about it in: conan-io/tribe#26

@w3sip
Copy link
Author

w3sip commented Nov 8, 2021

should probably be used only in extreme case

So what is the alternative?

Lets say I have a library/package libfoo, which depends on a very large package, providing both static and dynamic libraries -- lets say, IPP. libfoo takes care, through cmake settings to not link with the shared libraries. But it does bring IPP through a requires clause -- which puts IPP on the graph for the downstream libraries.

Then I have a libbar, which depends on libfoo. libbar now pulls in IPP through conan graph -- and as the result its product now depends on IPP shared libraries. Didn't plan on shipping those -- yet there they are.

If private clause on requires works (which I'm about to test), I see it as an absolute necessity for the above scenarios; otherwise shared libraries from an artifact from which static libraries had been used will end up a runtime requirement for downstream projects.

@w3sip
Copy link
Author

w3sip commented Nov 19, 2021

This keeps coming up. And I don't think a good solution currently exists, other than using build_requires with force_host_context=True. What am I missing here? How to link a project with a static library artifact, without having all the downstream objects to link with the same static library?

@wjswjq
Copy link

wjswjq commented Sep 26, 2022

should probably be used only in extreme case

So what is the alternative?

Lets say I have a library/package libfoo, which depends on a very large package, providing both static and dynamic libraries -- lets say, IPP. libfoo takes care, through cmake settings to not link with the shared libraries. But it does bring IPP through a requires clause -- which puts IPP on the graph for the downstream libraries.

Then I have a libbar, which depends on libfoo. libbar now pulls in IPP through conan graph -- and as the result its product now depends on IPP shared libraries. Didn't plan on shipping those -- yet there they are.

If private clause on requires works (which I'm about to test), I see it as an absolute necessity for the above scenarios; otherwise shared libraries from an artifact from which static libraries had been used will end up a runtime requirement for downstream projects.

Hi w3sip, have you got any work around? I have a libA, which depends on boost. As boost is quite a large dependency, I hope it can be compiled totally in libA via static library. In that way, I needn't install boost binary any more when using libA.

@w3sip
Copy link
Author

w3sip commented Sep 26, 2022

@wjswjq - unfortunately, no great solutions. build_requires(force_host_context=True) is a functional workaround, but my understanding is, it won't work anymore with Conan 2.0.
This, however, is a problem for another day.

@wjswjq
Copy link

wjswjq commented Sep 26, 2022

@w3sip, Thanks a lot.

@w3sip
Copy link
Author

w3sip commented Sep 26, 2022

@memsharded - I must be misunderstanding something very fundamental about Conan dependency chain management, even with shared dependencies, not just static. Let me give you an example.

Lets say I have a project libswissknife. It contains libswissknife_blade, libswissknife_bottleopener, libswissknife_screwdriver etc. One of these libraries (lets say libswissknife_screwdriver) depends on OpenCV.

We then have libA, depending on libswissknife, and linking with it using CONAN_PKG::libswissknife synthax.

However, now if we look a libA with ldd or otool, we see that it directly depends on OpenCV. It does not use OpenCV directly. Shouldn't link with it directly. Doesn't use its headers. That dependency should be transitive -- and yet, it isn't.

This causes a situation, where OpenCV upgrade, which should cause a rebuild of libswissknife only causes the need to rebuild/upgrade the entire dependency chain. Is there any way to avoid it?

@memsharded
Copy link
Member

However, now if we look a libA with ldd or otool, we see that it directly depends on OpenCV. It does not use OpenCV directly. Shouldn't link with it directly. Doesn't use its headers. That dependency should be transitive -- and yet, it isn't.

Can you please clarify? It is not very clear.

In any case, Conan 2.0 brings a new dependencies and graph model, that allows much better management of things like static dependencies. I'd recommend having a look to https://www.youtube.com/watch?v=kKGglzm5ous, trying things in the Conan 2.0 beta and reporting against that.

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

No branches or pull requests

3 participants