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 if not opts.ignore_default_opts:
66 default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
67 opts, pargs = parser.parse_args(default_opts + sys.argv[1:])
72 import portage.util, portage.const
74 portage.dep._dep_check_strict = True
76 # do this _after_ 'import portage' to prevent unnecessary tracing
77 if debug and "python-trace" in portage.features:
79 portage.debug.set_trace(True)
81 if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
82 portage.output.nocolor()
87 if 'parse-eapi-glep-55' in portage.settings.features:
88 pf, eapi = portage._split_ebuild_name_glep55(
89 os.path.basename(ebuild))
90 elif ebuild.endswith(".ebuild"):
91 pf = os.path.basename(ebuild)[:-7]
94 portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
95 (ebuild,), noiselevel=-1)
98 if not os.path.isabs(ebuild):
100 # Try to get the non-canonical path from the PWD evironment variable, since
101 # the canonical path returned from os.getcwd() may may be unusable in
102 # cases where the directory stucture is built from symlinks.
103 if "PWD" in os.environ and os.environ["PWD"] != mycwd and \
104 os.path.realpath(os.environ["PWD"]) == mycwd:
105 mycwd = portage.normalize_path(os.environ["PWD"])
106 ebuild = os.path.join(mycwd, ebuild)
107 ebuild = portage.normalize_path(ebuild)
108 # portdbapi uses the canonical path for the base of the portage tree, but
109 # subdirectories of the base can be built from symlinks (like crossdev does).
110 ebuild_portdir = os.path.realpath(
111 os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
112 ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
114 # Make sure that portdb.findname() returns the correct ebuild.
115 if ebuild_portdir not in portage.portdb.porttrees:
116 os.environ["PORTDIR_OVERLAY"] = \
117 os.environ.get("PORTDIR_OVERLAY","") + " " + ebuild_portdir
118 print "Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir
119 portage.close_portdbapi_caches()
121 del portage.portdb.porttrees[1:]
122 if ebuild_portdir != portage.portdb.porttree_root:
123 portage.portdb.porttrees.append(ebuild_portdir)
125 if not os.path.exists(ebuild):
126 print "'%s' does not exist." % ebuild
129 ebuild_split = ebuild.split("/")
130 cpv = "%s/%s" % (ebuild_split[-3], pf)
132 if not portage.catpkgsplit(cpv):
133 print "!!! %s does not follow correct package syntax." % (cpv)
136 if ebuild.startswith(portage.root + portage.const.VDB_PATH):
139 portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)
141 if os.path.realpath(portage_ebuild) != ebuild:
142 print "!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild)
148 portage_ebuild = portage.portdb.findname(cpv)
150 if not portage_ebuild or portage_ebuild != ebuild:
151 print "!!! %s does not seem to have a valid PORTDIR structure." % ebuild
154 if len(pargs) > 1 and "config" in pargs:
155 print "config must be called on it's own, not combined with any other phase"
158 def discard_digests(myebuild, mysettings, mydbapi):
159 """Discard all distfiles digests for the given ebuild. This is useful when
160 upstream has changed the identity of the distfiles and the user would
161 otherwise have to manually remove the Manifest and files/digest-* files in
162 order to ensure correct results."""
164 portage._doebuild_manifest_exempt_depend += 1
165 pkgdir = os.path.dirname(myebuild)
166 fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
167 from portage.manifest import Manifest
168 mf = Manifest(pkgdir, mysettings["DISTDIR"],
169 fetchlist_dict=fetchlist_dict, manifest1_compat=False)
170 mf.create(requiredDistfiles=None,
171 assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
172 distfiles = fetchlist_dict[cpv]
173 for myfile in distfiles:
175 del mf.fhashdict["DIST"][myfile]
180 portage._doebuild_manifest_exempt_depend -= 1
182 portage.settings.validate() # generate warning messages if necessary
183 tmpsettings = portage.config(clone=portage.settings)
184 tmpsettings["PORTAGE_VERBOSE"] = "1"
185 tmpsettings.backup_changes("PORTAGE_VERBOSE")
187 # This variable is a signal to config.regenerate() to
188 # indicate that the test phase should be enabled regardless
189 # of problems such as masked "test" USE flag.
190 tmpsettings["EBUILD_FORCE_TEST"] = "1"
191 tmpsettings.backup_changes("EBUILD_FORCE_TEST")
192 if "test" not in tmpsettings.features:
193 tmpsettings.features.add("test")
194 tmpsettings["FEATURES"] = " ".join(sorted(tmpsettings.features))
195 tmpsettings.backup_changes("FEATURES")
197 if opts.skip_manifest:
198 tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
199 tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
200 portage._doebuild_manifest_exempt_depend += 1
202 build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
203 "test", "install", "package", "rpm", "merge", "qmerge"])
205 # If the current metadata is invalid then force the ebuild to be
206 # sourced again even if $T/environment already exists.
207 ebuild_changed = False
208 if build_dir_phases.intersection(pargs):
209 metadata, st, emtime = \
210 portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)
212 ebuild_changed = True
214 def stale_env_warning():
215 if "clean" not in pargs and \
216 "noauto" not in tmpsettings.features and \
217 build_dir_phases.intersection(pargs):
218 portage.doebuild_environment(ebuild, "setup", portage.root,
219 tmpsettings, debug, 1, portage.portdb)
220 env_filename = os.path.join(tmpsettings["T"], "environment")
221 if os.path.exists(env_filename):
222 msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
223 "Run 'clean' to start with a fresh environment.") % \
224 (tmpsettings["PF"], )
225 from textwrap import wrap
228 portage.writemsg(">>> %s\n" % x)
231 open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
232 '.ebuild_changed'), 'w')
234 from portage.exception import PermissionDenied, \
235 PortagePackageException, UnsupportedAPIException
236 checked_for_stale_env = False
240 if not checked_for_stale_env and arg not in ("digest","manifest"):
241 # This has to go after manifest generation since otherwise
242 # aux_get() might fail due to invalid ebuild digests.
244 checked_for_stale_env = True
246 if arg in ("digest", "manifest") and force:
247 discard_digests(ebuild, tmpsettings, portage.portdb)
248 a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
249 debug=debug, tree=mytree)
250 except KeyboardInterrupt:
256 except UnsupportedAPIException, e:
257 from textwrap import wrap
258 msg = wrap(str(e), 70)
261 portage.writemsg("!!! %s\n" % x, noiselevel=-1)
263 except PortagePackageException, e:
264 portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
266 except PermissionDenied, e:
267 portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
270 print "Could not run the required binary?"