diff options
author | Chris Larson <chris_larson@mentor.com> | 2011-02-07 10:50:27 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-02-10 22:33:43 +0000 |
commit | 68bd4069625082503d5664744cf944c202779a4b (patch) | |
tree | b329fbe8cbc9745418f587efd8f0cd65f9c837e6 /bitbake | |
parent | 1385162cd22d71524e12dc58f48c7d8714d8dc0c (diff) | |
download | poky-68bd4069625082503d5664744cf944c202779a4b.tar.gz |
Add initial bitbake-layers script
This script has subcommands which operate against your bitbake layers, either
displaying useful information, or acting against them. Currently, it only
provides a show_appends command, which shows you what bbappends are in effect,
and warns you if you have appends which are not being utilized.
Currently, a bug exists when using this due to the DataContext stuff, but I'm
not certain as to the root cause, it appears to be the bb package relying
implicitly on the way the bitbake script does things. A fix for that issue
will be forthcoming, as will further subcommands.
(Bitbake rev: 78b6d4cb26cec3321f8eec9889205a6b93b2ee18)
Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/bin/bitbake-layers | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers new file mode 100644 index 0000000000..08a846be81 --- /dev/null +++ b/bitbake/bin/bitbake-layers | |||
@@ -0,0 +1,153 @@ | |||
1 | #!/usr/bin/env python2.6 | ||
2 | |||
3 | import cmd | ||
4 | import logging | ||
5 | import os.path | ||
6 | import sys | ||
7 | |||
8 | bindir = os.path.dirname(__file__) | ||
9 | topdir = os.path.dirname(bindir) | ||
10 | sys.path[0:0] = [os.path.join(topdir, 'lib')] | ||
11 | |||
12 | import bb.cache | ||
13 | import bb.cooker | ||
14 | import bb.providers | ||
15 | from bb.cooker import state | ||
16 | |||
17 | |||
18 | logger = logging.getLogger('BitBake') | ||
19 | default_cmd = 'show_appends' | ||
20 | |||
21 | |||
22 | def main(args): | ||
23 | logging.basicConfig(format='%(levelname)s: %(message)s') | ||
24 | |||
25 | cmds = Commands() | ||
26 | if args: | ||
27 | cmds.onecmd(' '.join(args)) | ||
28 | else: | ||
29 | cmds.onecmd(default_cmd) | ||
30 | return cmds.returncode | ||
31 | |||
32 | |||
33 | class Commands(cmd.Cmd): | ||
34 | def __init__(self): | ||
35 | cmd.Cmd.__init__(self) | ||
36 | |||
37 | self.returncode = 0 | ||
38 | self.config = Config(parse_only=True) | ||
39 | self.cooker = bb.cooker.BBCooker(self.config, | ||
40 | self.register_idle_function) | ||
41 | self.config_data = self.cooker.configuration.data | ||
42 | bb.providers.logger.setLevel(logging.ERROR) | ||
43 | self.prepare_cooker() | ||
44 | |||
45 | def register_idle_function(self, function, data): | ||
46 | pass | ||
47 | |||
48 | def prepare_cooker(self): | ||
49 | sys.stderr.write("Parsing recipes..") | ||
50 | logger.setLevel(logging.ERROR) | ||
51 | |||
52 | try: | ||
53 | while self.cooker.state in (state.initial, state.parsing): | ||
54 | self.cooker.updateCache() | ||
55 | except KeyboardInterrupt: | ||
56 | self.cooker.shutdown() | ||
57 | self.cooker.updateCache() | ||
58 | sys.exit(2) | ||
59 | |||
60 | logger.setLevel(logging.INFO) | ||
61 | sys.stderr.write("done.\n") | ||
62 | |||
63 | self.cooker_data = self.cooker.status | ||
64 | self.cooker_data.appends = self.cooker.appendlist | ||
65 | |||
66 | def do_show_layers(self, args): | ||
67 | logger.info(str(self.config_data.getVar('BBLAYERS', True))) | ||
68 | |||
69 | def do_show_appends(self, args): | ||
70 | if not self.cooker_data.appends: | ||
71 | logger.info('No append files found') | ||
72 | return | ||
73 | |||
74 | logger.info('State of append files:') | ||
75 | |||
76 | for pn in self.cooker_data.pkg_pn: | ||
77 | self.show_appends_for_pn(pn) | ||
78 | |||
79 | self.show_appends_with_no_recipes() | ||
80 | |||
81 | def show_appends_for_pn(self, pn): | ||
82 | filenames = self.cooker_data.pkg_pn[pn] | ||
83 | |||
84 | best = bb.providers.findBestProvider(pn, | ||
85 | self.cooker.configuration.data, | ||
86 | self.cooker_data, | ||
87 | self.cooker_data.pkg_pn) | ||
88 | best_filename = os.path.basename(best[3]) | ||
89 | |||
90 | appended, missing = self.get_appends_for_files(filenames) | ||
91 | if appended: | ||
92 | for basename, appends in appended: | ||
93 | logger.info('%s:', basename) | ||
94 | for append in appends: | ||
95 | logger.info(' %s', append) | ||
96 | |||
97 | if best_filename in missing: | ||
98 | logger.warn('%s: missing append for preferred version', | ||
99 | best_filename) | ||
100 | self.returncode |= 1 | ||
101 | |||
102 | def get_appends_for_files(self, filenames): | ||
103 | appended, notappended = set(), set() | ||
104 | for filename in filenames: | ||
105 | _, cls = bb.cache.Cache.virtualfn2realfn(filename) | ||
106 | if cls: | ||
107 | continue | ||
108 | |||
109 | basename = os.path.basename(filename) | ||
110 | appends = self.cooker_data.appends.get(basename) | ||
111 | if appends: | ||
112 | appended.add((basename, frozenset(appends))) | ||
113 | else: | ||
114 | notappended.add(basename) | ||
115 | return appended, notappended | ||
116 | |||
117 | def show_appends_with_no_recipes(self): | ||
118 | recipes = set(os.path.basename(f) | ||
119 | for f in self.cooker_data.pkg_fn.iterkeys()) | ||
120 | appended_recipes = self.cooker_data.appends.iterkeys() | ||
121 | appends_without_recipes = [self.cooker_data.appends[recipe] | ||
122 | for recipe in appended_recipes | ||
123 | if recipe not in recipes] | ||
124 | if appends_without_recipes: | ||
125 | appendlines = (' %s' % append | ||
126 | for appends in appends_without_recipes | ||
127 | for append in appends) | ||
128 | logger.warn('No recipes available for:\n%s', | ||
129 | '\n'.join(appendlines)) | ||
130 | self.returncode |= 4 | ||
131 | |||
132 | def do_EOF(self, line): | ||
133 | return True | ||
134 | |||
135 | |||
136 | class Config(object): | ||
137 | def __init__(self, **options): | ||
138 | self.pkgs_to_build = [] | ||
139 | self.debug_domains = [] | ||
140 | self.extra_assume_provided = [] | ||
141 | self.file = [] | ||
142 | self.debug = 0 | ||
143 | self.__dict__.update(options) | ||
144 | |||
145 | def __getattr__(self, attribute): | ||
146 | try: | ||
147 | return super(Config, self).__getattribute__(attribute) | ||
148 | except AttributeError: | ||
149 | return None | ||
150 | |||
151 | |||
152 | if __name__ == '__main__': | ||
153 | sys.exit(main(sys.argv[1:]) or 0) | ||