-
Notifications
You must be signed in to change notification settings - Fork 974
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] Public and private(build_requires) dependencies #7506
Comments
Hi, @FnGyula I understand your pain and I know it is problematic in Conan right now. To handle this properly I thnk we would need to wait until Conan 2.0 which should have an improved graph model (better management of requires, visibility, better propagation depending on library type,...). Meanwhile, I can give you some advice:
|
Thanks @jgsogo ! So I always wondered the difference between GTest is more straightforward, and indeed this is how we use our unit testing frameworks. But how is that different from a libz statically linked into the binaries of the project? It doesn't alter the API or the ABI of the binaries in any way, if I build it with one version or the other. This is why I thought that the idea behind But then again, the same applies to private dependencies, though for some reason I was under the impression that they are outdated since the introduction of build_requires:
As for build requirements the key point in the documentation seems to be:
So, if the dependency fully hidden, because it's already linked into the binaries (could be a source based library too), then there's no point in installing it transitively, is there? Anyway, it's a bit confusing. Your example is compellingly short, and perhaps with using As for the host and build context, I just recently came across of this feature, I will need to read up and tinker a little bit more about it. From the sound of it though, I think it's useful for another reason, using something like |
Even if the library is totally embedded (doesn't modify the ABI), it still implements some behavior. In your DLL you want to get a different binary (a different package-id) when you embed one version or the other... even if they are embedded, they behave differently, they have different bugs. If the package-id is exactly the same you cannot know which version of the embedded library you are using. The two profiles are useful to distinguish between the libraries you are building and the tools you are using. Conan doesn't propagate exactly the same information from packages that belong to the host context (here you will link with them) or packages in the build context (you only use them). Typically this is more evident in a cross-building scenario, you are building your project for Android linking with |
Now you left me really confused :) The package_id has multiple modes to be calculated, but the default is that the major version number is taken. That I figured, was a sensible default since I don't care which Python 2.7.x I'm building against for the compatibility of my package that depends on Python 2.7.x. So that means that the package id isn't intended to describe the exact build, it intended to describe compatibility. There's a build_id which I haven't used yet, but that might be useful to distiniguish between different artifacts in the cache. To me, the whole package id, hidden deps, etc. are basically a way to reduce the pain of rebuilding the world updates where you don't need to do so. If I know that zlib produces compatible compressed artifacts between versions, I'm totally comfortable to keep my Python called the same package id no matter if it is zlib 1.2.11 or 1.2.10 it has been built against statically. Mind, that the project I'm working on has it all: Qt, Python, Boost, VXL, and 40 others, so we try to minimise the rebuild the world time, when we can. Else, building everything from source in one build would be the safest bet. |
The default mode for package ID is One of the purposes of package-id is ABI compatibility, that's for sure, and for an embedded library, regarding ABI, you don't care about the version embedded inside your DLL. Nevertheless, other users consider it very important to control which version of every requirement is used in the graph, even if they have to rebuild the world again and again (it is a compromise). This is the main motivation for other packages IDs, not only to control the ABI, but also the versions of every piece of code compiled into a binary. |
@jgsogo So the system I'm working with isn't designed to rebuild the world. That's where I'm coming from. Coming back to the question: what is the definitional difference really between |
@FnGyula Maybe your project uses cmake to build, you want the cmake executable to run on Windows, not Android. If your project privately embeds a static library, you want that static library to be built for Android and not Windows. The former is a Generally speaking, |
Thanks @ohanar the explanation. Now onto changing my build_requires to private deps :) |
Didn't mean to close it... I did try to change our dependencies to use private instead of build_requires, but that turned out to be plain wrong. The problem with private requirements that they are still downloaded for any consumer for the package, which is absolutely not needed for static libraries already linked into the binaries. My guess here is that the private requirements are more of a hint for the generator, so it can generate things like PRIVATE CMake dependencies. So, overall, what I need is something like
The assumption that Overall, I do believe that the private/build_requires system needs a big refurbishment! |
See also #7016. Indeed there are a good number of issues with build_requires and even more so with private requires. These are intended to be addressed with Conan 2.0. With build_requires in particular, a goal is to have a completely decoupled dependency graph from normal requires. You can opt-in to an experimental version of this behavior presently by using separate build and host profiles, but you should note that various behavior changes when you do so. In particular, you can't readily link against build_requires, because they might not be valid for the host machine (see example in my previous comment). In other words, the current soft wall between requires vs build requires will become a hard wall in Conan 2.0. |
Hi, @FnGyula I can subscribe to everything @ohanar has said in previous comments. The concept of build-requires vs requires will work as described: build-requires are intended to run in the build-machine (CMake, protoc, GCC,...) while requires are the libraries (or other executables) that will be compiled for the host-machine. You can't link to a build-requires, and build-requires won't propagate linking/include information, only environment. I totally agree that require-private and the Conan graph require a big refurbishment and it is our intention to address it for Conan 2.0. We haven't defined the scope of this refurbishment yet, but we will consider things like the ones you mentioned, things related to visibility (public, private), consequences derived from linking (shared, static), DLL Hell problem,... We will start thinking about it soon, but it is something we cannot add to Conan 1.x, if we change the graph model it will likely break current behavior. |
I just had the same issue, missing |
Hi all! This has been a challenging feature for Conan 1.X, but we are designing Conan 2.0 to account for this. Regular library dependencies will not need to be we have also already done a lot of preliminary work and proof of concepts for these for |
Yeah would be awesome if the private require also cuts off the dependency graph for the consumer like build_require is doing 😄 One more finding is: We have a private require (Pkg A -private-> Pkg B) and generate a lockfile for our overall product. The lockfile is used on customer side to install all our packages (including Pkg B). After the installation in the local cache the remotes are disabled to ensure no interference. We have now some points here
|
This was solved some time ago by the new graph model in 2.0, to be released soon, so closing this issue. |
With regard to static and shared libraries, there's a simple rule of how I generally decide when is a dependency should be transitive:
build_requires
(which I'm not entirely sure if I prefer to private, but that's for later).build_requires
.Now, all is good so far because for most of our packages we had a single way to build them, either shared or not. However, as things taking off, the realisation set in, that basically we can't make that decision easily ahead of time, because if I build all our libraries as shared and static, then I have to write the same code over and over in the recipes:
Other than being ugly, it defeats ODR (need to evaluate the same condition in two different methods, it also makes the nice and declarative feeling of
requires
andbuild_requires
restricted to pretty much header-only libraries (unless that also depends on an option, like for boost).It feels like that this is something to be addressed in conan itself, but I don't know how to do this right, tbh. But this makes the recipes bloated and I need to re-do all requirements for all my recipes to get this right. Any ideas, how to handle this better?
The text was updated successfully, but these errors were encountered: