Add another chain in the string to run chpathtool. It seems the old code in portage...
authorFabian Groffen <grobian@gentoo.org>
Tue, 22 Dec 2009 20:48:42 +0000 (20:48 -0000)
committerFabian Groffen <grobian@gentoo.org>
Tue, 22 Dec 2009 20:48:42 +0000 (20:48 -0000)
svn path=/main/branches/prefix/; revision=15131

pym/_emerge/Binpkg.py
pym/_emerge/BinpkgChpathtoolAsync.py [new file with mode: 0644]

index 6da292caedcdf4a88172264595607d58a76b0089..12055ab8ec63bf8d31f0d34e911fc03439daf4f6 100644 (file)
@@ -5,6 +5,7 @@
 from _emerge.EbuildPhase import EbuildPhase
 from _emerge.BinpkgFetcher import BinpkgFetcher
 from _emerge.BinpkgExtractorAsync import BinpkgExtractorAsync
+from _emerge.BinpkgChpathtoolAsync import BinpkgChpathtoolAsync
 from _emerge.CompositeTask import CompositeTask
 from _emerge.BinpkgVerifier import BinpkgVerifier
 from _emerge.EbuildMerge import EbuildMerge
@@ -29,8 +30,8 @@ class Binpkg(CompositeTask):
        __slots__ = ("find_blockers",
                "ldpath_mtimes", "logger", "opts",
                "pkg", "pkg_count", "prefetcher", "settings", "world_atom") + \
-               ("_bintree", "_build_dir", "_ebuild_path", "_fetched_pkg",
-               "_image_dir", "_infloc", "_pkg_path", "_tree", "_verify")
+               ("_buildprefix", "_bintree", "_build_dir", "_ebuild_path", "_fetched_pkg",
+               "_image_dir", "_infloc", "_pkg_path", "_tree", "_verify", "_work_dir")
 
        def _writemsg_level(self, msg, level=0, noiselevel=0):
 
@@ -62,6 +63,7 @@ class Binpkg(CompositeTask):
                self._build_dir = EbuildBuildDir(dir_path=dir_path,
                        pkg=pkg, settings=settings)
                self._image_dir = os.path.join(dir_path, "image")
+               self._work_dir = os.path.join(dir_path, "work")
                self._infloc = os.path.join(dir_path, "build-info")
                self._ebuild_path = os.path.join(self._infloc, pkg.pf + ".ebuild")
                settings["EBUILD"] = self._ebuild_path
@@ -253,6 +255,23 @@ class Binpkg(CompositeTask):
                finally:
                        f.close()
 
+               # Retrieve the EPREFIX this package was built with
+               self._buildprefix = pkg_xpak.getfile(_unicode_encode("EPREFIX",
+                       encoding=_encodings['repo.content']))
+               if not self._buildprefix:
+                       self._buildprefix = ''
+               else:
+                       self._buildprefix = self._buildprefix.strip()
+               # We want to install in "our" prefix, not the binary one
+               self.settings["EPREFIX"] = EPREFIX
+               f = codecs.open(_unicode_encode(os.path.join(infloc, 'EPREFIX'),
+                       encoding=_encodings['fs'], errors='strict'),
+                       mode='w', encoding=_encodings['content'], errors='strict')
+               try:
+                       f.write(EPREFIX + "\n")
+               finally:
+                       f.close()
+
                # This gives bashrc users an opportunity to do various things
                # such as remove binary packages after they're installed.
                settings = self.settings
@@ -275,8 +294,15 @@ class Binpkg(CompositeTask):
                        self.wait()
                        return
 
+               # if the prefix differs, we copy it to the image after
+               # extraction using chpathtool
+               if (self._buildprefix != EPREFIX):
+                       pkgloc = self._image_dir
+               else:
+                       pkgloc = self._work_dir
+
                extractor = BinpkgExtractorAsync(background=self.background,
-                       image_dir=self._image_dir,
+                       image_dir=pkgloc,
                        pkg=self.pkg, pkg_path=self._pkg_path, scheduler=self.scheduler)
                self._writemsg_level(">>> Extracting %s\n" % self.pkg.cpv)
                self._start_task(extractor, self._extractor_exit)
@@ -286,6 +312,24 @@ class Binpkg(CompositeTask):
                        self._unlock_builddir()
                        writemsg("!!! Error Extracting '%s'\n" % self._pkg_path,
                                noiselevel=-1)
+                       self.wait()
+                       return
+
+               if self._buildprefix != EPREFIX:
+                       chpathtool = BinpkgChpathtoolAsync(background=self.background,
+                               image_dir=self._image_dir, work_dir=self._work_dir,
+                               buildprefix=self._buildprefix, eprefix=EPREFIX,
+                               scheduler=self.scheduler)
+                       self._writemsg_level(">>> Adjusting Prefix to %s\n" % EPREFIX)
+                       self._start_task(chpathtool, self._chpathtool_exit)
+               else:
+                       self.wait()
+
+       def _chpathtool_exit(self, chpathtool):
+               if self._final_exit(chpathtool) != os.EX_OK:
+                       self._unlock_builddir()
+                       writemsg("!!! Error Adjusting Prefix to %s\n" % EPREFIX,
+                               noiselevel=-1)
                self.wait()
 
        def _unlock_builddir(self):
diff --git a/pym/_emerge/BinpkgChpathtoolAsync.py b/pym/_emerge/BinpkgChpathtoolAsync.py
new file mode 100644 (file)
index 0000000..6218b8f
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id: BinpkgExtractorAsync.py 13715 2009-06-27 14:44:56Z grobian $
+
+from _emerge.SpawnProcess import SpawnProcess
+# for an explanation on this logic, see pym/_emerge/__init__.py
+import os
+import sys
+if os.environ.__contains__("PORTAGE_PYTHONPATH"):
+       sys.path.insert(0, os.environ["PORTAGE_PYTHONPATH"])
+else:
+       sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym"))
+import portage
+class BinpkgExtractorAsync(SpawnProcess):
+
+       __slots__ = ("buildprefix", "eprefix", "image_dir", "work_dir")
+
+       _shell_binary = portage.const.BASH_BINARY
+
+       def _start(self):
+               b = os.path.join(self.work_dir, self.buildprefix.lstrip(os.path.sep))
+               i = os.path.join(self.image_dir, self.eprefix.lstrip(os.path.sep))
+               # make sure the directory structure for EPREFIX is set up in
+               # the image, but avoid the last directory being there,
+               # otherwise chpathtool will complain
+               portage.util.ensure_dirs(i)
+               os.rmdir(i)
+               self.args = [self._shell_binary, "-c",
+                       "chpathtool -q '%s' '%s' '%s' '%s'" % \
+                               (b, i, self.buildprefix, self.eprefix)]
+
+               self.env = self.pkg.root_config.settings.environ()
+               SpawnProcess._start(self)
+