3 # Add 'bdist_debian' Debian binary package distribution support to 'distutils'.
5 # This command builds '.deb' packages and supports the "Maemo" extensions for the Nokia N770/N800/N810.
7 # Written by: Gene Cash <gene.cash@gmail.com> 16-NOV-2007
10 from distutils.core import Command, Distribution
11 from distutils.dir_util import remove_tree
12 from distutils.util import byte_compile
14 # make these legal keywords for setup()
15 Distribution.icon=None
16 Distribution.section=None
17 Distribution.depends=None
19 class ControlFile(object):
20 def __init__(self, Installed_Size=0, Long_Description='', Description='', Icon='', **kwargs):
22 self.description=Description
23 self.long_description=Long_Description
25 self.installed_size=Installed_Size
28 content=['%s: %s' % (k, v) for k,v in self.options.iteritems()]
30 content.append('Installed-Size: %d' % self.installed_size)
31 if self.description != 'UNKNOWN':
32 content.append('Description: %s' % self.description.strip())
33 if self.long_description != 'UNKNOWN':
34 self.long_description=self.long_description.replace('\n', '\n ')
35 content.append(' '+self.long_description.strip())
38 # generate Base64-encoded icon
39 s=file(self.icon, 'rb').read()
41 # wrap width MUST be 76 characters to make application manager happy after install
43 # trailing blank is important, and the XB- is NOT legal
44 content.append('XB-Maemo-Icon-26: ')
45 for i in range(0, len(x), lw):
46 content.append(' '+x[i:i+lw])
48 # must have two returns
49 return '\n'.join(content)+'\n\n'
51 class bdist_debian(Command):
53 # List of option tuples: long name, short name (None if no short name), and help string.
54 user_options=[('name=', None, 'Package name'),
55 ('section=', None, 'Section (Only "user/*" will display in App Mgr usually)'),
56 ('priority=', None, 'Priority'),
57 ('depends=', None, 'Other Debian package dependencies (comma separated)'),
58 ('icon=', None, 'Name of icon file to be displayed by App Mgr')]
60 def initialize_options(self):
66 def finalize_options(self):
67 if self.section is None:
68 self.section='user/other'
70 if self.priority is None:
71 self.priority='optional'
73 self.maintainer='%s <%s>' % (self.distribution.get_maintainer(), self.distribution.get_maintainer_email())
75 if self.depends is None:
76 self.depends='python2.5'
78 self.name=self.distribution.get_name()
79 self.description=self.distribution.get_description()
80 self.long_description=self.distribution.get_long_description()
81 self.version=self.distribution.get_version()
83 # process new keywords
84 if self.distribution.icon != None:
85 self.icon=self.distribution.icon
86 if self.distribution.section != None:
87 self.section=self.distribution.section
88 if self.distribution.depends != None:
89 self.depends=self.distribution.depends
92 build_dir=os.path.join(self.get_finalized_command('build').build_base, 'nokia')
94 binary_fn='debian-binary'
99 # build everything locally
100 self.run_command('build')
101 install=self.reinitialize_command('install', reinit_subcommands=1)
102 install.root=build_dir
103 self.run_command('install')
105 # find out how much space it takes
107 for root, dirs, files in os.walk('build'):
108 installed_size+=sum(os.path.getsize(os.path.join(root, name)) for name in files)
110 # make compressed tarball
111 self.make_archive(os.path.join(dist_dir, data_fn), 'gztar', root_dir=build_dir)
113 # remove all the stuff we just built
114 remove_tree(build_dir)
116 # create control file contents
117 ctl=ControlFile(Package=self.name, Version=self.version, Section=self.section, Priority=self.priority,
118 Installed_Size=installed_size/1024+1, Architecture='all', Maintainer=self.maintainer,
119 Depends=self.depends, Description=self.description, Long_Description=self.long_description,
120 Icon=self.icon).getContent()
124 for fn in ('postinst', 'preinst', 'postrm', 'prerm', 'config'):
125 if os.path.exists(fn):
126 scripts[fn]=file(fn, 'rb').read()
128 # now to create the deb package
132 file(control_fn, 'wb').write(ctl)
134 # write any scripts and chmod a+rx them
138 file(fn, 'wb').write(scripts[fn])
141 # make "control" compressed tarball with control file and any scripts
142 self.spawn(['tar', '-czf', control_fn+tgz_ext]+files)
144 # make debian-binary file
145 file(binary_fn, 'wb').write('2.0\n')
148 package_filename='%s_%s_all.deb' % (self.name, self.version)
149 self.spawn(['ar', '-cr', package_filename, binary_fn, control_fn+tgz_ext, data_fn+tgz_ext])