-
Notifications
You must be signed in to change notification settings - Fork 365
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
Is defining ABI compatibility in the producer instead of the consumer possible/desired? #3153
Comments
Indeed it is an interesting idea to explore, I am not saying it is not. How packages could define a versioning scheme themselves, and how that could be used by consumers regarding ABI. However, I think the ABI compatibility regarding dependencies, it cannot be fully defined in the producer. E.g.:
In short: PkgA cannot say, in a general way: for every change X in my version number, force my consumers to create a new binary We have some ideas to start modeling high-level relations in the dependency graph, like header-libs, static-libs, shared-libs, and better models of private, transitive, etc. |
Thank you James (and Diego on Slack) for the explanations, they clarify why the consumer is at the moment in charge of overriding the ABI compatibility. However, even without switching to a high level model with conan 2.0, I think that a first step towards defining ABI compatibility in the producer might be worthwhile for the current conan. In particular, the reason why I started to look into the ABI compatibility settings is that one of my builds broke because conan picked up an old package instead of rebuilding it against the new (overridden) dependency. At first, I thought that it might happened due to a bug but then realized that it is actually the ABI compatibility feature which assumes that semver is used by default. Unfortunately, this particular library dependency does not use semver and provides absolutely no ABI compatibility guarantees between versions. Currently, it seems that the only way to fix this particular problem is to modify all consumers which is not very nice and error prone. What I imagine instead is something like a |
Read conan-io/conan#4640 for further arguments. |
Allow packages to publish their suggestion for the default caseI agree with the decision that a consumer needs the full flexibility to define how it views changes to the producer, but I think today by default, with no changes or As I've learned the hard way, this is actually a pretty strong assumption. I think it might be very useful if a package could publish the default consumers should assume, which could be overriden (or not) by the consumer's |
I am also inclined to say that packages themselves should provide ability to the end user about whats their 'minimal' compatibility. I think boost is a good example here. Right now I am forced to go to every package that uses boost and say that boost has a 'major_versioning' otherwise i can very easily end up in undefined behavior - where one package depends on boost X and one on boost Y. You could argue that i could change globally the setting. unfortunatelly I cnanot do that, as this is a requirement of some of application in our system - we do use semver there. |
No, this is not possible. Version conflics are checked, unless you use some not-recommended way of using boost as build-requires or private, it is not possible to depend on different versions of the same package. The major, minor, patch things that are involved in things like
Then, by definition of how linking works in C and C++, a package cannot define by itself how it affects the consumers, but it is on the relation, how the consumers use the package what defines whenever it is necessary to build a new binary or not. For Conan 2.0 we will try to improve the default definition of |
Sorry, I had few inconsistencies in my post. we are using boost in a normal way, just put it in requires no build-requires nor private. let me share you with todays example i had:
New version of boost is out - and we are using here the Since we depend on boost in Therefore we would end up with: Therefore we are left with two choices.
|
I think that the Boost libraries are a great example of the limitations of the current (semver-mode by default, overridable only per-consumer or globally) model. The situation with ABI stability in the modern C++ world is very complicated, and there are many misconceptions and misunderstandings out there. For example, the following is, unfortunately, wrong in some (most?) common cases:
The most important rule for C++ ABI stability is One Definition Rule: in short, almost any entity with a global name should have an exactly-equivalent definition in all cpp files linked together, else the behavior of the whole program is undefined (which is usually quite bad). The language-level definitions knows nothing of the platform specific things like shared libraries, but I've tried to summarize the platform specifics:
So, the Boost library collection:
So, I'm afraid, by default, unless extra careful measures or platform restrictions (Windows-only, for example) are in place, all the code in a single executable must come from a exactly the same single Boost version. And all Boost-depending code should always be rebuilt when upgrading Boost, unless the Boost dependency is completely isolated to some some subgraph, and the said subgraph is isolated at least at the level of shared library with hidden visibility, leaking no Boost symbols outside. So, if I understand it correctly, the only safe way to depend on Boost in Conan is by using Unfortunately, C++ libraries like Qt that have an explicit ABI stability policy are the exception in the modern C++ ecosystem, not the norm. The default rules almost work for them (except the unexpected downgrade problem), but lead to silent failures in other cases. |
Having read through these issues, I feel that the following could solve the problem while also retaining consumer control of the package_mode:
Or even more passive and easy-to-implement: each package could add a public abi_compatibility_model property which consuming packages could check, if they want, and use this information to judge what package_mode to use for each of its dependencies. Default behaviour could be kept as it is. |
2 years later, still curious about this. Is this something that is possible in Conan 2.0? |
Yes, this was implemented in Conan 2.0.
Are the class attribute that allow defining the modes in which consumers will use it. |
This has been now documented as attributes and in the binary compatibility section, closing as solved |
As far as I understood, by default, conan assumes that dependencies follow semantic versioning and that I can override the default in the
package_id
method of the consuming recipe. (see https://docs.conan.io/en/latest/creating_packages/define_abi_compatibility.html#versioning-schema)However, when a package does not follow semver, does this mean that every consuming recipe has to override the versioning scheme or is there a possibility to define this directly within the package?
For reference, I had the following discussion with Hipony (Thank you!) on Slack who encouraged me to open this issue:
The text was updated successfully, but these errors were encountered: