2
# Copyright (C) 2001-2006 James Henstridge
3
# Copyright (C) 2007 Red Hat, Inc.
5
# linux.py: support for building the linux kernel
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
from jhbuild.errors import FatalError, BuildStateError
29
from jhbuild.modtypes import \
30
Package, get_dependencies, get_branch, register_module_type
32
__all__ = [ 'LinuxModule' ]
37
def __init__(self, version, path, branch):
38
self.version = version
42
def checkout(self, buildscript):
44
self.branch.checkout(buildscript)
45
if not os.path.exists(self.path):
46
raise BuildStateError(_('kconfig file %s was not created') % self.path)
49
class LinuxModule(Package):
50
'''For modules that are built with the linux kernel method of
51
make config, make, make install and make modules_install.'''
54
PHASE_CHECKOUT = 'checkout'
55
PHASE_FORCE_CHECKOUT = 'force_checkout'
57
PHASE_MRPROPER = 'mrproper'
58
PHASE_CONFIGURE = 'configure'
60
PHASE_KERNEL_INSTALL = 'kernel_install'
61
PHASE_MODULES_INSTALL = 'modules_install'
62
PHASE_HEADERS_INSTALL = 'headers_install'
63
PHASE_INSTALL = 'install'
65
def __init__(self, name, branch, kconfigs, makeargs,
66
dependencies, after, suggests):
67
Package.__init__(self, name, dependencies, after, suggests)
69
self.kconfigs = kconfigs
70
self.makeargs = makeargs
72
def get_srcdir(self, buildscript):
73
return self.branch.srcdir
75
def get_builddir(self, buildscript):
76
return self.get_srcdir(buildscript)
78
def get_revision(self):
79
return self.branch.branchname
81
def skip_checkout(self, buildscript, last_phase):
82
# skip the checkout stage if the nonetwork flag is set
83
# (can't just call Package.skip_checkout() as build policy won't work
85
return buildscript.config.nonetwork
87
def do_checkout(self, buildscript):
88
buildscript.set_action(_('Checking out'), self)
89
self.checkout(buildscript)
90
for kconfig in self.kconfigs:
91
kconfig.checkout(buildscript)
92
do_checkout.error_phases = [PHASE_MRPROPER]
94
def do_force_checkout(self, buildscript):
95
buildscript.set_action(_('Checking out'), self)
96
self.branch.force_checkout(buildscript)
97
do_force_checkout.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_MRPROPER]
99
def get_makeargs(self):
100
return self.makeargs + ' ' + self.config.module_makeargs.get(self.name, self.config.makeargs)
102
def do_mrproper(self, buildscript):
103
buildscript.set_action(_('make mrproper'), self)
104
for kconfig in self.kconfigs:
105
cmd = '%s %s mrproper EXTRAVERSION=%s O=%s' % (
106
os.environ.get('MAKE', 'make'),
109
'build-' + kconfig.version)
110
buildscript.execute(cmd, cwd = self.branch.srcdir,
111
extra_env = self.extra_env)
113
cmd = '%s mrproper' % os.environ.get('MAKE', 'make')
114
buildscript.execute(cmd, cwd = self.branch.srcdir,
115
extra_env = self.extra_env)
116
do_mrproper.depends = [PHASE_CHECKOUT]
118
def do_configure(self, buildscript):
119
buildscript.set_action(_('Configuring'), self)
121
for kconfig in self.kconfigs:
123
shutil.copyfile(kconfig.path, os.path.join(self.branch.srcdir, ".config"))
126
os.makedirs(os.path.join(self.branch.srcdir, 'build-' + kconfig.version))
127
except OSError, (e, msg):
128
if e != errno.EEXIST:
132
cmd = '%s oldconfig EXTRAVERSION=%s O=%s'
134
cmd = '%s defconfig EXTRAVERSION=%s O=%s'
137
os.environ.get('MAKE', 'make'),
139
'build-' + kconfig.version)
141
buildscript.execute(cmd, cwd = self.branch.srcdir,
142
extra_env = self.extra_env)
145
os.remove(os.path.join(self.branch.srcdir, ".config"))
147
do_configure.depends = [PHASE_MRPROPER]
148
do_configure.error_phases = [PHASE_FORCE_CHECKOUT]
150
def do_clean(self, buildscript):
151
buildscript.set_action(_('Cleaning'), self)
152
for kconfig in self.kconfigs:
153
cmd = '%s %s clean EXTRAVERSION=%s O=%s' % (
154
os.environ.get('MAKE', 'make'),
157
'build-' + kconfig.version)
158
buildscript.execute(cmd, cwd = self.branch.srcdir,
159
extra_env = self.extra_env)
161
do_clean.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
163
def do_build(self, buildscript):
164
buildscript.set_action(_('Building'), self)
165
for kconfig in self.kconfigs:
166
cmd = '%s %s EXTRAVERSION=%s O=%s' % (os.environ.get('MAKE', 'make'),
169
'build-' + kconfig.version)
170
buildscript.execute(cmd, cwd = self.branch.srcdir,
171
extra_env = self.extra_env)
173
do_build.depends = [PHASE_CONFIGURE]
174
do_build.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_MRPROPER, PHASE_CONFIGURE]
176
def do_kernel_install(self, buildscript):
177
buildscript.set_action(_('Installing kernel'), self)
178
bootdir = os.path.join(buildscript.config.prefix, 'boot')
179
if not os.path.isdir(bootdir):
181
for kconfig in self.kconfigs:
182
# We do this on our own without 'make install' because things will go weird on the user
183
# if they have a custom installkernel script in ~/bin or /sbin/ and we can't override this.
184
for f in ("System.map", ".config", "vmlinux"):
186
os.path.join('build-'+kconfig.version, f),
187
os.path.join(bootdir, f+'-'+kconfig.version))
188
buildscript.execute(cmd, cwd = self.branch.srcdir,
189
extra_env = self.extra_env)
191
do_kernel_install.depends = [PHASE_BUILD]
192
do_kernel_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
194
def do_modules_install(self, buildscript):
195
buildscript.set_action(_('Installing modules'), self)
196
for kconfig in self.kconfigs:
197
cmd = '%s %s modules_install EXTRAVERSION=%s O=%s INSTALL_MOD_PATH=%s' % (
198
os.environ.get('MAKE', 'make'),
201
'build-' + kconfig.version,
202
buildscript.config.prefix)
203
buildscript.execute(cmd, cwd = self.branch.srcdir,
204
extra_env = self.extra_env)
206
do_modules_install.depends = [PHASE_BUILD]
207
do_modules_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
209
def do_headers_install(self, buildscript):
210
buildscript.set_action(_('Installing kernel headers'), self)
211
for kconfig in self.kconfigs:
212
cmd = '%s %s headers_install EXTRAVERSION=%s O=%s INSTALL_HDR_PATH=%s' % (
213
os.environ.get('MAKE', 'make'),
216
'build-' + kconfig.version,
217
buildscript.config.prefix)
218
buildscript.execute(cmd, cwd = self.branch.srcdir,
219
extra_env = self.extra_env)
220
buildscript.packagedb.add(self.name, self.get_revision() or '')
222
do_headers_install.depends = [PHASE_BUILD]
223
do_headers_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
225
def do_install(self, buildscript):
227
do_install.depends = [PHASE_KERNEL_INSTALL, PHASE_MODULES_INSTALL, PHASE_HEADERS_INSTALL]
229
def xml_tag_and_attrs(self):
230
return 'linux', [('id', 'name', None),
231
('makeargs', 'makeargs', '')]
234
def get_kconfigs(node, repositories, default_repo):
235
id = node.getAttribute('id')
239
for childnode in node.childNodes:
240
if childnode.nodeType != childnode.ELEMENT_NODE or childnode.nodeName != 'kconfig':
243
if childnode.hasAttribute('repo'):
244
repo_name = childnode.getAttribute('repo')
246
repo = repositories[repo_name]
248
raise FatalError(_('Repository=%s not found for kconfig in linux id=%s. Possible repositories are %s') % (repo_name, id, repositories))
251
repo = repositories[default_repo]
253
raise FatalError(_('Default Repository=%s not found for kconfig in module id=%s. Possible repositories are %s') % (default_repo, id, repositories))
255
branch = repo.branch_from_xml(id, childnode, repositories, default_repo)
257
version = childnode.getAttribute('version')
259
if childnode.hasAttribute('config'):
260
path = os.path.join(kconfig.srcdir, childnode.getAttribute('config'))
262
path = kconfig.srcdir
264
kconfig = LinuxConfig(version, path, branch)
265
kconfigs.append(kconfig)
268
kconfig = LinuxConfig('default', None, None)
269
kconfigs.append(kconfig)
273
def parse_linux(node, config, uri, repositories, default_repo):
274
id = node.getAttribute('id')
277
if node.hasAttribute('makeargs'):
278
makeargs = node.getAttribute('makeargs')
279
# Make some substitutions; do special handling of '${prefix}' and '${libdir}'
280
p = re.compile('(\${prefix})')
281
makeargs = p.sub(config.prefix, makeargs)
283
dependencies, after, suggests = get_dependencies(node)
284
branch = get_branch(node, repositories, default_repo, config)
285
kconfigs = get_kconfigs(node, repositories, default_repo)
287
return LinuxModule(id, branch, kconfigs,
288
makeargs, dependencies, after, suggests)
290
register_module_type('linux', parse_linux)