summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorAlejandro Hernandez <alejandro.hernandez@linux.intel.com>2017-06-20 14:11:44 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-01-20 22:31:56 +0000
commit8d94b9db221d1def42f091b991903faa2d1651ce (patch)
tree9d32da2801fe835cc451c9b69040e01691b87906 /scripts
parente153efde9754a650e555f46cba09680baabd7d7e (diff)
downloadpoky-8d94b9db221d1def42f091b991903faa2d1651ce.tar.gz
python: Restructure python packaging and replace it with autopackaging
The reason we have a manifest file for python is that our goal is to keep python-core as small as posible and add other python packages only when the user needs them, hence why we split upstream python into several packages. Although our manifest file has several issues: - Its unorganized and hard to read and understand it for an average human being. - When a new package needs to be added, the user actually has to modify the script that creates the manifest, then call the script to create a new manifest, and then submit a patch for both the script and the manifest, so its a little convoluted. - Git complains every single time a patch is submitted to the manifest, since it violates some of its guidelines. - It changes or may change with every release of python, its impossible to know if the required files for a certain package have changed (it could have more or less dependencies), the only way of doing so would be to install and test them all one by one on separate individual images, and even then we wouldnt know if they require less dependencies, we would just know if an extra dependency is required since it would complain, lets face it, this isnt feasible. - The same thing happens for new packages, if someone wants to add a new package, its dependencies need to be checked manually one by one. This patch fixes those issues, while adding some additional features. Features/Fixes: - A new manifest format is used (JSON), easy to read and understand. This file is parsed by the python recipe and python packages read from here are passed directly to bitbake during parsing time. - It provides an automatic manifest creation task (explained below), which automagically checks for every package dependencies and adds them to the new manifest, hence we will have on each package exactly what that package needs to be run, providing finer granularity. - Dependencies are also checked automagically for new packages (explained below). - Fixes the manifest in the following ways: * python-core should be base and all packages should depend on it, fixes lang, string, codecs, etc. * Fixes packages with repeated files (e.g. bssdb and db, or netclient and mime, and many others). - Sitecustomize was fixed since encoding was deprecated. - The JSON manifest file invalidates bitbake's cache, so if it changes the python package will be rebuilt. - It creates a solution for users that want precompiled bytecode files (*.pyc) INCLUDE_PYCS = "1" can be set by the user on their local.conf to include such files, some argument they get faster boot time, even when the files would be created on their first run?, but they also sometimes give a magic number error and take up space, so we leave it to the user to decide if they want them or not. - Fixes python-core dependencies, e.g. When python is run on an image, it TRIES to import everything it needs, but it doesnt necessarily fails when it doesnt find something, so even if we didnt know, we had errors like (trimmed on purpose): # trying /usr/lib/python2.7/_locale.so # trying /usr/lib/python2.7/lib-dynload/_locale.so # trying /usr/lib/python2.7/_sysconfigdata.so while it didnt complain about _locale it should have imported it, after creating a new manifest with the automated script we get: # trying /usr/lib/python2.7/lib-dynload/_locale.so dlopen("/usr/lib/python2.7/lib-dynload/_locale.so", 2); import _locale # dynamically loaded from /usr/lib/python2.7/lib-dynload/_locale.so How to use (after a new release of python, or maybe before every OE release): - A new task called create_manifest was added to the python package, which may be invoked via: $ bitbake python -c create_manifest This task runs a script on native python on our HOST system, and since the python and python-native packages come from the same source, we can use it to know the dependencies of each module as if we were doing it on an image, this script is called create_manifest.py and in a very simplistic way it does the following: 1. Reads the JSON manifest file and creates a dictionary data structure with all of our python packages, their FILES, RDEPENDS and SUMMARY. 2. Loops through all of them and runs every module listed on them asynchronously, determining every dependency that they have. 3. These module dependencies are then handled, to be able to know which packages contain those files and which should RDEPEND on one another. 4. The data structure that comes out of this, is then used to create a new manifest file which is automatically copied onto the user's python directory replacing the old one. Create_manifest script features: - Handles modules which dont exist anymore (new release for example). - Handles modules that are builtin. - Deals with modules which were not compiled (e.g. bsddb or ossaudiodev) - Deals with packages which include folders. - Deals with packages which include FILES with a wildcard. - The manifest can be constructed on a multilib environment as well. - This method works for both python modules and shared libraries used by python. How to add a new package: - If a user wants to add a new package all that has to be done is modify the python2-manifest.json file, and add the required file(s) to the FILES list, the script should handle all the rest. Real example: We want to add a web browser package, including the file webbrowser.py which at the moment is on python-misc. "webbrowser": { "files": ["${libdir}/python2.7/lib-dynload/webbrowser.py"], "rdepends": [], "summary": "Python Web Browser support"} Run bitbake python -c create_manifest and the resulting manifest should be completed after a few seconds, showing something like: "webbrowser": { "files": ["${libdir}/python2.7/webbrowser.py"], "rdepends": ["core","fcntl","io","pickle","shell","subprocess"], "summary": "Python Web Browser support"} Known errors/issues: - Some special packages are handled differently: core, misc, modules,dev, staticdev. All these should be handled manually, because they either include binaries, static libraries, include files, etc. (something that we cant import). Specifically static libraries are not not supported by this method and have to be handled by the user. - The change should be transparent to the user, other than the fact that now we CANT build python-foo (it was pretty dumb anyway, since what building python-foo actually did was building the whole python package anyway), but doing IMAGE_INSTALL_append = " python-foo" would create an image with the requested package with no issues. [YOCTO #11510] [YOCTO #11694] [YOCTO #11695] (From OE-Core rev: 6959e2e4dba5bbfa6ffd49c44e738cc1c38bc280) Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/contrib/python/generate-manifest-2.7.py426
1 files changed, 0 insertions, 426 deletions
diff --git a/scripts/contrib/python/generate-manifest-2.7.py b/scripts/contrib/python/generate-manifest-2.7.py
deleted file mode 100755
index ee7540399f..0000000000
--- a/scripts/contrib/python/generate-manifest-2.7.py
+++ /dev/null
@@ -1,426 +0,0 @@
1#!/usr/bin/env python
2
3# generate Python Manifest for the OpenEmbedded build system
4# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
5# (C) 2007 Jeremy Laine
6# licensed under MIT, see COPYING.MIT
7#
8# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
9# * Updated to no longer generate special -dbg package, instead use the
10# single system -dbg
11# * Update version with ".1" to indicate this change
12#
13# February 26, 2017 -- Ming Liu <peter.x.liu@external.atlascopco.com>
14# * Updated to support generating manifest for native python
15
16import os
17import sys
18import time
19import argparse
20
21VERSION = "2.7.2"
22
23__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
24__version__ = "20110222.2"
25
26class MakefileMaker:
27
28 def __init__( self, outfile, isNative ):
29 """initialize"""
30 self.packages = {}
31 self.excluded_pkgs = []
32 self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
33 self.isNative = isNative
34 self.output = outfile
35 self.out( """
36# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
37# Generator: '%s%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
38""" % ( sys.argv[0], ' --native' if isNative else '', __version__ ) )
39
40 #
41 # helper functions
42 #
43
44 def out( self, data ):
45 """print a line to the output file"""
46 self.output.write( "%s\n" % data )
47
48 def setPrefix( self, targetPrefix ):
49 """set a file prefix for addPackage files"""
50 self.targetPrefix = targetPrefix
51
52 def doProlog( self ):
53 self.out( """ """ )
54 self.out( "" )
55
56 def addPackage( self, name, description, dependencies, filenames, mod_exclude = False ):
57 """add a package to the Makefile"""
58 if type( filenames ) == type( "" ):
59 filenames = filenames.split()
60 fullFilenames = []
61 for filename in filenames:
62 if filename[0] != "$":
63 fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
64 else:
65 fullFilenames.append( filename )
66 if mod_exclude:
67 self.excluded_pkgs.append( name )
68 self.packages[name] = description, dependencies, fullFilenames
69
70 def doBody( self ):
71 """generate body of Makefile"""
72
73 global VERSION
74
75 #
76 # generate rprovides line for native
77 #
78
79 if self.isNative:
80 pkglist = []
81 for name in ['${PN}-modules'] + sorted(self.packages):
82 pkglist.append('%s-native' % name.replace('${PN}', 'python'))
83
84 self.out('RPROVIDES += "%s"' % " ".join(pkglist))
85 return
86
87 #
88 # generate provides line
89 #
90
91 provideLine = 'PROVIDES+=" \\\n'
92 for name in sorted(self.packages):
93 provideLine += " %s \\\n" % name
94 provideLine += '"'
95
96 self.out( provideLine )
97 self.out( "" )
98
99 #
100 # generate package line
101 #
102
103 packageLine = 'PACKAGES=" \\\n'
104 packageLine += ' ${PN}-dbg \\\n'
105 for name in sorted(self.packages):
106 if name.startswith("${PN}-distutils"):
107 if name == "${PN}-distutils":
108 packageLine += " %s-staticdev %s \\\n" % (name, name)
109 elif name != '${PN}-dbg':
110 packageLine += " %s \\\n" % name
111 packageLine += ' ${PN}-modules\\\n"'
112
113 self.out( packageLine )
114 self.out( "" )
115
116 #
117 # generate package variables
118 #
119
120 for name, data in sorted(self.packages.items()):
121 desc, deps, files = data
122
123 #
124 # write out the description, revision and dependencies
125 #
126 self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
127 self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
128
129 line = 'FILES_%s=" \\\n' % name
130
131 #
132 # check which directories to make in the temporary directory
133 #
134
135 dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
136 for target in files:
137 dirset[os.path.dirname( target )] = True
138
139 #
140 # generate which files to copy for the target (-dfR because whole directories are also allowed)
141 #
142
143 for target in files:
144 line += " %s \\\n" % target
145
146 line += '"'
147 self.out( line )
148 self.out( "" )
149
150 self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
151 line = 'RDEPENDS_${PN}-modules=" \\\n'
152
153 for name, data in sorted(self.packages.items()):
154 if name not in ['${PN}-dev', '${PN}-distutils-staticdev'] and name not in self.excluded_pkgs:
155 line += " %s \\\n" % name
156
157 line += '"'
158 self.out( line )
159 self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
160
161 def doEpilog( self ):
162 self.out( """""" )
163 self.out( "" )
164
165 def make( self ):
166 self.doProlog()
167 self.doBody()
168 self.doEpilog()
169
170if __name__ == "__main__":
171 parser = argparse.ArgumentParser( description='generate python manifest' )
172 parser.add_argument( '-n', '--native', help='generate manifest for native python', action='store_true' )
173 parser.add_argument( 'outfile', metavar='OUTPUT_FILE', nargs='?', default='', help='Output file (defaults to stdout)' )
174 args = parser.parse_args()
175
176 if args.outfile:
177 try:
178 os.unlink( args.outfile )
179 except Exception:
180 sys.exc_clear()
181 outfile = open( args.outfile, "w" )
182 else:
183 outfile = sys.stdout
184
185 m = MakefileMaker( outfile, args.native )
186
187 # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
188 # Parameters: revision, name, description, dependencies, filenames
189 #
190
191 m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re",
192 "__future__.* _abcoll.* abc.* ast.* copy.* copy_reg.* ConfigParser.* " +
193 "genericpath.* getopt.* linecache.* new.* " +
194 "os.* posixpath.* struct.* " +
195 "warnings.* site.* stat.* " +
196 "UserDict.* UserList.* UserString.* " +
197 "lib-dynload/binascii.so lib-dynload/_struct.so lib-dynload/time.so " +
198 "lib-dynload/xreadlines.so types.* platform.* ${bindir}/python* " +
199 "_weakrefset.* sysconfig.* _sysconfigdata.* " +
200 "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h " +
201 "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
202
203 m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
204 "${includedir} " +
205 "${libdir}/lib*${SOLIBSDEV} " +
206 "${libdir}/*.la " +
207 "${libdir}/*.a " +
208 "${libdir}/*.o " +
209 "${libdir}/pkgconfig " +
210 "${base_libdir}/*.a " +
211 "${base_libdir}/*.o " +
212 "${datadir}/aclocal " +
213 "${datadir}/pkgconfig " +
214 "config/Makefile ")
215
216 m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
217 "${bindir}/2to3 lib2to3" ) # package
218
219 m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
220 "${bindir}/idle idlelib" ) # package
221
222 m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
223 "${bindir}/pydoc pydoc.* pydoc_data" )
224
225 m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
226 "${bindir}/smtpd.* smtpd.*" )
227
228 m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
229 "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so audiodev.* sunaudio.* sunau.* toaiff.*" )
230
231 m.addPackage( "${PN}-bsddb", "Python bindings for the Berkeley Database", "${PN}-core",
232 "bsddb lib-dynload/_bsddb.so" ) # package
233
234 m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
235 "codecs.* encodings gettext.* locale.* lib-dynload/_locale.so lib-dynload/_codecs* lib-dynload/_multibytecodec.so lib-dynload/unicodedata.so stringprep.* xdrlib.*" )
236
237 m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
238 "py_compile.* compileall.*" )
239
240 m.addPackage( "${PN}-compiler", "Python compiler support", "${PN}-core",
241 "compiler" ) # package
242
243 m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-zlib",
244 "gzip.* zipfile.* tarfile.* lib-dynload/bz2.so" )
245
246 m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
247 "hashlib.* md5.* sha.* lib-dynload/crypt.so lib-dynload/_hashlib.so lib-dynload/_sha256.so lib-dynload/_sha512.so" )
248
249 m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
250 "lib-dynload/_csv.so csv.* optparse.* textwrap.*" )
251
252 m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
253 "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # directory + low level module
254
255 m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
256 "ctypes lib-dynload/_ctypes.so lib-dynload/_ctypes_test.so" ) # directory + low level module
257
258 m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
259 "_strptime.* calendar.* lib-dynload/datetime.so" )
260
261 m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
262 "anydbm.* dumbdbm.* whichdb.* " )
263
264 m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
265 "bdb.* pdb.*" )
266
267 m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
268 "difflib.*" )
269
270 m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
271 "config/lib*.a" ) # package
272
273 m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core ${PN}-email",
274 "config distutils" ) # package
275
276 m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
277 "doctest.*" )
278
279 m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
280 "imaplib.* email" ) # package
281
282 m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
283 "lib-dynload/fcntl.so" )
284
285 m.addPackage( "${PN}-hotshot", "Python hotshot performance profiler", "${PN}-core",
286 "hotshot lib-dynload/_hotshot.so" )
287
288 m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
289 "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
290
291 m.addPackage( "${PN}-importlib", "Python import implementation library", "${PN}-core",
292 "importlib" )
293
294 m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
295 "lib-dynload/gdbm.so" )
296
297 m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
298 "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" )
299
300 m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math ${PN}-textutils ${PN}-netclient ${PN}-contextlib",
301 "lib-dynload/_socket.so lib-dynload/_io.so lib-dynload/_ssl.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so " +
302 "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
303
304 m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re ${PN}-codecs",
305 "json lib-dynload/_json.so" ) # package
306
307 m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
308 "lib-dynload/_bisect.so lib-dynload/_collections.so lib-dynload/_heapq.so lib-dynload/_weakref.so lib-dynload/_functools.so " +
309 "lib-dynload/array.so lib-dynload/itertools.so lib-dynload/operator.so lib-dynload/parser.so " +
310 "atexit.* bisect.* code.* codeop.* collections.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
311 "tokenize.* traceback.* weakref.*" )
312
313 m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
314 "logging" ) # package
315
316 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
317 "mailbox.*" )
318
319 m.addPackage( "${PN}-math", "Python math support", "${PN}-core ${PN}-crypt",
320 "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" )
321
322 m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
323 "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
324
325 m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
326 "lib-dynload/mmap.so " )
327
328 m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
329 "lib-dynload/_multiprocessing.so multiprocessing" ) # package
330
331 m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
332 "*Cookie*.* " +
333 "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.* uuid.* rfc822.* mimetools.*" )
334
335 m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient ${PN}-shell ${PN}-threading",
336 "cgi.* *HTTPServer.* SocketServer.*" )
337
338 m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
339 "decimal.* fractions.* numbers.*" )
340
341 m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
342 "pickle.* shelve.* lib-dynload/cPickle.so pickletools.*" )
343
344 m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
345 "pkgutil.*")
346
347 m.addPackage( "${PN}-plistlib", "Generate and parse Mac OS X .plist files", "${PN}-core ${PN}-datetime ${PN}-io",
348 "plistlib.*")
349
350 m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
351 "pprint.*" )
352
353 m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
354 "profile.* pstats.* cProfile.* lib-dynload/_lsprof.so" )
355
356 m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
357 "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
358
359 m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
360 "lib-dynload/readline.so rlcompleter.*" )
361
362 m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
363 "lib-dynload/resource.so" )
364
365 m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
366 "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
367
368 m.addPackage( "${PN}-robotparser", "Python robots.txt parser", "${PN}-core ${PN}-netclient",
369 "robotparser.*")
370
371 m.addPackage( "${PN}-runpy", "Python script for locating/executing scripts in module namespace", "${PN}-core ${PN}-pkgutil",
372 "runpy.*")
373
374 m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
375 "subprocess.*" )
376
377 m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading ${PN}-zlib",
378 "lib-dynload/_sqlite3.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
379
380 m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
381 "sqlite3/test" )
382
383 m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
384 "lib-dynload/strop.so string.* stringold.*" )
385
386 m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
387 "lib-dynload/syslog.so" )
388
389 m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
390 "pty.* tty.*" )
391
392 m.addPackage( "${PN}-tests", "Python tests", "${PN}-core ${PN}-modules",
393 "test", True ) # package
394
395 m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
396 "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
397
398 m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
399 "lib-dynload/_tkinter.so lib-tk" ) # package
400
401 m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
402 "unittest/" )
403
404 m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
405 "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" )
406
407 m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-re",
408 "lib-dynload/_elementtree.so lib-dynload/pyexpat.so xml xmllib.*" ) # package
409
410 m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
411 "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.*" )
412
413 m.addPackage( "${PN}-zlib", "Python zlib compression support", "${PN}-core",
414 "lib-dynload/zlib.so" )
415
416 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
417 "mailbox.*" )
418
419 m.addPackage( "${PN}-argparse", "Python command line argument parser", "${PN}-core ${PN}-codecs ${PN}-textutils",
420 "argparse.*" )
421
422 m.addPackage( "${PN}-contextlib", "Python utilities for with-statement" +
423 "contexts.", "${PN}-core",
424 "${libdir}/python${PYTHON_MAJMIN}/contextlib.*" )
425
426 m.make()