Hey folks! This seems like an interesting case that could benefit from more input, so I figured I'd highlight it for the list.
I got interested in the rpmdeplint failures for the new llvm update - https://bodhi.fedoraproject.org/updates/FEDORA-2024-e9a5fdd899 - so I started poking. rpmdeplint reports these failures:
clang18-18.1.7-5.fc42.x86_64 provides /usr/bin/clang++-18 which is also provided by clang-18.1.8-3.fc41.i686 compiler-rt18-18.1.7-3.fc42.x86_64 provides /usr/lib/clang/18/lib/x86_64-redhat-linux-gnu/clang_rt.crtbegin.o which is also provided by compiler-rt-18.1.8-2.fc41.x86_64 compiler-rt18-18.1.7-3.fc42.x86_64 provides /usr/lib/clang/18/lib/x86_64-redhat-linux-gnu/clang_rt.crtend.o which is also provided by compiler-rt-18.1.8-2.fc41.x86_64 compiler-rt18-18.1.7-3.fc42.x86_64 provides /usr/lib/clang/18/lib/x86_64-redhat-linux-gnu/libclang_rt.asan-preinit.a which is also provided by compiler-rt-18.1.8-2.fc41.x86_64 compiler-rt18-18.1.7-3.fc42.x86_64 provides /usr/lib/clang/18/lib/x86_64-redhat-linux-gnu/libclang_rt.asan.a which is also provided by compiler-rt-18.1.8-2.fc41.x86_64 compiler-rt18-18.1.7-3.fc42.x86_64 provides /usr/lib/clang/18/lib/x86_64-redhat-linux-gnu/libclang_rt.asan.so which is also provided by compiler-rt-18.1.8-2.fc41.x86_64 ... [there are lots more similar compiler-rt ones, cut for space]
libomp-19.1.0-1.fc42.x86_64 provides /usr/lib64/libarcher.so which is also provided by libomp18-18.1.7-3.fc41.x86_64 libomp-19.1.0-1.fc42.x86_64 provides /usr/lib64/libomp.so which is also provided by libomp18-18.1.7-3.fc41.x86_64 libomp-19.1.0-1.fc42.x86_64 provides /usr/lib64/libompd.so which is also provided by libomp18-18.1.7-3.fc41.x86_64
now in all cases there, the "also provided by" package is the *current* stable package, and the update contains a newer build of that package which would not conflict. So there's a clang-19 build, a compiler-rt-19 build, and a libomp18 build in the update, all of which do not conflict.
So at first I thought "obviously this behavior of rpmdeplint is wrong! It should not check for conflicts with packages that the update-under- test would replace". I wrote a PR for that...and it failed tests: https://github.com/fedora-ci/rpmdeplint/pull/21
the test it failed refers to https://bugzilla.redhat.com/show_bug.cgi?id=1502458 , which made me rethink whether this behavior of rpmdeplint is actually *wrong*. That bug specifically *wanted* rpmdeplint to catch a conflict with a package that the update would replace. It talks about a real-world case where vim-minimal and vim-common have some files in common. Now, say you have vim-minimal-1.0 on your system, but in the updates repo, there's a vim- 2.0 build with different versions of those files. If you tried to install something that depended on vim-common (but did not cause vim- minimal to be updated), it would fail, because vim-common-2.0 and vim- minimal-1.0 from your installed system would conflict. The reporter argued that rpmdeplint should've caught this and forced vim-common to add an explicit conflicts with different versions of vim-minimal, which seems kinda reasonable, honestly.
So that made me rethink whether the issue here is in the update or in rpmdeplint's behavior. True, if you have an 18 version of clang and also something that needs clang 18 installed and you just did `dnf update`, there would be no conflict: dnf would update to clang-19 and install clang18, and everything would be fine. But if you had an 18 version of clang installed and you tried to do something that, for some reason, caused clang18 to be pulled in but did *not* cause clang to be updated (maybe `dnf install clang18-devel` ?), you would hit a conflict.
So, arguably, the error here is in the package: clang18 should explicitly conflict with clang < 19, compiler-rt18 should explicitly conflict with compiler-rt < 19, libomp should explicitly conflict with libomp18 < 18.1.7-4 . (currently compiler-rt18 has an explicit conflicts with 'compiler-rt = 18', but that definitely seems wrong; I don't think that could ever be satisfied.)
What do folks think about this? Do you think the error is in the package, or in rpmdeplint's analysis? If the former, should we update the packaging guidelines to specifically cover this case (if they don't already)? If the latter, how do we change rpmdeplint's behavior, considering the request in 1502458 ?
Thanks for any thoughts!
On 22. 09. 24 1:00, Adam Williamson wrote:
So, arguably, the error here is in the package: clang18 should explicitly conflict with clang < 19, compiler-rt18 should explicitly conflict with compiler-rt < 19, libomp should explicitly conflict with libomp18 < 18.1.7-4 . (currently compiler-rt18 has an explicit conflicts with 'compiler-rt = 18', but that definitely seems wrong; I don't think that could ever be satisfied.)
I think the conflict in clang18 should actually be (clang >= 18 with clang < 19~~).
Anyway, we don't have such conflict in Pythons, we have Obsoletes.
- python3 version 3.13 has an unversioned Obsoletes for python3.13 - python3 version 3.12 has an unversioned Obsoletes for python3.12
Same for various subpackages, such as -libs or -devel.
---
The Obsoletes exists to upgrade python3.13 to python3 version 3.13 cleanly. Surely, this is desired in clang as well?
How do the Obsoletes behave in the case your describe:
When I have python3 version 3.12 installed (from before we upgraded Python to 3.13) and I run `dnf install python3.12-devel` (when the Python 3.13 upgrade is already in the repos), I get a clean, well-behaved transaction.
To reproduce, I tried this:
On Fedora 40 (e.g. in a container):
1. (optional) replace dnf with dnf5 to avoid dnf being dependent on Python 2. (optional) dnf5 remove python3-libs 3. dnf5 install python3 (installs python3 3.12.6-1.fc40) 4. dnf --releasever 41 install python3.12-devel
In both cases of doing 1-2 and not doing it, the transaction ends up as expected:
- python3 3.12 is upgraded to python3 3.13 - python3-libs 3.12 is upgraded to python3-libs 3.13 - python3.12-devel is installed - python3.12 and python3.12-libs are installed as dependencies
No transaction errors.
On Tue, 2024-09-24 at 14:50 +0200, Miro Hrončok wrote:
On 22. 09. 24 1:00, Adam Williamson wrote:
So, arguably, the error here is in the package: clang18 should explicitly conflict with clang < 19, compiler-rt18 should explicitly conflict with compiler-rt < 19, libomp should explicitly conflict with libomp18 < 18.1.7-4 . (currently compiler-rt18 has an explicit conflicts with 'compiler-rt = 18', but that definitely seems wrong; I don't think that could ever be satisfied.)
I think the conflict in clang18 should actually be (clang >= 18 with clang < 19~~).
Anyway, we don't have such conflict in Pythons, we have Obsoletes.
- python3 version 3.13 has an unversioned Obsoletes for python3.13
- python3 version 3.12 has an unversioned Obsoletes for python3.12
Same for various subpackages, such as -libs or -devel.
The Obsoletes exists to upgrade python3.13 to python3 version 3.13 cleanly. Surely, this is desired in clang as well?
I don't believe clang does builds *ahead* like Python does. These are purely *backwards-compatibility* builds. So when bumping the main package from 18 to 19, the clang18 package is created to keep things working which cannot yet work with 19.
On 24. 09. 24 18:37, Adam Williamson wrote:
On Tue, 2024-09-24 at 14:50 +0200, Miro Hrončok wrote:
On 22. 09. 24 1:00, Adam Williamson wrote:
So, arguably, the error here is in the package: clang18 should explicitly conflict with clang < 19, compiler-rt18 should explicitly conflict with compiler-rt < 19, libomp should explicitly conflict with libomp18 < 18.1.7-4 . (currently compiler-rt18 has an explicit conflicts with 'compiler-rt = 18', but that definitely seems wrong; I don't think that could ever be satisfied.)
I think the conflict in clang18 should actually be (clang >= 18 with clang < 19~~).
Anyway, we don't have such conflict in Pythons, we have Obsoletes.
- python3 version 3.13 has an unversioned Obsoletes for python3.13
- python3 version 3.12 has an unversioned Obsoletes for python3.12
Same for various subpackages, such as -libs or -devel.
The Obsoletes exists to upgrade python3.13 to python3 version 3.13 cleanly. Surely, this is desired in clang as well?
I don't believe clang does builds *ahead* like Python does. These are purely *backwards-compatibility* builds. So when bumping the main package from 18 to 19, the clang18 package is created to keep things working which cannot yet work with 19.
But at the same time, we can e.g. build clang18 on Fedora 39 today.
The Obsoletes approach works both ways.
E.g. postgresql also does it that way.
On 9/24/24 10:02, Miro Hrončok wrote:
On 24. 09. 24 18:37, Adam Williamson wrote:
On Tue, 2024-09-24 at 14:50 +0200, Miro Hrončok wrote:
On 22. 09. 24 1:00, Adam Williamson wrote:
So, arguably, the error here is in the package: clang18 should explicitly conflict with clang < 19, compiler-rt18 should explicitly conflict with compiler-rt < 19, libomp should explicitly conflict with libomp18 < 18.1.7-4 . (currently compiler-rt18 has an explicit conflicts with 'compiler-rt = 18', but that definitely seems wrong; I don't think that could ever be satisfied.)
I think the conflict in clang18 should actually be (clang >= 18 with clang < 19~~).
Anyway, we don't have such conflict in Pythons, we have Obsoletes.
- python3 version 3.13 has an unversioned Obsoletes for python3.13 - python3 version 3.12 has an unversioned Obsoletes for python3.12
Same for various subpackages, such as -libs or -devel.
The Obsoletes exists to upgrade python3.13 to python3 version 3.13 cleanly. Surely, this is desired in clang as well?
I don't believe clang does builds *ahead* like Python does. These are purely *backwards-compatibility* builds. So when bumping the main package from 18 to 19, the clang18 package is created to keep things working which cannot yet work with 19.
We may not do this now, but I don't want to rule out doing this in the future. The need for multiple versions of LLVM has increased a lot recently, and it's not hard to image a scenario where we may need to do this.
-Tom
But at the same time, we can e.g. build clang18 on Fedora 39 today.
The Obsoletes approach works both ways.
E.g. postgresql also does it that way.