Bug 37348

Summary: does not optimize out self-satisfied Requires: XXX < 0
Product: Sisyphus Reporter: Ivan Zakharyaschev <imz>
Component: rpm-buildAssignee: placeholder <placeholder>
Status: NEW --- QA Contact: qa-sisyphus
Severity: minor    
Priority: P3 CC: arseny, glebfm, imz, ldv, placeholder, vt
Version: unstable   
Hardware: all   
OS: Linux   

Description Ivan Zakharyaschev 2019-10-18 03:54:19 MSK
This dependency could be optimized out, becuase it is satisfied by Provides (according to the real behavior of rpm), but it isn't:

$ rpm -qp /ALT/Sisyphus/x86_64/RPMS.classic/python3-test-3.7.4-alt1.x86_64.rpm --provides | fgrep _testcapi
python3(_testcapi)
$ rpm -qp /ALT/Sisyphus/x86_64/RPMS.classic/python3-test-3.7.4-alt1.x86_64.rpm --requires | fgrep _testcapi
python3(_testcapi) < 0
$ 

Here is how it appears in the build log:

$ egrep -o '^Processing .*$|^(Requires|Provides): .*\(_testcapi\)' /beehive/logs/Sisyphus-x86_64/latest/success/python3-3.7.4-alt1 
Processing files: python3-3.7.4-alt1
Processing files: python3-base-3.7.4-alt1
Processing files: python3-dev-3.7.4-alt1
Processing files: libpython3-3.7.4-alt1
Processing files: python3-tools-3.7.4-alt1
Processing files: python3-modules-tkinter-3.7.4-alt1
Processing files: python3-modules-sqlite3-3.7.4-alt1
Processing files: python3-modules-curses-3.7.4-alt1
Processing files: python3-modules-nis-3.7.4-alt1
Processing files: python3-test-3.7.4-alt1
Provides: python3(_ctypes_test), python3(_testbuffer), python3(_testcapi)
Requires: python3 = 3.7.4-alt1, python3-modules-tkinter = 3.7.4-alt1, python3-modules-curses = 3.7.4-alt1, python3-modules-sqlite3 = 3.7.4-alt1, python3-tools = 3.7.4-alt1, /usr/bin/env, /usr/lib64/python3.7/Tools, /usr/lib64/python3.7/lib-dynload, libc.so.6(GLIBC_2.14)(64bit), libc.so.6(GLIBC_2.2.5)(64bit), libc.so.6(GLIBC_2.3.4)(64bit), libc.so.6(GLIBC_2.4)(64bit), libm.so.6(GLIBC_2.2.5)(64bit), libpthread.so.0(GLIBC_2.2.5)(64bit), libpython3.7m.so.1.0()(64bit) >= set:ogV8iGVEFBDV239IUOOjtxvEGuwUFBN8azfypkIIncm2iM5D87JM5Z9L2hCjH5xZeSZ8y7JmNZmYmEeShU0bY4sCeNPKwVibbpwNrhi1Zec9m73TZevFNuPsRyJwJLDPGaCCGInVNholZq2d4IBpajl37Bsww6c8lZpxU2Zlnaf7oYnuAqfDt1kCOrFKesZ5zSHqBnQGdMTrb1IZ0tfunnsmNRj1tnIHZh34ZhPuE9rDJB2QJQ29QUdwX8oieuGwOTHIcFzv1XVUiBzVZuchmMUMsQdtF4yPTCLQcBGDC2OgszLNEwQ7oFPWOxW7RZppxCz0OiB0MqO1IGSumpScpUqQhwfZEYkoZIqm861w3HOFZ0ca1x1ZvCqVpLuSx1tmRCgAeMZndQow0ZLUxWTUMUcx0Ix3jsKYhGqPimThR2SZk3teyhVHR1lJZ8jAkNR9CrkP3PkyZgo2oZyiPrhZv2sMUJIodwqD9OzWhYeUzShp4E1s6icfzMMbLDpNT5JTor3x1RGRjDVtZytWgCeQskOsrZ6FMEdSqwfVdBqPafOIp95xmGAEtrzDp4FWgwWYsrgn0RjkasPOVkvO0, python3(__future__) < 0, python3(_compat_pickle) < 0, python3(_compression) < 0, python3(_ctypes) < 0, python3(_ctypes_test) < 0, python3(_dummy_thread) < 0, python3(_multibytecodec) < 0, python3(_osx_support) < 0, python3(_pickle) < 0, python3(_py_abc) < 0, python3(_pyio) < 0, python3(_strptime) < 0, python3(_testcapi)
Processing files: python3-debuginfo-3.7.4-alt1
Processing files: python3-base-debuginfo-3.7.4-alt1
Processing files: python3-dev-debuginfo-3.7.4-alt1
Processing files: libpython3-debuginfo-3.7.4-alt1
Processing files: python3-modules-tkinter-debuginfo-3.7.4-alt1
Processing files: python3-modules-sqlite3-debuginfo-3.7.4-alt1
Processing files: python3-modules-curses-debuginfo-3.7.4-alt1
Processing files: python3-modules-nis-debuginfo-3.7.4-alt1
Processing files: python3-test-debuginfo-3.7.4-alt1
$

Compare it with a similar example with a similar dependency being actually optimized out. However, in this example, the form of Provides is XXX = set:... and the dependency is between two different suppackages (not between the package and itself):

$ egrep -o '^Processing .*$|^(Requires|Provides): .*\(certbot\)' /beehive/logs/Sisyphus-x86_64/latest/success/certbot-0.38.0-alt1 
Processing files: certbot-0.38.0-alt1
Provides: letsencrypt = 0.38.0, python3(certbot)
Processing files: certbot-apache-0.38.0-alt1
Requires: certbot = 0.38.0-alt1, python3-module-augeas, python3(acme) <= set:edzs, python3(acme.magic_typing) <= set:edzs, python3(binascii) <= set:edzs, python3(certbot)
Processing files: certbot-nginx-0.38.0-alt1
Requires: certbot = 0.38.0-alt1, python3(OpenSSL) <= set:edzs, python3(abc) <= set:edzs, python3(acme) <= set:edzs, python3(acme.magic_typing) <= set:edzs, python3(certbot)
Processing files: certbot-dns_rfc2136-0.38.0-alt1
Requires: certbot = 0.38.0-alt1, python3(certbot)
Processing files: certbot-dns_route53-0.38.0-alt1
Requires: certbot = 0.38.0-alt1, python3(acme.magic_typing) <= set:edzs, python3(boto3) <= set:edzs, python3(botocore.exceptions) <= set:edzs, python3(certbot)
$ rpm -qp /ALT/Sisyphus/noarch/RPMS.classic/certbot-apache-0.38.0-alt1.noarch.rpm --requires | fgrep certbot
certbot = 0.38.0-alt1:sisyphus+237698.4.6.1
$ 

I'm not quite sure which of the two factors plays the role of having an effect on the optimization. I suspect that the satisfaction of a Requires: XXX < 0 by versionless Provides is not implemented in the optimizer, because it is a strange behavior of the real rpm, which looks a bit like a dirty hack. (It would be even much more dirty if a versionless Provides could satisfy any versioned Requires like = N or >= N, not only < N -- I haven't tested that yet.)
Comment 1 Ivan Zakharyaschev 2019-10-18 03:55:17 MSK
rpm-build-4.0.4-alt133
Comment 2 Ivan Zakharyaschev 2019-11-12 19:04:56 MSK
(In reply to comment #0)

> I suspect that the satisfaction of a Requires: XXX < 0 by
> versionless Provides is not implemented in the optimizer, because it is a
> strange behavior of the real rpm, which looks a bit like a dirty hack. (It
> would be even much more dirty if a versionless Provides could satisfy any
> versioned Requires like = N or >= N, not only < N -- I haven't tested that
> yet.)

BTW, that's like this even for other Requires, not only < 0:

https://lists.altlinux.org/pipermail/devel/2019-November/208919.html "unversioned provides satisfy versioned requires" (at@):

Мужчины, у вас по-прежнему сабж. Я нахожу это возмутительным. Как говорил
Михаил Корлеоне, это оскорбляет мой разум.

$ rpm -q --provides glibc-core |grep libdl
libdl.so.2()(64bit) = set:hdBjS1I4gQ8BohwImELo8Zh
libdl.so.2(GLIBC_2.2.5)(64bit)
libdl.so.2(GLIBC_2.3.3)(64bit)
libdl.so.2(GLIBC_2.3.4)(64bit)
$ grep ^Requires: foo.spec
Requires: libdl.so.2(GLIBC_2.2.5)(64bit) >= set:hdBjS1I4gQ8BohwImELo8Zh
$ rpm -qpR foo-1.0-alt0.x86_64.rpm
libdl.so.2(GLIBC_2.2.5)(64bit) >= set:hdBjS1I4gQ8BohwImELo8Zh
rpmlib(SetVersions)
rpmlib(PayloadIsLzma)
$ rpm -iv --test foo-1.0-alt0.x86_64.rpm
Preparing packages...