summaryrefslogtreecommitdiffstats
path: root/bitbake-dev/bin
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2008-09-30 15:08:33 +0000
committerRichard Purdie <richard@openedhand.com>2008-09-30 15:08:33 +0000
commitc30eddb243e7e65f67f656e62848a033cf6f2e5c (patch)
tree110dd95788b76f55d31cb8d30aac2de8400b6f4a /bitbake-dev/bin
parent5ef0510474004eeb2ae8a99b64e2febb1920e077 (diff)
downloadpoky-c30eddb243e7e65f67f656e62848a033cf6f2e5c.tar.gz
Add bitbake-dev to allow ease of testing and development of bitbake trunk
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@5337 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake-dev/bin')
-rwxr-xr-xbitbake-dev/bin/bbimage160
-rwxr-xr-xbitbake-dev/bin/bitbake204
-rwxr-xr-xbitbake-dev/bin/bitdoc532
3 files changed, 896 insertions, 0 deletions
diff --git a/bitbake-dev/bin/bbimage b/bitbake-dev/bin/bbimage
new file mode 100755
index 0000000000..96b7dca323
--- /dev/null
+++ b/bitbake-dev/bin/bbimage
@@ -0,0 +1,160 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (C) 2003 Chris Larson
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20import sys, os
21sys.path.insert(0,os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
22import bb
23from bb import *
24
25__version__ = 1.1
26type = "jffs2"
27cfg_bb = data.init()
28cfg_oespawn = data.init()
29
30bb.msg.set_debug_level(0)
31
32def usage():
33 print "Usage: bbimage [options ...]"
34 print "Creates an image for a target device from a root filesystem,"
35 print "obeying configuration parameters from the BitBake"
36 print "configuration files, thereby easing handling of deviceisms."
37 print ""
38 print " %s\t\t%s" % ("-r [arg], --root [arg]", "root directory (default=${IMAGE_ROOTFS})")
39 print " %s\t\t%s" % ("-t [arg], --type [arg]", "image type (jffs2[default], cramfs)")
40 print " %s\t\t%s" % ("-n [arg], --name [arg]", "image name (override IMAGE_NAME variable)")
41 print " %s\t\t%s" % ("-v, --version", "output version information and exit")
42 sys.exit(0)
43
44def version():
45 print "BitBake Build Tool Core version %s" % bb.__version__
46 print "BBImage version %s" % __version__
47
48def emit_bb(d, base_d = {}):
49 for v in d.keys():
50 if d[v] != base_d[v]:
51 data.emit_var(v, d)
52
53def getopthash(l):
54 h = {}
55 for (opt, val) in l:
56 h[opt] = val
57 return h
58
59import getopt
60try:
61 (opts, args) = getopt.getopt(sys.argv[1:], 'vr:t:e:n:', [ 'version', 'root=', 'type=', 'bbfile=', 'name=' ])
62except getopt.GetoptError:
63 usage()
64
65# handle opts
66opthash = getopthash(opts)
67
68if '--version' in opthash or '-v' in opthash:
69 version()
70 sys.exit(0)
71
72try:
73 cfg_bb = parse.handle(os.path.join('conf', 'bitbake.conf'), cfg_bb)
74except IOError:
75 fatal("Unable to open bitbake.conf")
76
77# sanity check
78if cfg_bb is None:
79 fatal("Unable to open/parse %s" % os.path.join('conf', 'bitbake.conf'))
80 usage(1)
81
82# Handle any INHERITs and inherit the base class
83inherits = ["base"] + (bb.data.getVar('INHERIT', cfg_bb, True ) or "").split()
84for inherit in inherits:
85 cfg_bb = bb.parse.handle(os.path.join('classes', '%s.bbclass' % inherit), cfg_bb, True )
86
87rootfs = None
88extra_files = []
89
90if '--root' in opthash:
91 rootfs = opthash['--root']
92if '-r' in opthash:
93 rootfs = opthash['-r']
94
95if '--type' in opthash:
96 type = opthash['--type']
97if '-t' in opthash:
98 type = opthash['-t']
99
100if '--bbfile' in opthash:
101 extra_files.append(opthash['--bbfile'])
102if '-e' in opthash:
103 extra_files.append(opthash['-e'])
104
105for f in extra_files:
106 try:
107 cfg_bb = parse.handle(f, cfg_bb)
108 except IOError:
109 print "unable to open %s" % f
110
111if not rootfs:
112 rootfs = data.getVar('IMAGE_ROOTFS', cfg_bb, 1)
113
114if not rootfs:
115 bb.fatal("IMAGE_ROOTFS not defined")
116
117data.setVar('IMAGE_ROOTFS', rootfs, cfg_bb)
118
119from copy import copy, deepcopy
120localdata = data.createCopy(cfg_bb)
121
122overrides = data.getVar('OVERRIDES', localdata)
123if not overrides:
124 bb.fatal("OVERRIDES not defined.")
125data.setVar('OVERRIDES', '%s:%s' % (overrides, type), localdata)
126data.update_data(localdata)
127data.setVar('OVERRIDES', overrides, localdata)
128
129if '-n' in opthash:
130 data.setVar('IMAGE_NAME', opthash['-n'], localdata)
131if '--name' in opthash:
132 data.setVar('IMAGE_NAME', opthash['--name'], localdata)
133
134topdir = data.getVar('TOPDIR', localdata, 1) or os.getcwd()
135
136cmd = data.getVar('IMAGE_CMD', localdata, 1)
137if not cmd:
138 bb.fatal("IMAGE_CMD not defined")
139
140outdir = data.getVar('DEPLOY_DIR_IMAGE', localdata, 1)
141if not outdir:
142 bb.fatal('DEPLOY_DIR_IMAGE not defined')
143mkdirhier(outdir)
144
145#depends = data.getVar('IMAGE_DEPENDS', localdata, 1) or ""
146#if depends:
147# bb.note("Spawning bbmake to satisfy dependencies: %s" % depends)
148# ret = os.system('bbmake %s' % depends)
149# if ret != 0:
150# bb.error("executing bbmake to satisfy dependencies")
151
152bb.note("Executing %s" % cmd)
153data.setVar('image_cmd', cmd, localdata)
154data.setVarFlag('image_cmd', 'func', 1, localdata)
155try:
156 bb.build.exec_func('image_cmd', localdata)
157except bb.build.FuncFailed:
158 sys.exit(1)
159#ret = os.system(cmd)
160#sys.exit(ret)
diff --git a/bitbake-dev/bin/bitbake b/bitbake-dev/bin/bitbake
new file mode 100755
index 0000000000..067cc274f9
--- /dev/null
+++ b/bitbake-dev/bin/bitbake
@@ -0,0 +1,204 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (C) 2003, 2004 Chris Larson
6# Copyright (C) 2003, 2004 Phil Blundell
7# Copyright (C) 2003 - 2005 Michael 'Mickey' Lauer
8# Copyright (C) 2005 Holger Hans Peter Freyther
9# Copyright (C) 2005 ROAD GmbH
10# Copyright (C) 2006 Richard Purdie
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License version 2 as
14# published by the Free Software Foundation.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along
22# with this program; if not, write to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25import sys, os, getopt, re, time, optparse, xmlrpclib
26sys.path.insert(0,os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
27import bb
28from bb import cooker
29from bb import daemonize
30from bb import ui
31from bb.ui import uievent
32
33__version__ = "1.9.0"
34
35#============================================================================#
36# BBOptions
37#============================================================================#
38class BBConfiguration( object ):
39 """
40 Manages build options and configurations for one run
41 """
42 def __init__( self, options ):
43 for key, val in options.__dict__.items():
44 setattr( self, key, val )
45
46
47#============================================================================#
48# main
49#============================================================================#
50
51def main():
52 return_value = 0
53 pythonver = sys.version_info
54 if pythonver[0] < 2 or (pythonver[0] == 2 and pythonver[1] < 5):
55 print "Sorry, bitbake needs python 2.5 or later."
56 sys.exit(1)
57
58 parser = optparse.OptionParser( version = "BitBake Build Tool Core version %s, %%prog version %s" % ( bb.__version__, __version__ ),
59 usage = """%prog [options] [package ...]
60
61Executes the specified task (default is 'build') for a given set of BitBake files.
62It expects that BBFILES is defined, which is a space separated list of files to
63be executed. BBFILES does support wildcards.
64Default BBFILES are the .bb files in the current directory.""" )
65
66 parser.add_option( "-b", "--buildfile", help = "execute the task against this .bb file, rather than a package from BBFILES.",
67 action = "store", dest = "buildfile", default = None )
68
69 parser.add_option( "-k", "--continue", help = "continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other dependencies of these targets can be processed all the same.",
70 action = "store_false", dest = "abort", default = True )
71
72 parser.add_option( "-f", "--force", help = "force run of specified cmd, regardless of stamp status",
73 action = "store_true", dest = "force", default = False )
74
75 parser.add_option( "-i", "--interactive", help = "drop into the interactive mode also called the BitBake shell.",
76 action = "store_true", dest = "interactive", default = False )
77
78 parser.add_option( "-c", "--cmd", help = "Specify task to execute. Note that this only executes the specified task for the providee and the packages it depends on, i.e. 'compile' does not implicitly call stage for the dependencies (IOW: use only if you know what you are doing). Depending on the base.bbclass a listtasks tasks is defined and will show available tasks",
79 action = "store", dest = "cmd" )
80
81 parser.add_option( "-r", "--read", help = "read the specified file before bitbake.conf",
82 action = "append", dest = "file", default = [] )
83
84 parser.add_option( "-v", "--verbose", help = "output more chit-chat to the terminal",
85 action = "store_true", dest = "verbose", default = False )
86
87 parser.add_option( "-D", "--debug", help = "Increase the debug level. You can specify this more than once.",
88 action = "count", dest="debug", default = 0)
89
90 parser.add_option( "-n", "--dry-run", help = "don't execute, just go through the motions",
91 action = "store_true", dest = "dry_run", default = False )
92
93 parser.add_option( "-p", "--parse-only", help = "quit after parsing the BB files (developers only)",
94 action = "store_true", dest = "parse_only", default = False )
95
96 parser.add_option( "-d", "--disable-psyco", help = "disable using the psyco just-in-time compiler (not recommended)",
97 action = "store_true", dest = "disable_psyco", default = False )
98
99 parser.add_option( "-s", "--show-versions", help = "show current and preferred versions of all packages",
100 action = "store_true", dest = "show_versions", default = False )
101
102 parser.add_option( "-e", "--environment", help = "show the global or per-package environment (this is what used to be bbread)",
103 action = "store_true", dest = "show_environment", default = False )
104
105 parser.add_option( "-g", "--graphviz", help = "emit the dependency trees of the specified packages in the dot syntax",
106 action = "store_true", dest = "dot_graph", default = False )
107
108 parser.add_option( "-I", "--ignore-deps", help = """Assume these dependencies don't exist and are already provided (equivalent to ASSUME_PROVIDED). Useful to make dependency graphs more appealing""",
109 action = "append", dest = "extra_assume_provided", default = [] )
110
111 parser.add_option( "-l", "--log-domains", help = """Show debug logging for the specified logging domains""",
112 action = "append", dest = "debug_domains", default = [] )
113
114 parser.add_option( "-P", "--profile", help = "profile the command and print a report",
115 action = "store_true", dest = "profile", default = False )
116
117 parser.add_option( "-u", "--ui", help = "userinterface to use",
118 action = "store", dest = "ui")
119
120 options, args = parser.parse_args(sys.argv)
121
122 configuration = BBConfiguration(options)
123 configuration.pkgs_to_build = []
124 configuration.pkgs_to_build.extend(args[1:])
125
126
127 # Work out which UI(s) to use
128 curseUI = False
129 depexplorerUI = False
130 if configuration.ui:
131 if configuration.ui == "ncurses":
132 curseUI = True
133 elif configuration.ui == "knotty" or configuration.ui == "tty" or configuration.ui == "file":
134 curseUI = False
135 elif configuration.ui == "depexp":
136 depexplorerUI = True
137 else:
138 print "FATAL: Invalid user interface '%s' specified.\nValid interfaces are 'ncurses', 'depexp' or the default, 'knotty'." % configuration.ui
139 sys.exit(1)
140
141
142 cooker = bb.cooker.BBCooker(configuration)
143 host = cooker.server.host
144 port = cooker.server.port
145
146 # Save a logfile for cooker somewhere
147 t = bb.data.getVar('TMPDIR', cooker.configuration.data, True)
148 if not t:
149 bb.msg.fatal(bb.msg.domain.Build, "TMPDIR not set")
150 t = os.path.join(t, "cooker")
151 bb.mkdirhier(t)
152 cooker_logfile = "%s/log.cooker.%s" % (t, str(os.getpid()))
153
154 daemonize.createDaemon(cooker.serve, cooker_logfile)
155 del cooker
156
157 # Setup a connection to the server (cooker)
158 server = xmlrpclib.Server("http://%s:%s" % (host, port), allow_none=True)
159 # Setup an event receiving queue
160 eventHandler = uievent.BBUIEventQueue(server)
161
162 # Launch the UI
163 try:
164 # Disable UIs that need a terminal
165 if not os.isatty(sys.stdout.fileno()):
166 curseUI = False
167
168 if curseUI:
169 try:
170 import curses
171 except ImportError, details:
172 curseUI = False
173
174 if curseUI:
175 from bb.ui import ncurses
176 ncurses.init(server, eventHandler)
177 elif depexplorerUI:
178 from bb.ui import depexplorer
179 depexplorer.init(server, eventHandler)
180 else:
181 from bb.ui import knotty
182 return_value = knotty.init(server, eventHandler)
183
184 finally:
185 # Don't wait for server indefinitely
186 import socket
187 socket.setdefaulttimeout(2)
188 try:
189 eventHandler.system_quit()
190 except:
191 pass
192 try:
193 server.terminateServer()
194 except:
195 pass
196 return return_value
197
198if __name__ == "__main__":
199 print """WARNING, WARNING, WARNING
200This is a Bitbake from the Unstable/Development 1.9 Branch. This software is a work in progress and should only be used by Bitbake developers/testers"""
201
202 ret = main()
203 sys.exit(ret)
204
diff --git a/bitbake-dev/bin/bitdoc b/bitbake-dev/bin/bitdoc
new file mode 100755
index 0000000000..3bcc9b344b
--- /dev/null
+++ b/bitbake-dev/bin/bitdoc
@@ -0,0 +1,532 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (C) 2005 Holger Hans Peter Freyther
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20import optparse, os, sys
21
22# bitbake
23sys.path.append(os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
24import bb
25import bb.parse
26from string import split, join
27
28__version__ = "0.0.2"
29
30class HTMLFormatter:
31 """
32 Simple class to help to generate some sort of HTML files. It is
33 quite inferior solution compared to docbook, gtkdoc, doxygen but it
34 should work for now.
35 We've a global introduction site (index.html) and then one site for
36 the list of keys (alphabetical sorted) and one for the list of groups,
37 one site for each key with links to the relations and groups.
38
39 index.html
40 all_keys.html
41 all_groups.html
42 groupNAME.html
43 keyNAME.html
44 """
45
46 def replace(self, text, *pairs):
47 """
48 From pydoc... almost identical at least
49 """
50 while pairs:
51 (a,b) = pairs[0]
52 text = join(split(text, a), b)
53 pairs = pairs[1:]
54 return text
55 def escape(self, text):
56 """
57 Escape string to be conform HTML
58 """
59 return self.replace(text,
60 ('&', '&amp;'),
61 ('<', '&lt;' ),
62 ('>', '&gt;' ) )
63 def createNavigator(self):
64 """
65 Create the navgiator
66 """
67 return """<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
68<tr valign="middle">
69<td><a accesskey="g" href="index.html">Home</a></td>
70<td><a accesskey="n" href="all_groups.html">Groups</a></td>
71<td><a accesskey="u" href="all_keys.html">Keys</a></td>
72</tr></table>
73"""
74
75 def relatedKeys(self, item):
76 """
77 Create HTML to link to foreign keys
78 """
79
80 if len(item.related()) == 0:
81 return ""
82
83 txt = "<p><b>See also:</b><br>"
84 txts = []
85 for it in item.related():
86 txts.append("""<a href="key%(it)s.html">%(it)s</a>""" % vars() )
87
88 return txt + ",".join(txts)
89
90 def groups(self,item):
91 """
92 Create HTML to link to related groups
93 """
94
95 if len(item.groups()) == 0:
96 return ""
97
98
99 txt = "<p><b>See also:</b><br>"
100 txts = []
101 for group in item.groups():
102 txts.append( """<a href="group%s.html">%s</a> """ % (group,group) )
103
104 return txt + ",".join(txts)
105
106
107 def createKeySite(self,item):
108 """
109 Create a site for a key. It contains the header/navigator, a heading,
110 the description, links to related keys and to the groups.
111 """
112
113 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
114<html><head><title>Key %s</title></head>
115<link rel="stylesheet" href="style.css" type="text/css">
116<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
117%s
118<h2><span class="refentrytitle">%s</span></h2>
119
120<div class="refsynopsisdiv">
121<h2>Synopsis</h2>
122<p>
123%s
124</p>
125</div>
126
127<div class="refsynopsisdiv">
128<h2>Related Keys</h2>
129<p>
130%s
131</p>
132</div>
133
134<div class="refsynopsisdiv">
135<h2>Groups</h2>
136<p>
137%s
138</p>
139</div>
140
141
142</body>
143""" % (item.name(), self.createNavigator(), item.name(),
144 self.escape(item.description()), self.relatedKeys(item), self.groups(item))
145
146 def createGroupsSite(self, doc):
147 """
148 Create the Group Overview site
149 """
150
151 groups = ""
152 sorted_groups = doc.groups()
153 sorted_groups.sort()
154 for group in sorted_groups:
155 groups += """<a href="group%s.html">%s</a><br>""" % (group, group)
156
157 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
158<html><head><title>Group overview</title></head>
159<link rel="stylesheet" href="style.css" type="text/css">
160<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
161%s
162<h2>Available Groups</h2>
163%s
164</body>
165""" % (self.createNavigator(), groups)
166
167 def createIndex(self):
168 """
169 Create the index file
170 """
171
172 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
173<html><head><title>Bitbake Documentation</title></head>
174<link rel="stylesheet" href="style.css" type="text/css">
175<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
176%s
177<h2>Documentation Entrance</h2>
178<a href="all_groups.html">All available groups</a><br>
179<a href="all_keys.html">All available keys</a><br>
180</body>
181""" % self.createNavigator()
182
183 def createKeysSite(self, doc):
184 """
185 Create Overview of all avilable keys
186 """
187 keys = ""
188 sorted_keys = doc.doc_keys()
189 sorted_keys.sort()
190 for key in sorted_keys:
191 keys += """<a href="key%s.html">%s</a><br>""" % (key, key)
192
193 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
194<html><head><title>Key overview</title></head>
195<link rel="stylesheet" href="style.css" type="text/css">
196<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
197%s
198<h2>Available Keys</h2>
199%s
200</body>
201""" % (self.createNavigator(), keys)
202
203 def createGroupSite(self, gr, items, _description = None):
204 """
205 Create a site for a group:
206 Group the name of the group, items contain the name of the keys
207 inside this group
208 """
209 groups = ""
210 description = ""
211
212 # create a section with the group descriptions
213 if _description:
214 description += "<h2 Description of Grozp %s</h2>" % gr
215 description += _description
216
217 items.sort(lambda x,y:cmp(x.name(),y.name()))
218 for group in items:
219 groups += """<a href="key%s.html">%s</a><br>""" % (group.name(), group.name())
220
221 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
222<html><head><title>Group %s</title></head>
223<link rel="stylesheet" href="style.css" type="text/css">
224<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
225%s
226%s
227<div class="refsynopsisdiv">
228<h2>Keys in Group %s</h2>
229<pre class="synopsis">
230%s
231</pre>
232</div>
233</body>
234""" % (gr, self.createNavigator(), description, gr, groups)
235
236
237
238 def createCSS(self):
239 """
240 Create the CSS file
241 """
242 return """.synopsis, .classsynopsis
243{
244 background: #eeeeee;
245 border: solid 1px #aaaaaa;
246 padding: 0.5em;
247}
248.programlisting
249{
250 background: #eeeeff;
251 border: solid 1px #aaaaff;
252 padding: 0.5em;
253}
254.variablelist
255{
256 padding: 4px;
257 margin-left: 3em;
258}
259.variablelist td:first-child
260{
261 vertical-align: top;
262}
263table.navigation
264{
265 background: #ffeeee;
266 border: solid 1px #ffaaaa;
267 margin-top: 0.5em;
268 margin-bottom: 0.5em;
269}
270.navigation a
271{
272 color: #770000;
273}
274.navigation a:visited
275{
276 color: #550000;
277}
278.navigation .title
279{
280 font-size: 200%;
281}
282div.refnamediv
283{
284 margin-top: 2em;
285}
286div.gallery-float
287{
288 float: left;
289 padding: 10px;
290}
291div.gallery-float img
292{
293 border-style: none;
294}
295div.gallery-spacer
296{
297 clear: both;
298}
299a
300{
301 text-decoration: none;
302}
303a:hover
304{
305 text-decoration: underline;
306 color: #FF0000;
307}
308"""
309
310
311
312class DocumentationItem:
313 """
314 A class to hold information about a configuration
315 item. It contains the key name, description, a list of related names,
316 and the group this item is contained in.
317 """
318
319 def __init__(self):
320 self._groups = []
321 self._related = []
322 self._name = ""
323 self._desc = ""
324
325 def groups(self):
326 return self._groups
327
328 def name(self):
329 return self._name
330
331 def description(self):
332 return self._desc
333
334 def related(self):
335 return self._related
336
337 def setName(self, name):
338 self._name = name
339
340 def setDescription(self, desc):
341 self._desc = desc
342
343 def addGroup(self, group):
344 self._groups.append(group)
345
346 def addRelation(self,relation):
347 self._related.append(relation)
348
349 def sort(self):
350 self._related.sort()
351 self._groups.sort()
352
353
354class Documentation:
355 """
356 Holds the documentation... with mappings from key to items...
357 """
358
359 def __init__(self):
360 self.__keys = {}
361 self.__groups = {}
362
363 def insert_doc_item(self, item):
364 """
365 Insert the Doc Item into the internal list
366 of representation
367 """
368 item.sort()
369 self.__keys[item.name()] = item
370
371 for group in item.groups():
372 if not group in self.__groups:
373 self.__groups[group] = []
374 self.__groups[group].append(item)
375 self.__groups[group].sort()
376
377
378 def doc_item(self, key):
379 """
380 Return the DocumentationInstance describing the key
381 """
382 try:
383 return self.__keys[key]
384 except KeyError:
385 return None
386
387 def doc_keys(self):
388 """
389 Return the documented KEYS (names)
390 """
391 return self.__keys.keys()
392
393 def groups(self):
394 """
395 Return the names of available groups
396 """
397 return self.__groups.keys()
398
399 def group_content(self,group_name):
400 """
401 Return a list of keys/names that are in a specefic
402 group or the empty list
403 """
404 try:
405 return self.__groups[group_name]
406 except KeyError:
407 return []
408
409
410def parse_cmdline(args):
411 """
412 Parse the CMD line and return the result as a n-tuple
413 """
414
415 parser = optparse.OptionParser( version = "Bitbake Documentation Tool Core version %s, %%prog version %s" % (bb.__version__,__version__))
416 usage = """%prog [options]
417
418Create a set of html pages (documentation) for a bitbake.conf....
419"""
420
421 # Add the needed options
422 parser.add_option( "-c", "--config", help = "Use the specified configuration file as source",
423 action = "store", dest = "config", default = os.path.join("conf", "documentation.conf") )
424
425 parser.add_option( "-o", "--output", help = "Output directory for html files",
426 action = "store", dest = "output", default = "html/" )
427
428 parser.add_option( "-D", "--debug", help = "Increase the debug level",
429 action = "count", dest = "debug", default = 0 )
430
431 parser.add_option( "-v","--verbose", help = "output more chit-char to the terminal",
432 action = "store_true", dest = "verbose", default = False )
433
434 options, args = parser.parse_args( sys.argv )
435
436 if options.debug:
437 bb.msg.set_debug_level(options.debug)
438
439 return options.config, options.output
440
441def main():
442 """
443 The main Method
444 """
445
446 (config_file,output_dir) = parse_cmdline( sys.argv )
447
448 # right to let us load the file now
449 try:
450 documentation = bb.parse.handle( config_file, bb.data.init() )
451 except IOError:
452 bb.fatal( "Unable to open %s" % config_file )
453 except bb.parse.ParseError:
454 bb.fatal( "Unable to parse %s" % config_file )
455
456
457 # Assuming we've the file loaded now, we will initialize the 'tree'
458 doc = Documentation()
459
460 # defined states
461 state_begin = 0
462 state_see = 1
463 state_group = 2
464
465 for key in bb.data.keys(documentation):
466 data = bb.data.getVarFlag(key, "doc", documentation)
467 if not data:
468 continue
469
470 # The Documentation now starts
471 doc_ins = DocumentationItem()
472 doc_ins.setName(key)
473
474
475 tokens = data.split(' ')
476 state = state_begin
477 string= ""
478 for token in tokens:
479 token = token.strip(',')
480
481 if not state == state_see and token == "@see":
482 state = state_see
483 continue
484 elif not state == state_group and token == "@group":
485 state = state_group
486 continue
487
488 if state == state_begin:
489 string += " %s" % token
490 elif state == state_see:
491 doc_ins.addRelation(token)
492 elif state == state_group:
493 doc_ins.addGroup(token)
494
495 # set the description
496 doc_ins.setDescription(string)
497 doc.insert_doc_item(doc_ins)
498
499 # let us create the HTML now
500 bb.mkdirhier(output_dir)
501 os.chdir(output_dir)
502
503 # Let us create the sites now. We do it in the following order
504 # Start with the index.html. It will point to sites explaining all
505 # keys and groups
506 html_slave = HTMLFormatter()
507
508 f = file('style.css', 'w')
509 print >> f, html_slave.createCSS()
510
511 f = file('index.html', 'w')
512 print >> f, html_slave.createIndex()
513
514 f = file('all_groups.html', 'w')
515 print >> f, html_slave.createGroupsSite(doc)
516
517 f = file('all_keys.html', 'w')
518 print >> f, html_slave.createKeysSite(doc)
519
520 # now for each group create the site
521 for group in doc.groups():
522 f = file('group%s.html' % group, 'w')
523 print >> f, html_slave.createGroupSite(group, doc.group_content(group))
524
525 # now for the keys
526 for key in doc.doc_keys():
527 f = file('key%s.html' % doc.doc_item(key).name(), 'w')
528 print >> f, html_slave.createKeySite(doc.doc_item(key))
529
530
531if __name__ == "__main__":
532 main()