2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
7 # This block ensures that ^C interrupts are handled quietly.
11 def exithandler(signum,frame):
12 signal.signal(signal.SIGINT, signal.SIG_IGN)
13 signal.signal(signal.SIGTERM, signal.SIG_IGN)
16 signal.signal(signal.SIGINT, exithandler)
17 signal.signal(signal.SIGTERM, exithandler)
19 except KeyboardInterrupt:
22 def debug_signal(signum, frame):
25 signal.signal(signal.SIGUSR1, debug_signal)
30 description = "See the ebuild(1) man page for more info"
31 usage = "Usage: ebuild <ebuild file> <command> [command] ..."
32 parser = optparse.OptionParser(description=description, usage=usage)
34 force_help = "When used together with the digest or manifest " + \
35 "command, this option forces regeneration of digests for all " + \
36 "distfiles associated with the current ebuild. Any distfiles " + \
37 "that do not already exist in ${DISTDIR} will be automatically fetched."
39 parser.add_option("--force", help=force_help, action="store_true", dest="force")
40 parser.add_option("--debug", help="show debug output",
41 action="store_true", dest="debug")
42 parser.add_option("--ignore-default-opts",
44 help="do not use the EBUILD_DEFAULT_OPTS environment variable")
45 parser.add_option("--skip-manifest", help="skip all manifest checks",
46 action="store_true", dest="skip_manifest")
48 opts, pargs = parser.parse_args(args=sys.argv[1:])
51 parser.error("missing required args")
54 print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
55 os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
57 os.environ["PORTAGE_CALLER"]="ebuild"
61 from os import path as osp
62 sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
65 from portage import os
67 if not opts.ignore_default_opts:
68 default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
69 opts, pargs = parser.parse_args(default_opts + sys.argv[1:])
74 import portage.util, portage.const
76 portage.dep._dep_check_strict = True
78 # do this _after_ 'import portage' to prevent unnecessary tracing
79 if debug and "python-trace" in portage.features:
81 portage.debug.set_trace(True)
83 if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
84 portage.output.nocolor()
89 if 'parse-eapi-glep-55' in portage.settings.features:
90 pf, eapi = portage._split_ebuild_name_glep55(
91 os.path.basename(ebuild))
92 elif ebuild.endswith(".ebuild"):
93 pf = os.path.basename(ebuild)[:-7]
96 portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
97 (ebuild,), noiselevel=-1)
100 if not os.path.isabs(ebuild):
102 # Try to get the non-canonical path from the PWD evironment variable, since
103 # the canonical path returned from os.getcwd() may may be unusable in
104 # cases where the directory stucture is built from symlinks.
105 if "PWD" in os.environ and os.environ["PWD"] != mycwd and \
106 os.path.realpath(os.environ["PWD"]) == mycwd:
107 mycwd = portage.normalize_path(os.environ["PWD"])
108 ebuild = os.path.join(mycwd, ebuild)
109 ebuild = portage.normalize_path(ebuild)
110 # portdbapi uses the canonical path for the base of the portage tree, but
111 # subdirectories of the base can be built from symlinks (like crossdev does).
112 ebuild_portdir = os.path.realpath(
113 os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
114 ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
116 # Make sure that portdb.findname() returns the correct ebuild.
117 if ebuild_portdir not in portage.portdb.porttrees:
118 os.environ["PORTDIR_OVERLAY"] = \
119 os.environ.get("PORTDIR_OVERLAY","") + " " + ebuild_portdir
120 print "Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir
121 portage.close_portdbapi_caches()
123 del portage.portdb.porttrees[1:]
124 if ebuild_portdir != portage.portdb.porttree_root:
125 portage.portdb.porttrees.append(ebuild_portdir)
127 if not os.path.exists(ebuild):
128 print "'%s' does not exist." % ebuild
131 ebuild_split = ebuild.split("/")
132 cpv = "%s/%s" % (ebuild_split[-3], pf)
134 if not portage.catpkgsplit(cpv):
135 print "!!! %s does not follow correct package syntax." % (cpv)
138 if ebuild.startswith(os.path.join(portage.root, portage.const.VDB_PATH)):
141 portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
143 if os.path.realpath(portage_ebuild) != ebuild:
144 print "!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild)
150 portage_ebuild = portage.portdb.findname(cpv)
152 if not portage_ebuild or portage_ebuild != ebuild:
153 print "!!! %s does not seem to have a valid PORTDIR structure." % ebuild
156 if len(pargs) > 1 and "config" in pargs:
157 print "config must be called on it's own, not combined with any other phase"
160 def discard_digests(myebuild, mysettings, mydbapi):
161 """Discard all distfiles digests for the given ebuild. This is useful when
162 upstream has changed the identity of the distfiles and the user would
163 otherwise have to manually remove the Manifest and files/digest-* files in
164 order to ensure correct results."""
166 portage._doebuild_manifest_exempt_depend += 1
167 pkgdir = os.path.dirname(myebuild)
168 fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
169 from portage.manifest import Manifest
170 mf = Manifest(pkgdir, mysettings["DISTDIR"],
171 fetchlist_dict=fetchlist_dict, manifest1_compat=False)
172 mf.create(requiredDistfiles=None,
173 assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
174 distfiles = fetchlist_dict[cpv]
175 for myfile in distfiles:
177 del mf.fhashdict["DIST"][myfile]
182 portage._doebuild_manifest_exempt_depend -= 1
184 portage.settings.validate() # generate warning messages if necessary
185 tmpsettings = portage.config(clone=portage.settings)
186 tmpsettings["PORTAGE_VERBOSE"] = "1"
187 tmpsettings.backup_changes("PORTAGE_VERBOSE")
189 # This variable is a signal to config.regenerate() to
190 # indicate that the test phase should be enabled regardless
191 # of problems such as masked "test" USE flag.
192 tmpsettings["EBUILD_FORCE_TEST"] = "1"
193 tmpsettings.backup_changes("EBUILD_FORCE_TEST")
194 if "test" not in tmpsettings.features:
195 tmpsettings.features.add("test")
196 tmpsettings["FEATURES"] = " ".join(sorted(tmpsettings.features))
197 tmpsettings.backup_changes("FEATURES")
199 if opts.skip_manifest:
200 tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
201 tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
202 portage._doebuild_manifest_exempt_depend += 1
204 build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
205 "test", "install", "package", "rpm", "merge", "qmerge"])
207 # If the current metadata is invalid then force the ebuild to be
208 # sourced again even if $T/environment already exists.
209 ebuild_changed = False
210 if build_dir_phases.intersection(pargs):
211 metadata, st, emtime = \
212 portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)
214 ebuild_changed = True
216 def stale_env_warning():
217 if "clean" not in pargs and \
218 "noauto" not in tmpsettings.features and \
219 build_dir_phases.intersection(pargs):
220 portage.doebuild_environment(ebuild, "setup", portage.root,
221 tmpsettings, debug, 1, portage.portdb)
222 env_filename = os.path.join(tmpsettings["T"], "environment")
223 if os.path.exists(env_filename):
224 msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
225 "Run 'clean' to start with a fresh environment.") % \
226 (tmpsettings["PF"], )
227 from textwrap import wrap
230 portage.writemsg(">>> %s\n" % x)
233 open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
234 '.ebuild_changed'), 'w')
236 from portage.exception import PermissionDenied, \
237 PortagePackageException, UnsupportedAPIException
238 checked_for_stale_env = False
242 if not checked_for_stale_env and arg not in ("digest","manifest"):
243 # This has to go after manifest generation since otherwise
244 # aux_get() might fail due to invalid ebuild digests.
246 checked_for_stale_env = True
248 if arg in ("digest", "manifest") and force:
249 discard_digests(ebuild, tmpsettings, portage.portdb)
250 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
251 debug=debug, tree=mytree)
252 except KeyboardInterrupt:
258 except UnsupportedAPIException as e:
259 from textwrap import wrap
260 msg = wrap(str(e), 70)
263 portage.writemsg("!!! %s\n" % x, noiselevel=-1)
265 except PortagePackageException as e:
266 portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
268 except PermissionDenied as e:
269 portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
272 print "Could not run the required binary?"