diff options
author | Robert Yang <liezhi.yang@windriver.co> | 2011-11-24 12:55:14 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-11-25 11:25:53 +0000 |
commit | 37c4f373e42b54f6c65b8482bd1172563fbc1ea5 (patch) | |
tree | 794326622526c6005326e1427a074b894c3a75eb | |
parent | 4ce5d30de78be5ce637a576bc84d59ca1547f5bc (diff) | |
download | poky-37c4f373e42b54f6c65b8482bd1172563fbc1ea5.tar.gz |
bitbake: Update and fix bitbake-runtask
Since bitbake switched back to the fork instead of the exec model,
it no longer used bitbake-runtask and the code has suffered some bitrot.
bitbake-runtask is a useful tool for excuting the task without
the scheduler of bitbake, so that the external tool can invoke it
easily. It also provides a useful example of how to invoke exec_task()
with low overhead without a lot of the bitbake threading/UI overhead.
Significant changes:
* This patch changes the argument order so that the commonly used
and mandatory arguments come first.
* The taskhash file and dryrun options are now optional
* It now uses the bitbake logging mechanisms to provide processed
logging output to the console.
* The process handling to do with stdout/stderr redirection
are removed since they're no longer required.
[YOCTO #1229]
RP: Logging updates to the patch based on Roberts original patch
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-x | bitbake/bin/bitbake-runtask | 131 |
1 files changed, 65 insertions, 66 deletions
diff --git a/bitbake/bin/bitbake-runtask b/bitbake/bin/bitbake-runtask index bee0f429ff..394b4c3ef9 100755 --- a/bitbake/bin/bitbake-runtask +++ b/bitbake/bin/bitbake-runtask | |||
@@ -4,6 +4,10 @@ import os | |||
4 | import sys | 4 | import sys |
5 | import warnings | 5 | import warnings |
6 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) | 6 | sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) |
7 | from bb import fetch2 | ||
8 | import logging | ||
9 | |||
10 | logger = logging.getLogger("BitBake") | ||
7 | 11 | ||
8 | try: | 12 | try: |
9 | import cPickle as pickle | 13 | import cPickle as pickle |
@@ -16,13 +20,20 @@ class BBConfiguration(object): | |||
16 | Manages build options and configurations for one run | 20 | Manages build options and configurations for one run |
17 | """ | 21 | """ |
18 | 22 | ||
19 | def __init__(self, debug, debug_domains): | 23 | def __init__(self, **options): |
20 | setattr(self, "data", {}) | 24 | self.data = {} |
21 | setattr(self, "file", []) | 25 | self.file = [] |
22 | setattr(self, "cmd", None) | 26 | self.cmd = None |
23 | setattr(self, "dump_signatures", True) | 27 | self.dump_signatures = True |
24 | setattr(self, "debug", debug) | 28 | self.prefile = [] |
25 | setattr(self, "debug_domains", debug_domains) | 29 | self.postfile = [] |
30 | self.parse_only = True | ||
31 | |||
32 | def __getattr__(self, attribute): | ||
33 | try: | ||
34 | return super(BBConfiguration, self).__getattribute__(attribute) | ||
35 | except AttributeError: | ||
36 | return None | ||
26 | 37 | ||
27 | _warnings_showwarning = warnings.showwarning | 38 | _warnings_showwarning = warnings.showwarning |
28 | def _showwarning(message, category, filename, lineno, file=None, line=None): | 39 | def _showwarning(message, category, filename, lineno, file=None, line=None): |
@@ -39,82 +50,70 @@ warnings.showwarning = _showwarning | |||
39 | warnings.simplefilter("ignore", DeprecationWarning) | 50 | warnings.simplefilter("ignore", DeprecationWarning) |
40 | 51 | ||
41 | import bb.event | 52 | import bb.event |
42 | |||
43 | # Need to map our I/O correctly. stdout is a pipe to the server expecting | ||
44 | # events. We save this and then map stdout to stderr. | ||
45 | |||
46 | eventfd = os.dup(sys.stdout.fileno()) | ||
47 | bb.event.worker_pipe = os.fdopen(eventfd, 'w', 0) | ||
48 | |||
49 | # map stdout to stderr | ||
50 | os.dup2(sys.stderr.fileno(), sys.stdout.fileno()) | ||
51 | |||
52 | # Replace those fds with our own | ||
53 | #logout = data.expand("${TMPDIR}/log/stdout.%s" % os.getpid(), self.cfgData, True) | ||
54 | #mkdirhier(os.path.dirname(logout)) | ||
55 | #newso = open("/tmp/stdout.%s" % os.getpid(), 'w') | ||
56 | #os.dup2(newso.fileno(), sys.stdout.fileno()) | ||
57 | #os.dup2(newso.fileno(), sys.stderr.fileno()) | ||
58 | |||
59 | # Don't read from stdin from the parent | ||
60 | si = file("/dev/null", 'r') | ||
61 | os.dup2(si.fileno( ), sys.stdin.fileno( )) | ||
62 | |||
63 | # We don't want to see signals to our parent, e.g. Ctrl+C | ||
64 | os.setpgrp() | ||
65 | |||
66 | # Save out the PID so that the event can include it the | ||
67 | # events | ||
68 | bb.event.worker_pid = os.getpid() | ||
69 | bb.event.useStdout = False | ||
70 | |||
71 | hashfile = sys.argv[1] | ||
72 | buildfile = sys.argv[2] | ||
73 | taskname = sys.argv[3] | ||
74 | |||
75 | import bb.cooker | 53 | import bb.cooker |
76 | 54 | ||
77 | p = pickle.Unpickler(file(hashfile, "rb")) | 55 | buildfile = sys.argv[1] |
78 | hashdata = p.load() | 56 | taskname = sys.argv[2] |
79 | 57 | if len(sys.argv) >= 4: | |
80 | debug = hashdata["msg-debug"] | 58 | dryrun = sys.argv[3] |
81 | debug_domains = hashdata["msg-debug-domains"] | 59 | else: |
82 | verbose = hashdata["verbose"] | 60 | dryrun = False |
61 | if len(sys.argv) >= 5: | ||
62 | hashfile = sys.argv[4] | ||
63 | p = pickle.Unpickler(file(hashfile, "rb")) | ||
64 | hashdata = p.load() | ||
65 | else: | ||
66 | hashdata = None | ||
67 | |||
68 | handler = bb.event.LogHandler() | ||
69 | logger.addHandler(handler) | ||
70 | |||
71 | #An example to make debug log messages show up | ||
72 | #bb.msg.init_msgconfig(True, 3, []) | ||
73 | |||
74 | console = logging.StreamHandler(sys.stdout) | ||
75 | format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") | ||
76 | bb.msg.addDefaultlogFilter(console) | ||
77 | console.setFormatter(format) | ||
78 | |||
79 | def worker_fire(event, d): | ||
80 | if isinstance(event, logging.LogRecord): | ||
81 | console.handle(event) | ||
82 | bb.event.worker_fire = worker_fire | ||
83 | bb.event.worker_pid = os.getpid() | ||
83 | 84 | ||
84 | bb.utils.init_logger(bb.msg, verbose, debug, debug_domains) | 85 | initialenv = os.environ.copy() |
86 | config = BBConfiguration() | ||
85 | 87 | ||
86 | cooker = bb.cooker.BBCooker(BBConfiguration(debug, debug_domains), None) | 88 | def register_idle_function(self, function, data): |
87 | cooker.parseConfiguration() | 89 | pass |
88 | 90 | ||
89 | cooker.bb_cache = bb.cache.init(cooker) | 91 | cooker = bb.cooker.BBCooker(config, register_idle_function, initialenv) |
90 | cooker.status = bb.cache.CacheData() | 92 | config_data = cooker.configuration.data |
93 | cooker.status = config_data | ||
94 | cooker.handleCollections(bb.data.getVar("BBFILE_COLLECTIONS", config_data, 1)) | ||
91 | 95 | ||
92 | (fn, cls) = cooker.bb_cache.virtualfn2realfn(buildfile) | 96 | fn, cls = bb.cache.Cache.virtualfn2realfn(buildfile) |
93 | buildfile = cooker.matchFile(fn) | 97 | buildfile = cooker.matchFile(fn) |
94 | fn = cooker.bb_cache.realfn2virtual(buildfile, cls) | 98 | fn = bb.cache.Cache.realfn2virtual(buildfile, cls) |
95 | 99 | ||
96 | cooker.buildSetVars() | 100 | cooker.buildSetVars() |
97 | 101 | ||
98 | # Load data into the cache for fn and parse the loaded cache data | 102 | # Load data into the cache for fn and parse the loaded cache data |
99 | the_data = cooker.bb_cache.loadDataFull(fn, cooker.get_file_appends(fn), cooker.configuration.data) | 103 | the_data = bb.cache.Cache.loadDataFull(fn, cooker.get_file_appends(fn), cooker.configuration.data) |
100 | cooker.bb_cache.setData(fn, buildfile, the_data) | ||
101 | cooker.bb_cache.handle_data(fn, cooker.status) | ||
102 | |||
103 | #exportlist = bb.utils.preserved_envvars_export_list() | ||
104 | #bb.utils.filter_environment(exportlist) | ||
105 | 104 | ||
106 | if taskname.endswith("_setscene"): | 105 | if taskname.endswith("_setscene"): |
107 | the_data.setVarFlag(taskname, "quieterrors", "1") | 106 | the_data.setVarFlag(taskname, "quieterrors", "1") |
108 | 107 | ||
109 | bb.parse.siggen.set_taskdata(hashdata["hashes"], hashdata["deps"]) | 108 | if hashdata: |
110 | 109 | bb.parse.siggen.set_taskdata(hashdata["hashes"], hashdata["deps"]) | |
111 | for h in hashdata["hashes"]: | 110 | for h in hashdata["hashes"]: |
112 | bb.data.setVar("BBHASH_%s" % h, hashdata["hashes"][h], the_data) | 111 | bb.data.setVar("BBHASH_%s" % h, hashdata["hashes"][h], the_data) |
113 | for h in hashdata["deps"]: | 112 | for h in hashdata["deps"]: |
114 | bb.data.setVar("BBHASHDEPS_%s" % h, hashdata["deps"][h], the_data) | 113 | bb.data.setVar("BBHASHDEPS_%s" % h, hashdata["deps"][h], the_data) |
115 | 114 | ||
116 | ret = 0 | 115 | ret = 0 |
117 | if sys.argv[4] != "True": | 116 | if dryrun != "True": |
118 | ret = bb.build.exec_task(fn, taskname, the_data) | 117 | ret = bb.build.exec_task(fn, taskname, the_data) |
119 | sys.exit(ret) | 118 | sys.exit(ret) |
120 | 119 | ||