compiler.version semantics and GCC/Clang versioning quirks
See original GitHub issueConan currently uses MAJOR.MINOR
as the compiler.version
ABI compatibility key for GCC/Clang, and this key is included in package_id
by default. As far as I understand, this choice is a reasonable compromise: it allows seamlessly upgrading, for example, GCC 4.7.2 to GCC 4.7.3 (which is a bugfix-only release, with no new features), and distinguishes packages built with GCC 4.7 and 4.8 (a normal release with many new features, so the user could care about that). The same logic applies to Clang versioning scheme.
But recently, both GCC >= 5 and Clang >= 4 have changed the semantics of their version numbers. Now major version number will increase on any non-bugfix release. While Clang made their versioning change backwards-compatible (there will be no Clang 4.1.x or 5.1.x ever, just X.0.Y), GCC took a different approach: GCC 5.2 is a small bugfix release to 5.1 (and there is no 5.0 release, but that does not matter much).
So, using the current default compiler.version
detection has entirely different and surprising behavior on GCC >= 5. You cannot reuse binary packages over a bugfix-only compiler version difference, and the cmake generator even checks that actual compiler version matches compiler.version
, which prohibits using compiler.version=6.2
as the equality class for GCC 6.x
. It could be patched individually for each package (including all dependencies) by manually specifying compiler.version=6
in package_id
method, but this is a laborious workaround.
I would argue that the default behavior should be specified in terms of having more or less the same semantics on all compilers, not by just enforcing a formal rule with MAJOR.MINOR
. In case of GCC, that would require making compiler.version
equal X
for GCC X.Y where X >= 5
, and adjusting compiler version checks to handle more flexible version comparison. The same could be done for Clang >= 4, but luckily X.0
would still work just fine.
I understand that there could be some backwards compatibility concerns over changing the default compiler detection logic. At the very least, making the suggested behavior a global configuration opt-in would make adoption of Conan at my company much easier (GCC 5.x and 6.x are widely used here).
Issue Analytics
- State:
- Created 6 years ago
- Comments:13 (11 by maintainers)
We are facing this while upgrading some packages and updating conan-package-tools.
Indeed it is a bit of inconvenience, because minors are being frequently released, and the bad thing is that distros are just replacing the old one, like gcc 7.1 with the new gcc 7.2, so it is no longer easy to install 7.1 at all (in fact, it seems rather complicated).
We are thinking to do the next changes to conan:
settings.yml
Doing this we would achieve what was already achieved with older gcc 4.9.X versions, in which the compiler could be updated without issues, and packages were compatible.
Hi, Adam nice to read you! To summarize, the purposed behavior is:
compiler.version=7
(same for 5, 6 and 7, same for clang >=4) (For conan devs: Requires a little new feature in the detect.py module)settings.yml
will contain 5,6,7 as valid versions of gcc, keeping the existing ones too. (For conan devs: Requires changing the default template for settings.yml)compiler.version=7
conan will generate a different binary package, won’t reuse any package already created forcompiler.version=7.1
. It doesn’t require any new feature in Conan, is the normal behavior.compiler.version=7
and the detected compiler is7.1
. (For conan devs: It requires changing a little the compiler check in conan.)compiler.version=7.1
and the detected compiler is7.1
, but will complain if the minor doesn’t match.compiler.version=7
packages without any difference, because the specified setting is the same, 7.