Suppose I have multiple projects A,B,C and D which depends each other on following versions.
B(v0.1) depends on A(v0.1)
C(v0.1) depends on A(v0.2)
D(v0.1) depends on B(v0.1) and C(v0.1)
And I have exported packages like this,
PackageA/0.1@demo/demo
PackageA/0.2@demo/demo
PackageB/0.1@demo/demo
PackageC/0.1@demo/demo
And when I try to create package D, I get the following warning.
WARN: Conflict in PackageC/0.1@demo/demo
Requirement PackageA/0.2@demo/demo conflicts with already defined PackageA/0.1@demo/demo
Keeping PackageA/0.1@demo/demo
To change it, override it in your base requirements
Which is understandable considering that two different versions of PackageA is referenced.
But my question is why conan has picked version 0.1 instead of picking 0.2? Shouldn't the latest version needs to be picked here?
I'm using conan version 0.28.1.
Choosing one or the other is quite arbitrary, given that you are in a version conflict. The build can error both if you go for the latest or for the previous version. The -werror command line option allows to raise an error instead of warning (just thinking, probably we want to make this the default, what do you think @lasote?).
The criteria used for conan is the requirements declared first have priority. The graph computation is depth-first, so the requirements that you declare first will be the ones that define the upstream dependencies to use.
Hi, Thanks for the quick reply.
Is there a way to guarantee all downstream projects gets the latest version of PackageA? In practice, PackageA is the Boost library. I would like to propagate Boost library release updates to downstream with smallest changes as possible.
It seems like I have following options,
First option would require a careful maintenance of the dependency graph, and the second will require to bump releases in downstream exponentially.
Any thoughts?
There are several ways to do this:
You can use rquirements overriding. The consumer always has control. So if the project defines a requirement to the Boost version you want, that is the version that will be used upstream, irrespective of the one declared in the upstream packages. This is standard procedure to resolve version conflicts. It can also override user/channel
You might try to use version ranges in packages like depending on Boost/[>1.60]@user/channel, so they will upgrade automatically when new versions are out (if using --update, or cleaning the cache). Beware of binary compatibility, you might want to learn about the package_id() method: http://docs.conan.io/en/latest/howtos/define_abi_compatibility.html
You can try to use package-creator definition of latest. So with conan alias you can define a Boost/latest@user/channel that points to the latest published version (or the one you want to consider latest for your team)
About the -werror is not the first time I think about it and probably should be an error by default. You never read the warning.
It seems like I could get it working using version ranges. Thanks!
Hello, about the versioning using semver, what if I have:
B(v0.1.0) depends on A/[>=0.1.0)]
C(v0.1.0) depends on A/[~0.1.0]
D(v0.1.0) depends on B(v0.1.0) and C(v0.1.0)
and I have packages:
PackageA/0.1.0@demo/demo
PackageA/0.2.0@demo/demo
PackageB/0.1.0@demo/demo
PackageC/0.1.0@demo/demo
With Conan 1.0 (I have Conan 1.1.0), this throws a conflict error because PackageB resolves to A(v0.2.0) and PackageA to A(v0.1.0). Shouldn't PackageB resolve to A(v0.1.0) since we have greater or equal to A(v0.1.0)?
Conan version resolution is greedy, it doesn't compute interval intersections or try to solve the joint compatibility problem (which is an NP problem).
The reason for this is that the conan dependency graphs are not unique. They can change with every configuration of input (settings, options). And the configuration can be different in different branches of the dependency graph, this makes this computation extremelly challenging and slow, not to say unfeasible.
So the computation is greedy, first B depends on A>0.1.0, which is resolved to A/0.2.0, and when the other branch via C evaluates, it finds a conflict.
To solve it, add a dependency to A/[~0.1.0] from D and the conflict should be resolved.
I've been experiencing this as well in a setup similar.
A depends on B and C.
B has a requirement D/[>=0.1,<0.4]@test/test
C has a requirement D/[>=0.3,<0.6]@test/test
D has no requirements.
Here, B and C overlap in a requirement for D v0.3. Conan instead produces the error described above. This is really misleading and is not intuitive. I shouldn't have to modify or pin A to any version of D, especially if A is supposed to be agnostic of what its dependencies are doing.
Hi @Lnk2past
The reasons are explained above, conan is not computing the SAT problem that joint compatibility of dependencies ranges define, which is an NP problem, because of the added complexity of exploding combinatorics of dependency graphs over the possible binary configurations. It is not that B has a requirement on D.1, but it could have that requirement if it is a static library, and require a different version D.2 if it is not. That makes the problem extremely difficult to solve, specially if it has to be solved in finite time. Instead of waiting for many minutes for a solution to come, failing quickly and letting the user define which version they want upstream works very well in practice.
Thanks for the feedback!