commit:     4b7e34b956d910b3723354b9351d21d8f010788f
Author:     Michael Haubenwallner <haubi <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 18 14:08:44 2017 +0000
Commit:     Michael Haubenwallner <haubi <AT> gentoo <DOT> org>
CommitDate: Mon Sep 18 14:08:44 2017 +0000
URL:        https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=4b7e34b9

sys-apps/portage: bump prefix-chaining.patch

Package-Manager: Portage-2.3.8-prefix, Repoman-2.3.3

 .../files/portage-2.3.8-prefix-chaining.patch      | 927 +++++++++++++++++++++
 sys-apps/portage/portage-2.3.8.ebuild              |   2 +-
 2 files changed, 928 insertions(+), 1 deletion(-)

diff --git a/sys-apps/portage/files/portage-2.3.8-prefix-chaining.patch 
b/sys-apps/portage/files/portage-2.3.8-prefix-chaining.patch
new file mode 100644
index 0000000000..036d022191
--- /dev/null
+++ b/sys-apps/portage/files/portage-2.3.8-prefix-chaining.patch
@@ -0,0 +1,927 @@
+From 448d210bb312ed0930763376d5182ebfbed1abd8 Mon Sep 17 00:00:00 2001
+From: Michael Haubenwallner <[email protected]>
+Date: Thu, 23 Mar 2017 13:52:32 +0100
+Subject: [PATCH] add prefix-chaining support
+
+---
+ bin/install-qa-check.d/05prefix                    | 30 ++++++-
+ bin/phase-helpers.sh                               | 28 ++++++
+ pym/_emerge/actions.py                             |  6 +-
+ pym/_emerge/depgraph.py                            | 51 ++++++-----
+ pym/_emerge/resolver/output.py                     | 40 ++++++++-
+ pym/portage/_sets/__init__.py                      |  5 ++
+ pym/portage/const.py                               |  6 ++
+ pym/portage/dbapi/vartree.py                       | 34 ++++++--
+ pym/portage/dep/dep_check.py                       | 99 +++++++++++++++++++++-
+ .../package/ebuild/_config/LocationsManager.py     |  3 +
+ pym/portage/package/ebuild/config.py               | 62 ++++++++++++++
+ pym/portage/package/ebuild/doebuild.py             | 24 +++++-
+ pym/portage/package/ebuild/fetch.py                |  4 +
+ pym/portage/sync/controller.py                     | 27 +++---
+ pym/portage/util/_dyn_libs/LinkageMapELF.py        |  4 +-
+ 15 files changed, 376 insertions(+), 47 deletions(-)
+
+diff --git a/bin/install-qa-check.d/05prefix b/bin/install-qa-check.d/05prefix
+index 32561e2..0c11473 100644
+--- a/bin/install-qa-check.d/05prefix
++++ b/bin/install-qa-check.d/05prefix
+@@ -79,16 +79,42 @@ install_qa_check_prefix() {
+               # unprefixed shebang, is the script directly in $PATH or an init
+               # script?
+               if [[ ":${PATH}:${EPREFIX}/etc/init.d:" == *":${fp}:"* ]] ; then
+-                      if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; 
then
++                      
all_epfs="$PORTAGE_READONLY_EPREFIXES:$EPREFIX:$EROOT:$ED"
++                      save_IFS=$IFS
++                      IFS=:
++                      epfs=( $all_epfs )
++                      IFS=$save_IFS
++
++                      found=
++                      for x in "${epfs[@]}"; do
++                              [[ -z "${x}" ]] && continue
++                              check="${x}${line[0]}"
++
++                              # might already contain a prefix
++                              if [[ "${line[0]}" == "${x}"* ]]; then
++                                      check="${line[0]}"
++                              fi
++
++                              if [[ -e ${check} ]]; then
++                                      found="${check}"
++                              fi
++                      done
++
++                      if [[ -n ${found} ]] ; then
+                               # is it unprefixed, but we can just fix it 
because a
+                               # prefixed variant exists
+                               eqawarn "prefixing shebang of ${fn#${D}}"
++
++                              if [[ ${found} == "${ED}"* || ${found} == 
"${EROOT}"* ]]; then
++                                      found="${EPREFIX}${line[0]}"
++                              fi
++
+                               # statement is made idempotent on purpose, 
because
+                               # symlinks may point to the same target, and 
hence the
+                               # same real file may be sedded multiple times 
since we
+                               # read the shebangs in one go upfront for 
performance
+                               # reasons
+-                              sed -i -e '1s:^#! 
\?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
++                              sed -i -e '1s:^#! 
\?'"${line[0]}"':#!'"${found}"':' "${rf}"
+                               continue
+                       else
+                               # this is definitely wrong: script in $PATH and 
invalid shebang
+diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
+index b28fd92..dcfd263 100644
+--- a/bin/phase-helpers.sh
++++ b/bin/phase-helpers.sh
+@@ -867,6 +867,10 @@ has_version() {
+               "${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" has_version 
"${eroot}" "${atom}"
+       fi
+       local retval=$?
++      if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++              ${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' EPYTHON= 
'${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' has_version 
'${READONLY_EPREFIX%:*}' '${atom}'"
++              retval=$?
++      fi
+       case "${retval}" in
+               0|1)
+                       return ${retval}
+@@ -926,6 +930,10 @@ best_version() {
+               "${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" best_version 
"${eroot}" "${atom}"
+       fi
+       local retval=$?
++      if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++              ${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' EPYTHON= 
'${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' best_version 
'${READONLY_EPREFIX%:*}' '${atom}'"
++              retval=$?
++      fi
+       case "${retval}" in
+               0|1)
+                       return ${retval}
+@@ -1166,6 +1174,10 @@ if ___eapi_has_master_repositories; then
+                       output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" 
master_repositories "${EROOT}" "${repository}")
+               fi
+               retval=$?
++              if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++                      output=$(${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' 
EPYTHON= '${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' master_repositories 
'${READONLY_EPREFIX%:*}' '${repository}'")
++                      retval=$?
++              fi
+               [[ -n ${output} ]] && echo "${output}"
+               case "${retval}" in
+                       0|1)
+@@ -1197,6 +1209,10 @@ if ___eapi_has_repository_path; then
+                       output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" 
get_repo_path "${EROOT}" "${repository}")
+               fi
+               retval=$?
++              if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++                      output=$(${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' 
EPYTHON= '${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' repository_path 
'${READONLY_EPREFIX%:*}' '${repository}'")
++                      retval=$?
++              fi
+               [[ -n ${output} ]] && echo "${output}"
+               case "${retval}" in
+                       0|1)
+@@ -1227,6 +1243,10 @@ if ___eapi_has_available_eclasses; then
+                       output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" 
available_eclasses "${EROOT}" "${repository}")
+               fi
+               retval=$?
++              if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++                      output=$(${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' 
EPYTHON= '${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' available_eclasses 
'${READONLY_EPREFIX%:*}' '${repository}'")
++                      retval=$?
++              fi
+               [[ -n ${output} ]] && echo "${output}"
+               case "${retval}" in
+                       0|1)
+@@ -1257,6 +1277,10 @@ if ___eapi_has_eclass_path; then
+               else
+                       output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" 
eclass_path "${EROOT}" "${repository}" "${eclass}")
+               fi
++              if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++                      output=$(${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' 
EPYTHON= '${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' eclass_path 
'${READONLY_EPREFIX%:*}' '${repository}' '${eclass}'")
++                      retval=$?
++              fi
+               retval=$?
+               [[ -n ${output} ]] && echo "${output}"
+               case "${retval}" in
+@@ -1288,6 +1312,10 @@ if ___eapi_has_license_path; then
+               else
+                       output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" 
license_path "${EROOT}" "${repository}" "${license}")
+               fi
++              if [[ ${retval} -eq 1 && -n ${READONLY_EPREFIX} ]]; then
++                      output=(${SHELL} -c "EPREFIX='${READONLY_EPREFIX%:*}' 
EPYTHON= '${PORTAGE_BIN_PATH}/ebuild-helpers/portageq' license_path 
'${READONLY_EPREFIX%:*}' '${repository}' '${license}'")
++                      retval=$?
++              fi
+               retval=$?
+               [[ -n ${output} ]] && echo "${output}"
+               case "${retval}" in
+diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py
+index 1d37d0e..2b185ef 100644
+--- a/pym/_emerge/actions.py
++++ b/pym/_emerge/actions.py
+@@ -39,7 +39,7 @@ from portage import os
+ from portage import shutil
+ from portage import eapi_is_supported, _encodings, _unicode_decode
+ from portage.cache.cache_errors import CacheError
+-from portage.const import EPREFIX
++from portage.const import EPREFIX, BPREFIX
+ from portage.const import GLOBAL_CONFIG_PATH, VCS_DIRS, 
_DEPCLEAN_LIB_CHECK_DEFAULT
+ from portage.const import SUPPORTED_BINPKG_FORMATS, TIMESTAMP_FORMAT
+ from portage.dbapi.dep_expand import dep_expand
+@@ -65,6 +65,7 @@ from portage.util.SlotObject import SlotObject
+ from portage.util._async.run_main_scheduler import run_main_scheduler
+ from portage.util._async.SchedulerInterface import SchedulerInterface
+ from portage.util._eventloop.global_event_loop import global_event_loop
++from portage.util._path import exists_raise_eaccess
+ from portage._global_updates import _global_updates
+ from portage.sync.old_tree_timestamp import old_tree_timestamp_warn
+ from portage.localization import _
+@@ -2659,6 +2660,9 @@ def missing_sets_warning(root_config, missing_sets):
+       if portage.const.EPREFIX:
+               global_config_path = os.path.join(portage.const.EPREFIX,
+                               portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep))
++              if not exists_raise_eaccess(global_config_path) and 
portage.const.BPREFIX:
++                      global_config_path = os.path.join(portage.const.BPREFIX,
++                    portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep))
+       msg.append("        This usually means that '%s'" % \
+               (os.path.join(global_config_path, "sets/portage.conf"),))
+       msg.append("        is missing or corrupt.")
+diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
+index 76f1370..8f681d6 100644
+--- a/pym/_emerge/depgraph.py
++++ b/pym/_emerge/depgraph.py
+@@ -3180,23 +3180,24 @@ class depgraph(object):
+                               edepend["HDEPEND"] = ""
+ 
+               deps = (
+-                      (depend_root, edepend["DEPEND"],
++                      (depend_root, "DEPEND",
+                               self._priority(buildtime=True,
+                               optional=(pkg.built or ignore_depend_deps),
+                               ignored=ignore_depend_deps)),
+-                      (self._frozen_config._running_root.root, 
edepend["HDEPEND"],
++                      (self._frozen_config._running_root.root, "HDEPEND",
+                               self._priority(buildtime=True,
+                               optional=(pkg.built or ignore_hdepend_deps),
+                               ignored=ignore_hdepend_deps)),
+-                      (myroot, edepend["RDEPEND"],
++                      (myroot, "RDEPEND",
+                               self._priority(runtime=True)),
+-                      (myroot, edepend["PDEPEND"],
++                      (myroot, "PDEPEND",
+                               self._priority(runtime_post=True))
+               )
+ 
+               debug = "--debug" in self._frozen_config.myopts
+ 
+-              for dep_root, dep_string, dep_priority in deps:
++              for dep_root, dep_type, dep_priority in deps:
++                              dep_string = edepend[dep_type]
+                               if not dep_string:
+                                       continue
+                               if debug:
+@@ -3234,7 +3235,7 @@ class depgraph(object):
+ 
+                               try:
+                                       dep_string = 
list(self._queue_disjunctive_deps(
+-                                              pkg, dep_root, dep_priority, 
dep_string))
++                                              pkg, dep_root, dep_priority, 
dep_string, dep_type))
+                               except portage.exception.InvalidDependString as 
e:
+                                       if pkg.installed:
+                                               
self._dynamic_config._masked_installed.add(pkg)
+@@ -3249,14 +3250,14 @@ class depgraph(object):
+ 
+                               if not self._add_pkg_dep_string(
+                                       pkg, dep_root, dep_priority, dep_string,
+-                                      allow_unsatisfied):
++                                      allow_unsatisfied, dep_type):
+                                       return 0
+ 
+               self._dynamic_config._traversed_pkg_deps.add(pkg)
+               return 1
+ 
+       def _add_pkg_dep_string(self, pkg, dep_root, dep_priority, dep_string,
+-              allow_unsatisfied):
++              allow_unsatisfied, dep_type=None):
+               _autounmask_backup = self._dynamic_config._autounmask
+               if dep_priority.optional or dep_priority.ignored:
+                       # Temporarily disable autounmask for deps that
+@@ -3265,7 +3266,7 @@ class depgraph(object):
+               try:
+                       return self._wrapped_add_pkg_dep_string(
+                               pkg, dep_root, dep_priority, dep_string,
+-                              allow_unsatisfied)
++                              allow_unsatisfied, dep_type)
+               finally:
+                       self._dynamic_config._autounmask = _autounmask_backup
+ 
+@@ -3301,7 +3302,7 @@ class depgraph(object):
+                       not slot_operator_rebuild
+ 
+       def _wrapped_add_pkg_dep_string(self, pkg, dep_root, dep_priority,
+-              dep_string, allow_unsatisfied):
++              dep_string, allow_unsatisfied, dep_type=None):
+               if isinstance(pkg.depth, int):
+                       depth = pkg.depth + 1
+               else:
+@@ -3325,7 +3326,7 @@ class depgraph(object):
+               try:
+                       selected_atoms = self._select_atoms(dep_root,
+                               dep_string, myuse=self._pkg_use_enabled(pkg), 
parent=pkg,
+-                              strict=strict, priority=dep_priority)
++                              strict=strict, priority=dep_priority, 
dep_type=dep_type)
+               except portage.exception.InvalidDependString:
+                       if pkg.installed:
+                               self._dynamic_config._masked_installed.add(pkg)
+@@ -3623,7 +3624,7 @@ class depgraph(object):
+                                       child_pkgs.sort()
+                               yield (atom, child_pkgs[-1])
+ 
+-      def _queue_disjunctive_deps(self, pkg, dep_root, dep_priority, 
dep_struct):
++      def _queue_disjunctive_deps(self, pkg, dep_root, dep_priority, 
dep_struct, dep_type=None):
+               """
+               Queue disjunctive (virtual and ||) deps in 
self._dynamic_config._dep_disjunctive_stack.
+               Yields non-disjunctive deps. Raises InvalidDependString when
+@@ -3632,33 +3633,33 @@ class depgraph(object):
+               for x in dep_struct:
+                       if isinstance(x, list):
+                               if x and x[0] == "||":
+-                                      self._queue_disjunction(pkg, dep_root, 
dep_priority, [x])
++                                      self._queue_disjunction(pkg, dep_root, 
dep_priority, [x], dep_type)
+                               else:
+                                       for y in self._queue_disjunctive_deps(
+-                                              pkg, dep_root, dep_priority, x):
++                                              pkg, dep_root, dep_priority, x, 
dep_type):
+                                               yield y
+                       else:
+                               # Note: Eventually this will check for 
PROPERTIES=virtual
+                               # or whatever other metadata gets implemented 
for this
+                               # purpose.
+                               if x.cp.startswith('virtual/'):
+-                                      self._queue_disjunction(pkg, dep_root, 
dep_priority, [x])
++                                      self._queue_disjunction(pkg, dep_root, 
dep_priority, [x], dep_type)
+                               else:
+                                       yield x
+ 
+-      def _queue_disjunction(self, pkg, dep_root, dep_priority, dep_struct):
++      def _queue_disjunction(self, pkg, dep_root, dep_priority, dep_struct, 
dep_type=None):
+               self._dynamic_config._dep_disjunctive_stack.append(
+-                      (pkg, dep_root, dep_priority, dep_struct))
++                      (pkg, dep_root, dep_priority, dep_struct, dep_type))
+ 
+       def _pop_disjunction(self, allow_unsatisfied):
+               """
+               Pop one disjunctive dep from 
self._dynamic_config._dep_disjunctive_stack, and use it to
+               populate self._dynamic_config._dep_stack.
+               """
+-              pkg, dep_root, dep_priority, dep_struct = \
++              pkg, dep_root, dep_priority, dep_struct, dep_type = \
+                       self._dynamic_config._dep_disjunctive_stack.pop()
+               if not self._add_pkg_dep_string(
+-                      pkg, dep_root, dep_priority, dep_struct, 
allow_unsatisfied):
++                      pkg, dep_root, dep_priority, dep_struct, 
allow_unsatisfied, dep_type):
+                       return 0
+               return 1
+ 
+@@ -4511,7 +4512,7 @@ class depgraph(object):
+               return self._select_atoms_highest_available(*pargs, **kwargs)
+ 
+       def _select_atoms_highest_available(self, root, depstring,
+-              myuse=None, parent=None, strict=True, trees=None, 
priority=None):
++              myuse=None, parent=None, strict=True, trees=None, 
priority=None, dep_type=None):
+               """This will raise InvalidDependString if necessary. If trees is
+               None then self._dynamic_config._filtered_trees is used."""
+ 
+@@ -4534,6 +4535,13 @@ class depgraph(object):
+               pkgsettings = self._frozen_config.pkgsettings[root]
+               if trees is None:
+                       trees = self._dynamic_config._filtered_trees
++
++              # this one is needed to guarantee good readonly root
++              # resolution display in the merge list. required since
++              # parent (below) can be None
++              trees[root]["disp_parent"] = parent
++
++
+               mytrees = trees[root]
+               atom_graph = digraph()
+               if True:
+@@ -4565,7 +4573,7 @@ class depgraph(object):
+ 
+                               mycheck = portage.dep_check(depstring, None,
+                                       pkgsettings, myuse=myuse,
+-                                      myroot=root, trees=trees)
++                                      myroot=root, trees=trees, 
dep_type=dep_type)
+                       finally:
+                               # restore state
+                               self._dynamic_config._autounmask = 
_autounmask_backup
+@@ -4641,6 +4649,7 @@ class depgraph(object):
+                                                       continue
+                                               node_stack.append((child_node, 
node, child_atom))
+ 
++              trees[root].pop("disp_parent")
+               return selected_atoms
+ 
+       def _expand_virt_from_graph(self, root, atom):
+diff --git a/pym/_emerge/resolver/output.py b/pym/_emerge/resolver/output.py
+index e993ce1..32a942c 100644
+--- a/pym/_emerge/resolver/output.py
++++ b/pym/_emerge/resolver/output.py
+@@ -22,11 +22,12 @@ from portage.localization import localized_size
+ from portage.package.ebuild.config import _get_feature_flags
+ from portage.package.ebuild._spawn_nofetch import spawn_nofetch
+ from portage.output import ( blue, colorize, create_color_func,
+-      darkblue, darkgreen, green, nc_len, teal)
++      darkblue, darkgreen, green, nc_len, teal, yellow, turquoise)
+ bad = create_color_func("BAD")
+ from portage._sets.base import InternalPackageSet
+ from portage.util import writemsg_stdout
+ from portage.versions import best, cpv_getversion
++from portage.dep.dep_check import ro_selected
+ 
+ from _emerge.Blocker import Blocker
+ from _emerge.create_world_atom import create_world_atom
+@@ -563,6 +564,42 @@ class Display(object):
+                       writemsg_stdout("%s\n" % (pkg,), noiselevel=-1)
+               return
+ 
++      def print_readonly_prefix(self):
++              """Performs the actual output printing for the readonly prefix
++              information stuff
++              """
++              out = sys.stdout
++
++        # print readonly selected packages
++              if len(ro_selected) > 0:
++                      out.write("\n%s\n\n" % (darkgreen("Packages resolved 
from readonly installations:")))
++
++              ro_mismatch_warning = False
++              ro_dupcheck = []
++              for x in ro_selected:
++                      tmp_type = x["type"].replace("END","")
++                      while len(tmp_type) < 4:
++                              tmp_type += " "
++                      if x["parent"] and str(x["atom"]) not in ro_dupcheck:
++                              out.write("[%s %s] %s %s %s (%s by %s)" % 
(teal("readonly"),
++                                      green(tmp_type), 
green(str(x["matches"][0])), yellow("from"),
++                                      blue(x["ro_root"]), 
turquoise(str(x["atom"])), green(x["parent"].cpv)))
++
++                              ro_dupcheck.append(str(x["atom"]))
++
++                              if x["host_mismatch"]:
++                                      ro_mismatch_warning = True
++                                      out.write(" %s\n" % (red("**")))
++                              else:
++                                      out.write("\n")
++
++              if ro_mismatch_warning:
++                      out.write("\n%s:" % (red("**")))
++                      out.write(yellow(" WARNING: packages marked with ** 
have been resolved as a\n"))
++                      out.write(yellow("    runtime dependency, but the CHOST 
variable for the parent\n"))
++                      out.write(yellow("    and dependency package don't 
match. This could cause link\n"))
++                      out.write(yellow("    errors. It is recommended to use 
RDEPEND READONLY_EPREFIX's\n"))
++                      out.write(yellow("    only with matching CHOST portage 
instances.\n"))
+ 
+       def print_verbose(self, show_repos):
+               """Prints the verbose output to std_out
+@@ -913,6 +950,7 @@ class Display(object):
+               show_repos = self.quiet_repo_display and repoadd_set and 
repoadd_set != set(["0"])
+ 
+               # now finally print out the messages
++              self.print_readonly_prefix()
+               self.print_messages(show_repos)
+               self.print_blockers()
+               if self.conf.verbosity == 3:
+diff --git a/pym/portage/_sets/__init__.py b/pym/portage/_sets/__init__.py
+index 2c9bf97..6a27842 100644
+--- a/pym/portage/_sets/__init__.py
++++ b/pym/portage/_sets/__init__.py
+@@ -21,6 +21,7 @@ from portage.const import _ENABLE_SET_CONFIG
+ from portage.exception import PackageSetNotFound
+ from portage.localization import _
+ from portage.util import writemsg_level
++from portage.util._path import exists_raise_eaccess
+ from portage.util.configparser import (SafeConfigParser,
+       NoOptionError, ParsingError, read_configs)
+ 
+@@ -281,6 +282,10 @@ def load_default_config(settings, trees):
+       if portage.const.EPREFIX:
+               global_config_path = os.path.join(portage.const.EPREFIX,
+                       GLOBAL_CONFIG_PATH.lstrip(os.sep))
++              if not exists_raise_eaccess(global_config_path) and 
portage.const.BPREFIX:
++                      global_config_path = os.path.join(portage.const.BPREFIX,
++                              GLOBAL_CONFIG_PATH.lstrip(os.sep))
++
+       vcs_dirs = [_unicode_encode(x, encoding=_encodings['fs']) for x in 
VCS_DIRS]
+       def _getfiles():
+               for path, dirs, files in 
os.walk(os.path.join(global_config_path, "sets")):
+diff --git a/pym/portage/const.py b/pym/portage/const.py
+index a0ad1f9..4f14bc8 100644
+--- a/pym/portage/const.py
++++ b/pym/portage/const.py
+@@ -189,6 +189,7 @@ SUPPORTED_FEATURES       = frozenset([
+       "notitles",
+       "parallel-fetch",
+       "parallel-install",
++      "prefix-chaining",
+       "prelink-checksums",
+       "preserve-libs",
+       "protect-owned",
+@@ -266,6 +267,11 @@ MANIFEST2_IDENTIFIERS    = ("AUX", "MISC", "DIST", 
"EBUILD")
+ #EPREFIX = ""
+ # END PREFIX LOCAL
+ 
++BPREFIX = EPREFIX
++
++# --prefix commandline arg always rules, ends up in os.environ["EPREFIX"]
++if "EPREFIX" in os.environ:
++    os.environ["PORTAGE_OVERRIDE_EPREFIX"] = os.environ["EPREFIX"]
+ # pick up EPREFIX from the environment if set
+ if "PORTAGE_OVERRIDE_EPREFIX" in os.environ:
+       EPREFIX = os.environ["PORTAGE_OVERRIDE_EPREFIX"]
+diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
+index 0006bc5..2ea5f16 100644
+--- a/pym/portage/dbapi/vartree.py
++++ b/pym/portage/dbapi/vartree.py
+@@ -194,8 +194,19 @@ class vardbapi(dbapi):
+               self._counter_path = os.path.join(self._eroot,
+                       CACHE_PATH, "counter")
+ 
+-              self._plib_registry = PreservedLibsRegistry(settings["ROOT"],
+-                      os.path.join(self._eroot, PRIVATE_PATH, 
"preserved_libs_registry"))
++              plibreg_path = os.path.join(self._eroot, PRIVATE_PATH, 
"preserved_libs_registry")
++
++              if vartree:
++                      self._kill_eprefix = vartree._kill_eprefix
++              else:
++                      self._kill_eprefix = False
++
++              if self._kill_eprefix:
++                      self._aux_cache_filename = 
self._aux_cache_filename.replace(EPREFIX, "")
++                      self._counter_path = 
self._counter_path.replace(EPREFIX, "")
++                      plibreg_path = plibreg_path.replace(EPREFIX, "")
++
++              self._plib_registry = PreservedLibsRegistry(settings["ROOT"], 
plibreg_path)
+               self._linkmap = LinkageMap(self)
+               chost = self.settings.get('CHOST')
+               if not chost:
+@@ -236,6 +247,9 @@ class vardbapi(dbapi):
+               # This is an optimized hotspot, so don't use unicode-wrapped
+               # os module and don't use os.path.join().
+               rValue = self._eroot + VDB_PATH + _os.sep + mykey
++              if self._kill_eprefix:
++                      rValue = rValue.replace(EPREFIX, "")
++
+               if filename is not None:
+                       # If filename is always relative, we can do just
+                       # rValue += _os.sep + filename
+@@ -499,6 +513,9 @@ class vardbapi(dbapi):
+               returnme = []
+               basepath = os.path.join(self._eroot, VDB_PATH) + os.path.sep
+ 
++              if self._kill_eprefix:
++                      basepath = os.path.join(self.root, 
basepath.replace(EPREFIX, ""))
++
+               if use_cache:
+                       from portage import listdir
+               else:
+@@ -595,11 +612,17 @@ class vardbapi(dbapi):
+                               del self.matchcache[mycat]
+                       return list(self._iter_match(mydep,
+                               self.cp_list(mydep.cp, use_cache=use_cache)))
++
++              _tmp_path = os.path.join(self._eroot, VDB_PATH, mycat)
++
++              if self._kill_eprefix:
++                      _tmp_path = _tmp_path.replace(EPREFIX, "")
++
+               try:
+                       if sys.hexversion >= 0x3030000:
+-                              curmtime = os.stat(os.path.join(self._eroot, 
VDB_PATH, mycat)).st_mtime_ns
++                              curmtime = os.stat(_tmp_path).st_mtime_ns
+                       else:
+-                              curmtime = os.stat(os.path.join(self._eroot, 
VDB_PATH, mycat)).st_mtime
++                              curmtime = os.stat(_tmp_path).st_mtime
+               except (IOError, OSError):
+                       curmtime=0
+ 
+@@ -1410,7 +1433,7 @@ class vardbapi(dbapi):
+ class vartree(object):
+       "this tree will scan a var/db/pkg database located at root (passed to 
init)"
+       def __init__(self, root=None, virtual=DeprecationWarning, 
categories=None,
+-              settings=None):
++              settings=None, kill_eprefix=None):
+ 
+               if settings is None:
+                       settings = portage.settings
+@@ -1428,6 +1451,7 @@ class vartree(object):
+                               " constructor is unused",
+                               DeprecationWarning, stacklevel=2)
+ 
++              self._kill_eprefix = kill_eprefix
+               self.settings = settings
+               self.dbapi = vardbapi(settings=settings, vartree=self)
+               self.populated = 1
+diff --git a/pym/portage/dep/dep_check.py b/pym/portage/dep/dep_check.py
+index 35caecc..f0dca8a 100644
+--- a/pym/portage/dep/dep_check.py
++++ b/pym/portage/dep/dep_check.py
+@@ -255,6 +255,95 @@ class _dep_choice(SlotObject):
+       __slots__ = ('atoms', 'slot_map', 'cp_map', 'all_available',
+               'all_installed_slots')
+ 
++ro_trees={}
++ro_vartrees={}
++ro_selected=[]
++
++def dep_match_readonly_roots(settings, atom, dep_type, parent=None):
++   if len(ro_trees) < len(settings.readonly_prefixes):
++       # MDUFT: create additional vartrees for every readonly root here.
++       # the ro_vartrees instances are created below as they are needed to
++       # avoid reading vartrees of portage instances which aren't required
++       # while resolving this dependencies.
++       for type in ("DEPEND","RDEPEND", "PDEPEND"):
++           ro_trees[type] = []
++
++           for ro_root, ro_dep_types in settings.readonly_prefixes.items():
++               if type in ro_dep_types:
++                   ro_trees[type].append(ro_root)
++
++   if len(ro_trees) == 0:
++       return []
++
++   matches = []
++
++   for ro_root in ro_trees[dep_type]:
++       if not ro_root in ro_vartrees:
++           # target_root=ro_root ok? or should it be the real target_root?
++           _tmp_settings = portage.config(config_root=ro_root, 
target_root=ro_root,
++               config_incrementals=portage.const.INCREMENTALS)
++
++           ro_vartrees[ro_root] = portage.vartree(root=ro_root,
++               categories=_tmp_settings.categories,
++               settings=_tmp_settings, kill_eprefix=True)
++
++       ro_matches = ro_vartrees[ro_root].dbapi.match(atom)
++
++       if ro_matches:
++           ro_host_mismatch = False
++           if dep_type is "RDEPEND":
++               # we need to assure binary compatability, so it needs to be
++               # the same CHOST! But how? for now i cannot do anything...
++               if parent and parent.metadata["CHOST"] != 
ro_vartrees[ro_root].settings.get("CHOST", ""):
++                   # provocate a big fat warning in the list of external 
packages.
++                   ro_host_mismatch = True
++               pass
++
++           matches.append({ "ro_root": ro_root, "atom": atom, "matches": 
ro_matches,
++               "type": dep_type, "parent": parent, "host_mismatch": 
ro_host_mismatch })
++
++   return matches
++
++def dep_wordreduce_readonly(reduced, unreduced, settings, dep_type, parent):
++   for mypos, token in enumerate(unreduced):
++       # recurse if it's a list.
++       if isinstance(reduced[mypos], list):
++           reduced[mypos] = dep_wordreduce_readonly(reduced[mypos],
++               unreduced[mypos], settings, dep_type, parent)
++
++       # do nothing if it's satisfied already.
++       elif not reduced[mypos]:
++           ro_matches = dep_match_readonly_roots(settings, unreduced[mypos], 
dep_type, parent)
++
++           if ro_matches:
++               # TODO: select a match if there are more than one?
++               # for now, the first match is taken...
++               ro_selected.append(ro_matches[0])
++               reduced[mypos] = True
++
++   return reduced
++
++# this may be better placed somewhere else, but i put it here for now, to
++# keep all functions in the patch on one big heap.
++def readonly_pathmatch_any(settings, path):
++   path = path.lstrip('/')
++   # first try locally, and match that if it exists.
++   if os.path.exists(os.path.join(EPREFIX,path)):
++       return os.path.join(EPREFIX,path)
++
++   # after that try all readonly roots where DEPEND is allowed. this makes
++   # sure that executing binaries is possible from there.
++   for ro_root, ro_deps in settings.readonly_roots.items():
++       if "DEPEND" in ro_deps:
++           print(" --- checking %s --- " % (os.path.join(ro_root,path)))
++           if os.path.exists(os.path.join(ro_root,path)):
++               return os.path.join(ro_root,path)
++           break
++
++   # as a fallback make the string the same as it was originally.
++   # even though this path doesn't exist.
++   return os.path.join(EPREFIX,path)
++
+ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
+       """
+       Takes an unreduced and reduced deplist and removes satisfied 
dependencies.
+@@ -643,7 +732,7 @@ def dep_zapdeps(unreduced, reduced, myroot, 
use_binaries=0, trees=None):
+       assert(False) # This point should not be reachable
+ 
+ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, 
myuse=None,
+-      use_cache=1, use_binaries=0, myroot=None, trees=None):
++      use_cache=1, use_binaries=0, myroot=None, trees=None, dep_type=None):
+       """
+       Takes a depend string, parses it, and selects atoms.
+       The myroot parameter is unused (use mysettings['EROOT'] instead).
+@@ -741,6 +830,14 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", 
mode=None, myuse=None,
+       writemsg("mysplit:  %s\n" % (mysplit), 1)
+       writemsg("mysplit2: %s\n" % (mysplit2), 1)
+ 
++      if dep_type is not None:
++              mysplit2=dep_wordreduce_readonly(unreduced=mysplit[:],
++                              reduced=mysplit2, settings=mysettings,
++                              dep_type=dep_type, 
parent=trees[myroot].get("disp_parent"))
++
++              writemsg("\n", 1)
++              writemsg("mysplit2 after readonly reduce: %s\n" % (mysplit2), 1)
++
+       selected_atoms = dep_zapdeps(mysplit, mysplit2, myroot,
+               use_binaries=use_binaries, trees=trees)
+ 
+diff --git a/pym/portage/package/ebuild/_config/LocationsManager.py 
b/pym/portage/package/ebuild/_config/LocationsManager.py
+index 55b8c08..32e969e 100644
+--- a/pym/portage/package/ebuild/_config/LocationsManager.py
++++ b/pym/portage/package/ebuild/_config/LocationsManager.py
+@@ -307,6 +307,9 @@ class LocationsManager(object):
+               if portage.const.EPREFIX:
+                       self.global_config_path = 
os.path.join(portage.const.EPREFIX,
+                               GLOBAL_CONFIG_PATH.lstrip(os.sep))
++                      if not exists_raise_eaccess(self.global_config_path) 
and portage.const.BPREFIX:
++                              self.global_config_path = 
os.path.join(portage.const.BPREFIX,
++                                      GLOBAL_CONFIG_PATH.lstrip(os.sep))
+ 
+       def set_port_dirs(self, portdir, portdir_overlay):
+               self.portdir = portdir
+diff --git a/pym/portage/package/ebuild/config.py 
b/pym/portage/package/ebuild/config.py
+index b5fb42e..8cac700 100644
+--- a/pym/portage/package/ebuild/config.py
++++ b/pym/portage/package/ebuild/config.py
+@@ -306,6 +306,7 @@ class config(object):
+                       self.features = features_set(self)
+                       self.features._features = 
copy.deepcopy(clone.features._features)
+                       self._features_overrides = 
copy.deepcopy(clone._features_overrides)
++                      self.readonly_prefixes = 
copy.deepcopy(clone.readonly_prefixes)
+ 
+                       #Strictly speaking _license_manager is not immutable. 
Users need to ensure that
+                       #extract_global_changes() is called right after 
__init__ (if at all).
+@@ -945,6 +946,63 @@ class config(object):
+ 
+                       self._validate_commands()
+ 
++                      # expand READONLY_EPREFIX to a list of all readonly 
portage instances
++                      # all the way down to the last one. beware that ATM a 
deeper instance
++                      # in the chain can provide more than the toplevel! this 
means that
++                      # if you only inherit DEPENDS from one instance, that 
instance may
++                      # inherit RDEPENDs from another one, making the 
top-level instance
++                      # inherit RDEPENDs from there too - even if the 
intermediate prefix
++                      # does not do this.
++                      self.readonly_prefixes = {}
++                      ro_cfg_root = config_root
++                      ro_widest_depset = set(['DEPEND', 'RDEPEND', 'PDEPEND'])
++
++                      while ro_cfg_root:
++                              ro_make_conf_paths = [
++                                      os.path.join(ro_cfg_root, 'etc', 
'make.conf'),
++                                      os.path.join(ro_cfg_root, 
MAKE_CONF_FILE)
++                              ]
++                              try:
++                                      if 
os.path.samefile(*ro_make_conf_paths):
++                                              ro_make_conf_paths.pop()
++                              except OSError:
++                                      pass
++
++                              ro_cfg_root = None
++                              for ro_make_conf in ro_make_conf_paths:
++                                      if not os.path.exists(ro_make_conf):
++                                              continue
++
++                                      ro_cfg = getconfig(ro_make_conf, 
tolerant=True, allow_sourcing=True)
++                                      if not "READONLY_EPREFIX" in ro_cfg:
++                                              continue
++
++                                      if not 
ro_cfg["READONLY_EPREFIX"].find(":"):
++                                              raise 
portage.exception.InvalidReadonlyERoot("ERROR: malformed READONLY_EPREFIX in 
%s" % (ro_make_conf))
++
++                                      if ro_cfg_root is not None:
++                                              raise 
portage.exception.InvalidReadonlyERoot("ERROR: duplicate READONLY_EPREFIX in %s 
and %s" % tuple(ro_make_conf_paths))
++
++                                      (ro_cfg_root,ro_cfg_root_deps) = 
ro_cfg["READONLY_EPREFIX"].rsplit(":",1)
++
++                                      if not os.path.exists(ro_cfg_root):
++                                              raise 
portage.exception.InvalidReadonlyERoot("ERROR: malformed READONLY_EPREFIX in 
%s: %s does not exist!" % (ro_make_conf, ro_cfg_root))
++
++                                      if os.path.samefile(ro_cfg_root, 
config_root):
++                                              raise 
portage.exception.InvalidReadonlyERoot("ERROR: cannot add this instance (%s) as 
READONLY_EPREFIX in %s." % (ro_cfg_root, ro_make_conf))
++
++                                      if ro_cfg_root in 
self.readonly_prefixes:
++                                              raise 
portage.exception.InvalidReadonlyERoot("ERROR: circular READONLY_EPREFIX's in 
%s. %s already checked for %s" % (ro_make_conf, ro_cfg_root, 
self.readonly_prefixes[ro_cfg_root])) 
++
++                                      # intersect the widest depset with the 
current one to strip down
++                                      # the allowed dependency resolution to 
not be wider than the
++                                      # next higher one. this way we can 
prevent for a given prefix
++                                      # to resolve RDEPENDs from a prefix 
with a different CHOST that
++                                      # is a few levels deeper in the chain.
++                                      ro_widest_depset = 
set(ro_cfg_root_deps.split(",")) & ro_widest_depset
++                                      self.readonly_prefixes[ro_cfg_root] = 
ro_widest_depset
++                              pass
++
+                       for k in self._case_insensitive_vars:
+                               if k in self:
+                                       self[k] = self[k].lower()
+@@ -2805,6 +2863,10 @@ class config(object):
+               if not eapi_exports_merge_type(eapi):
+                       mydict.pop("MERGE_TYPE", None)
+ 
++              # populate with PORTAGE_READONLY_EPREFIXES
++              if self.readonly_prefixes and len(self.readonly_prefixes) > 0:
++                      mydict["PORTAGE_READONLY_EPREFIXES"] = 
':'.join(self.readonly_prefixes)
++
+               # Prefix variables are supported beginning with EAPI 3, or when
+               # force-prefix is in FEATURES, since older EAPIs would 
otherwise be
+               # useless with prefix configurations. This brings compatibility 
with
+diff --git a/pym/portage/package/ebuild/doebuild.py 
b/pym/portage/package/ebuild/doebuild.py
+index c6d6133..f914091 100644
+--- a/pym/portage/package/ebuild/doebuild.py
++++ b/pym/portage/package/ebuild/doebuild.py
+@@ -51,6 +51,7 @@ from portage import bsd_chflags, \
+       unmerge, _encodings, _os_merge, \
+       _shell_quote, _unicode_decode, _unicode_encode
+ from portage.const import EBUILD_SH_ENV_FILE, EBUILD_SH_ENV_DIR, \
++    GLOBAL_CONFIG_PATH, \
+       EBUILD_SH_BINARY, INVALID_ENV_FILE, MISC_SH_BINARY, 
PORTAGE_PYM_PACKAGES, EPREFIX, MACOSSANDBOX_PROFILE
+ from portage.data import portage_gid, portage_uid, secpass, \
+       uid, userpriv_groups
+@@ -72,6 +73,7 @@ from portage.package.ebuild.prepare_build_dirs import 
prepare_build_dirs
+ from portage.process import find_binary
+ from portage.util import ( apply_recursive_permissions,
+       apply_secpass_permissions,
++      getconfig,
+       noiselimit,
+       shlex_split,
+       varexpand,
+@@ -79,6 +81,7 @@ from portage.util import ( apply_recursive_permissions,
+       writemsg_stdout,
+       write_atomic
+       )
++from portage.util._path import exists_raise_eaccess
+ from portage.util.cpuinfo import get_cpu_count
+ from portage.util.lafilefixer import rewrite_lafile
+ from portage.util.compression_probe import _compressors
+@@ -241,8 +244,27 @@ def _doebuild_path(settings, eapi=None):
+ 
+       for x in portage_bin_path:
+               path.append(os.path.join(x, "ebuild-helpers"))
++
++      # PREFIX CHAINING: append default path for all prefixes involved
++      pfxs = [ eprefix ]
++      pfxs.extend(settings.readonly_prefixes)
++      for prefix in pfxs:
++              global_config_path = os.path.join(prefix, 
GLOBAL_CONFIG_PATH.lstrip(os.sep))
++              make_globals_path = os.path.join(global_config_path, 
"make.globals")
++              if exists_raise_eaccess(make_globals_path):
++                      expand_map = { "EPREFIX": prefix }
++                      pxcfg = getconfig(make_globals_path, True, expand_map)
++                      pxdefp = [x for x in pxcfg.get("DEFAULT_PATH", 
"").split(":") if x]
++                      for x in pxdefp:
++                              if x.startswith(prefix) and not x in path:
++                                      path.append(x)
++              else:
++                      pxdefs = [prefix + "/usr/sbin", prefix + "/usr/bin", 
prefix + "/sbin", prefix + "/bin"]
++                      path.extend(pxdefs)
++      # END PREFIX CHAINING
++
+       path.extend(prerootpath)
+-      path.extend(defaultpath)
++      # path.extend(defaultpath) # PREFIX CHAINING appends the default path 
for involved prefixes above
+       path.extend(rootpath)
+       path.extend(extrapath)
+       # END PREFIX LOCAL
+diff --git a/pym/portage/package/ebuild/fetch.py 
b/pym/portage/package/ebuild/fetch.py
+index 265d0c9..2ec6ff4 100644
+--- a/pym/portage/package/ebuild/fetch.py
++++ b/pym/portage/package/ebuild/fetch.py
+@@ -43,6 +43,7 @@ from portage.output import colorize, EOutput
+ from portage.util import apply_recursive_permissions, \
+       apply_secpass_permissions, ensure_dirs, grabdict, shlex_split, \
+       varexpand, writemsg, writemsg_level, writemsg_stdout
++from portage.util._path import exists_raise_eaccess
+ from portage.process import spawn
+ 
+ _userpriv_spawn_kwargs = (
+@@ -874,6 +875,9 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
+                               global_config_path = GLOBAL_CONFIG_PATH
+                               if portage.const.EPREFIX:
+                                       global_config_path = 
os.path.join(portage.const.EPREFIX,
++                                              
GLOBAL_CONFIG_PATH.lstrip(os.sep))
++                                      if not 
exists_raise_eaccess(global_config_path) and portage.const.BPREFIX:
++                                              global_config_path = 
os.path.join(portage.const.BPREFIX,
+                                                       
GLOBAL_CONFIG_PATH.lstrip(os.sep))
+ 
+                               missing_file_param = False
+diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py
+index 3bccf6f..cacd637 100644
+--- a/pym/portage/sync/controller.py
++++ b/pym/portage/sync/controller.py
+@@ -94,19 +94,20 @@ class SyncManager(object):
+               self.module_controller = portage.sync.module_controller
+               self.module_names = self.module_controller.module_names
+               self.hooks = {}
+-              for _dir in ["repo.postsync.d", "postsync.d"]:
+-                      postsync_dir = 
os.path.join(self.settings["PORTAGE_CONFIGROOT"],
+-                              portage.USER_CONFIG_PATH, _dir)
+-                      hooks = OrderedDict()
+-                      for filepath in util._recursive_file_list(postsync_dir):
+-                              name = 
filepath.split(postsync_dir)[1].lstrip(os.sep)
+-                              if os.access(filepath, os.X_OK):
+-                                      hooks[filepath] = name
+-                              else:
+-                                      writemsg_level(" %s %s hook: '%s' is 
not executable\n"
+-                                              % (warn("*"), _dir, 
_unicode_decode(name),),
+-                                              level=logging.WARN, 
noiselevel=2)
+-                      self.hooks[_dir] = hooks
++              for _confroot in [self.settings["PORTAGE_CONFIGROOT"], 
portage.const.BPREFIX]:
++                      for _dir in ["repo.postsync.d", "postsync.d"]:
++                                      postsync_dir = os.path.join(_confroot,
++                                              portage.USER_CONFIG_PATH, _dir)
++                                      hooks = OrderedDict()
++                                      for filepath in 
util._recursive_file_list(postsync_dir):
++                                              name = 
filepath.split(postsync_dir)[1].lstrip(os.sep)
++                                              if os.access(filepath, os.X_OK):
++                                                      hooks[filepath] = name
++                                              else:
++                                                      writemsg_level(" %s %s 
hook: '%s' is not executable\n"
++                                                              % (warn("*"), 
_dir, _unicode_decode(name),),
++                                                              
level=logging.WARN, noiselevel=2)
++                                      self.hooks[_dir] = hooks
+ 
+       def __getattr__(self, name):
+               if name == 'async':
+diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py 
b/pym/portage/util/_dyn_libs/LinkageMapELF.py
+index a063621..968fbd3 100644
+--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
++++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
+@@ -12,7 +12,7 @@ from portage import _os_merge
+ from portage import _unicode_decode
+ from portage import _unicode_encode
+ from portage.cache.mappings import slot_dict_class
+-from portage.const import EPREFIX
++from portage.const import BPREFIX
+ from portage.dep.soname.multilib_category import compute_multilib_category
+ from portage.exception import CommandNotFound, InvalidData
+ from portage.localization import _
+@@ -268,7 +268,7 @@ class LinkageMapELF(object):
+                                       continue
+                               plibs.update((x, cpv) for x in items)
+               if plibs:
+-                      args = [os.path.join(EPREFIX or "/", 
"usr/bin/scanelf"), "-qF", "%a;%F;%S;%r;%n"]
++                      args = [os.path.join(BPREFIX or "/", 
"usr/bin/scanelf"), "-qF", "%a;%F;%S;%r;%n"]
+                       args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
+                               for x in plibs)
+                       try:
+-- 
+2.10.2
+

diff --git a/sys-apps/portage/portage-2.3.8.ebuild 
b/sys-apps/portage/portage-2.3.8.ebuild
index 60f0e15afe..07490db2e3 100644
--- a/sys-apps/portage/portage-2.3.8.ebuild
+++ b/sys-apps/portage/portage-2.3.8.ebuild
@@ -91,7 +91,7 @@ python_prepare_all() {
 
        epatch "${FILESDIR}"/${PN}-2.2.28-ebuildshell-r1.patch # 155161
        use prefix-chaining &&
-               epatch "${FILESDIR}"/${PN}-2.3.5-prefix-chaining.patch
+               epatch "${FILESDIR}"/${PN}-2.3.8-prefix-chaining.patch
 
        if use native-extensions; then
                printf "[build_ext]\nportage-ext-modules=true\n" >> \

Reply via email to