diff options
author | Sam James <sam@gentoo.org> | 2023-09-04 16:38:18 +0100 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2023-12-10 22:01:48 +0000 |
commit | af550b8b5cb91f27b26d6800c3b4cdd2d86a46e6 (patch) | |
tree | 5cedec748f249aa4ce83780a3ef83936a4ff727e /lib/_emerge/depgraph.py | |
parent | ebuild: refactor flushing vdb keys (diff) | |
download | gentoo-portage-af550b8b5cb91f27b26d6800c3b4cdd2d86a46e6.tar.xz gentoo-portage-af550b8b5cb91f27b26d6800c3b4cdd2d86a46e6.zip |
ebuild: inject implicit libc RDEPEND
Inject >=${LIBC_PROVIDER}-${VERSION_OF_LIBC_PROVIDER} into RDEPEND.
We already try to upgrade the virtual/libc provider and its deps aggressively
but that's not so helpful if there's a binpkg for, say, one of its deps available
built against a newer glibc - which ends up breaking the system because our
glibc isn't new enough (symbol versioning).
This is a long-standing problem for binpkg users and one of the last showstoppers
for being able to use them reliably.
Note that this applies to source installs too, although it matters less there;
it'll make downgrading libc a bit harder for people who want to do that, but users
are already prevented from doing that (pkg_* check) for glibc, and I don't really
see it as a bad thing to effectively propagate this to other libcs.
To fully solve the problem, we should arguably do at least one of the following:
1) Implicit >= on anything (not just libc) which installs ELF (at least a PROVIDES);
2) Implement the suggestion in bug #753500 based on analysis of used versioned symbols (*).
But libc is really the critical one and the one where things explode pretty badly,
especially combined with us trying to Do The Right Thing for non-binpkg cases
(aggressively upgrading libc before anything else). The other cases don't matter
so much as they get upgraded later and by that point, the library is usually done.
(It's not really clear if downgrading musl works and even if it is supported,
I'm not really sure it's a supported case at all, so I'm not bothering to carve
out an exception here. It'd make this far less elegant and I don't see any benefit
to doing so.)
(*) util-linux is one of the examples I have in mind here as justification
for either point.
Bug: https://bugs.gentoo.org/753500
Bug: https://bugs.gentoo.org/913628
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'lib/_emerge/depgraph.py')
-rw-r--r-- | lib/_emerge/depgraph.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index 59c78c73543..4612ac2049b 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -36,6 +36,7 @@ from portage.dep import ( match_from_list, _repo_separator, ) +from portage.dep.libc import find_libc_deps, strip_libc_deps from portage.dep._slot_operator import ignore_built_slot_operator_deps, strip_slots from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use, _get_eapi_attrs from portage.exception import ( @@ -2984,6 +2985,19 @@ class depgraph: else: depvars = Package._runtime_keys + eroot = pkg.root_config.settings["EROOT"] + try: + libc_deps = self._frozen_config._libc_deps_cache[eroot] + except (AttributeError, KeyError) as e: + if isinstance(e, AttributeError): + self._frozen_config._libc_deps_cache = {} + + self._frozen_config._libc_deps_cache[eroot] = find_libc_deps( + self._frozen_config._trees_orig[eroot]["vartree"].dbapi, + False, + ) + libc_deps = self._frozen_config._libc_deps_cache[eroot] + # Use _raw_metadata, in order to avoid interaction # with --dynamic-deps. try: @@ -2996,6 +3010,10 @@ class depgraph: token_class=Atom, ) strip_slots(dep_struct) + # This strip_libc_deps call is done with non-realized deps; + # we can change that later if we're having trouble with + # matching/intersecting them. + strip_libc_deps(dep_struct, libc_deps) built_deps.append(dep_struct) except InvalidDependString: changed = True @@ -3009,6 +3027,10 @@ class depgraph: token_class=Atom, ) strip_slots(dep_struct) + # This strip_libc_deps call is done with non-realized deps; + # we can change that later if we're having trouble with + # matching/intersecting them. + strip_libc_deps(dep_struct, libc_deps) unbuilt_deps.append(dep_struct) changed = built_deps != unbuilt_deps |