d3a4dd8dd6b951b37e66e4feda66679efe4cba76
[portage.git] / pym / _emerge / EbuildExecuter.py
1 # Copyright 1999-2010 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 from _emerge.EbuildPhase import EbuildPhase
5 from _emerge.TaskSequence import TaskSequence
6 from _emerge.CompositeTask import CompositeTask
7 import portage
8 from portage import os
9 from portage.eapi import eapi_has_src_prepare_and_src_configure, \
10         eapi_exports_replace_vars
11 from portage.package.ebuild.doebuild import _prepare_fake_distdir
12
13 class EbuildExecuter(CompositeTask):
14
15         __slots__ = ("pkg", "scheduler", "settings")
16
17         _phases = ("prepare", "configure", "compile", "test", "install")
18
19         _live_eclasses = frozenset([
20                 "bzr",
21                 "cvs",
22                 "darcs",
23                 "git",
24                 "mercurial",
25                 "subversion",
26                 "tla",
27         ])
28
29         def _start(self):
30                 pkg = self.pkg
31                 scheduler = self.scheduler
32                 settings = self.settings
33                 cleanup = 0
34                 portage.prepare_build_dirs(pkg.root, settings, cleanup)
35
36                 portdb = pkg.root_config.trees['porttree'].dbapi
37                 ebuild_path = settings['EBUILD']
38                 alist = settings.configdict["pkg"].get("A", "").split()
39                 _prepare_fake_distdir(settings, alist)
40
41                 if eapi_exports_replace_vars(settings['EAPI']):
42                         vardb = pkg.root_config.trees['vartree'].dbapi
43                         settings["REPLACING_VERSIONS"] = " ".join(
44                                 set(portage.versions.cpv_getversion(match) \
45                                         for match in vardb.match(pkg.slot_atom) + \
46                                         vardb.match('='+pkg.cpv)))
47
48                 setup_phase = EbuildPhase(background=self.background,
49                         phase="setup", scheduler=scheduler,
50                         settings=settings)
51
52                 setup_phase.addExitListener(self._setup_exit)
53                 self._current_task = setup_phase
54                 self.scheduler.scheduleSetup(setup_phase)
55
56         def _setup_exit(self, setup_phase):
57
58                 if self._default_exit(setup_phase) != os.EX_OK:
59                         self.wait()
60                         return
61
62                 unpack_phase = EbuildPhase(background=self.background,
63                         phase="unpack", scheduler=self.scheduler,
64                         settings=self.settings)
65
66                 if self._live_eclasses.intersection(self.pkg.inherited):
67                         # Serialize $DISTDIR access for live ebuilds since
68                         # otherwise they can interfere with eachother.
69
70                         unpack_phase.addExitListener(self._unpack_exit)
71                         self._current_task = unpack_phase
72                         self.scheduler.scheduleUnpack(unpack_phase)
73
74                 else:
75                         self._start_task(unpack_phase, self._unpack_exit)
76
77         def _unpack_exit(self, unpack_phase):
78
79                 if self._default_exit(unpack_phase) != os.EX_OK:
80                         self.wait()
81                         return
82
83                 ebuild_phases = TaskSequence(scheduler=self.scheduler)
84
85                 pkg = self.pkg
86                 phases = self._phases
87                 eapi = pkg.metadata["EAPI"]
88                 if not eapi_has_src_prepare_and_src_configure(eapi):
89                         # skip src_prepare and src_configure
90                         phases = phases[2:]
91
92                 for phase in phases:
93                         ebuild_phases.add(EbuildPhase(background=self.background,
94                                 phase=phase, scheduler=self.scheduler,
95                                 settings=self.settings))
96
97                 self._start_task(ebuild_phases, self._default_final_exit)
98