PageRenderTime 105ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/jhbuild/modtypes/linux.py

https://github.com/oliver/jhbuild
Python | 290 lines | 226 code | 38 blank | 26 comment | 22 complexity | 575f1d2ea0918106647c823bdf0e0812 MD5 | raw file
  1. #
  2. # Copyright (C) 2001-2006 James Henstridge
  3. # Copyright (C) 2007 Red Hat, Inc.
  4. #
  5. # linux.py: support for building the linux kernel
  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 as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  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.
  16. #
  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
  20. __metaclass__ = type
  21. import os
  22. import re
  23. import shutil
  24. import errno
  25. from jhbuild.errors import FatalError, BuildStateError
  26. from jhbuild.modtypes import \
  27. Package, get_dependencies, get_branch, register_module_type
  28. __all__ = [ 'LinuxModule' ]
  29. class LinuxConfig:
  30. def __init__(self, version, path, branch):
  31. self.version = version
  32. self.path = path
  33. self.branch = branch
  34. def checkout(self, buildscript):
  35. if self.branch:
  36. self.branch.checkout(buildscript)
  37. if not os.path.exists(self.path):
  38. raise BuildStateError(_('kconfig file %s was not created') % self.path)
  39. class LinuxModule(Package):
  40. '''For modules that are built with the linux kernel method of
  41. make config, make, make install and make modules_install.'''
  42. type = 'linux'
  43. PHASE_CHECKOUT = 'checkout'
  44. PHASE_FORCE_CHECKOUT = 'force_checkout'
  45. PHASE_CLEAN = 'clean'
  46. PHASE_MRPROPER = 'mrproper'
  47. PHASE_CONFIGURE = 'configure'
  48. PHASE_BUILD = 'build'
  49. PHASE_KERNEL_INSTALL = 'kernel_install'
  50. PHASE_MODULES_INSTALL = 'modules_install'
  51. PHASE_HEADERS_INSTALL = 'headers_install'
  52. PHASE_INSTALL = 'install'
  53. def __init__(self, name, branch, kconfigs, makeargs,
  54. dependencies, after, suggests):
  55. Package.__init__(self, name, dependencies, after, suggests)
  56. self.branch = branch
  57. self.kconfigs = kconfigs
  58. self.makeargs = makeargs
  59. def get_srcdir(self, buildscript):
  60. return self.branch.srcdir
  61. def get_builddir(self, buildscript):
  62. return self.get_srcdir(buildscript)
  63. def get_revision(self):
  64. return self.branch.branchname
  65. def skip_checkout(self, buildscript, last_phase):
  66. # skip the checkout stage if the nonetwork flag is set
  67. # (can't just call Package.skip_checkout() as build policy won't work
  68. # with kconfigs)
  69. return buildscript.config.nonetwork
  70. def do_checkout(self, buildscript):
  71. buildscript.set_action(_('Checking out'), self)
  72. self.checkout(buildscript)
  73. for kconfig in self.kconfigs:
  74. kconfig.checkout(buildscript)
  75. do_checkout.error_phases = [PHASE_MRPROPER]
  76. def do_force_checkout(self, buildscript):
  77. buildscript.set_action(_('Checking out'), self)
  78. self.branch.force_checkout(buildscript)
  79. do_force_checkout.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_MRPROPER]
  80. def get_makeargs(self):
  81. return self.makeargs + ' ' + self.config.module_makeargs.get(self.name, self.config.makeargs)
  82. def do_mrproper(self, buildscript):
  83. buildscript.set_action(_('make mrproper'), self)
  84. for kconfig in self.kconfigs:
  85. cmd = '%s %s mrproper EXTRAVERSION=%s O=%s' % (
  86. os.environ.get('MAKE', 'make'),
  87. self.get_makeargs(),
  88. kconfig.version,
  89. 'build-' + kconfig.version)
  90. buildscript.execute(cmd, cwd = self.branch.srcdir,
  91. extra_env = self.extra_env)
  92. cmd = '%s mrproper' % os.environ.get('MAKE', 'make')
  93. buildscript.execute(cmd, cwd = self.branch.srcdir,
  94. extra_env = self.extra_env)
  95. do_mrproper.depends = [PHASE_CHECKOUT]
  96. def do_configure(self, buildscript):
  97. buildscript.set_action(_('Configuring'), self)
  98. for kconfig in self.kconfigs:
  99. if kconfig.path:
  100. shutil.copyfile(kconfig.path, os.path.join(self.branch.srcdir, ".config"))
  101. try:
  102. os.makedirs(os.path.join(self.branch.srcdir, 'build-' + kconfig.version))
  103. except OSError, (e, msg):
  104. if e != errno.EEXIST:
  105. raise
  106. if kconfig.branch:
  107. cmd = '%s oldconfig EXTRAVERSION=%s O=%s'
  108. else:
  109. cmd = '%s defconfig EXTRAVERSION=%s O=%s'
  110. cmd = cmd % (
  111. os.environ.get('MAKE', 'make'),
  112. kconfig.version,
  113. 'build-' + kconfig.version)
  114. buildscript.execute(cmd, cwd = self.branch.srcdir,
  115. extra_env = self.extra_env)
  116. if kconfig.path:
  117. os.remove(os.path.join(self.branch.srcdir, ".config"))
  118. do_configure.depends = [PHASE_MRPROPER]
  119. do_configure.error_phases = [PHASE_FORCE_CHECKOUT]
  120. def do_clean(self, buildscript):
  121. buildscript.set_action(_('Cleaning'), self)
  122. for kconfig in self.kconfigs:
  123. cmd = '%s %s clean EXTRAVERSION=%s O=%s' % (
  124. os.environ.get('MAKE', 'make'),
  125. self.get_makeargs(),
  126. kconfig.version,
  127. 'build-' + kconfig.version)
  128. buildscript.execute(cmd, cwd = self.branch.srcdir,
  129. extra_env = self.extra_env)
  130. do_clean.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
  131. def do_build(self, buildscript):
  132. buildscript.set_action(_('Building'), self)
  133. for kconfig in self.kconfigs:
  134. cmd = '%s %s EXTRAVERSION=%s O=%s' % (os.environ.get('MAKE', 'make'),
  135. self.get_makeargs(),
  136. kconfig.version,
  137. 'build-' + kconfig.version)
  138. buildscript.execute(cmd, cwd = self.branch.srcdir,
  139. extra_env = self.extra_env)
  140. do_build.depends = [PHASE_CONFIGURE]
  141. do_build.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_MRPROPER, PHASE_CONFIGURE]
  142. def do_kernel_install(self, buildscript):
  143. buildscript.set_action(_('Installing kernel'), self)
  144. bootdir = os.path.join(buildscript.config.prefix, 'boot')
  145. if not os.path.isdir(bootdir):
  146. os.makedirs(bootdir)
  147. for kconfig in self.kconfigs:
  148. # We do this on our own without 'make install' because things will go weird on the user
  149. # if they have a custom installkernel script in ~/bin or /sbin/ and we can't override this.
  150. for f in ("System.map", ".config", "vmlinux"):
  151. cmd = "cp %s %s" % (
  152. os.path.join('build-'+kconfig.version, f),
  153. os.path.join(bootdir, f+'-'+kconfig.version))
  154. buildscript.execute(cmd, cwd = self.branch.srcdir,
  155. extra_env = self.extra_env)
  156. do_kernel_install.depends = [PHASE_BUILD]
  157. do_kernel_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
  158. def do_modules_install(self, buildscript):
  159. buildscript.set_action(_('Installing modules'), self)
  160. for kconfig in self.kconfigs:
  161. cmd = '%s %s modules_install EXTRAVERSION=%s O=%s INSTALL_MOD_PATH=%s' % (
  162. os.environ.get('MAKE', 'make'),
  163. self.get_makeargs(),
  164. kconfig.version,
  165. 'build-' + kconfig.version,
  166. buildscript.config.prefix)
  167. buildscript.execute(cmd, cwd = self.branch.srcdir,
  168. extra_env = self.extra_env)
  169. do_modules_install.depends = [PHASE_BUILD]
  170. do_modules_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
  171. def do_headers_install(self, buildscript):
  172. buildscript.set_action(_('Installing kernel headers'), self)
  173. for kconfig in self.kconfigs:
  174. cmd = '%s %s headers_install EXTRAVERSION=%s O=%s INSTALL_HDR_PATH=%s' % (
  175. os.environ.get('MAKE', 'make'),
  176. self.get_makeargs(),
  177. kconfig.version,
  178. 'build-' + kconfig.version,
  179. buildscript.config.prefix)
  180. buildscript.execute(cmd, cwd = self.branch.srcdir,
  181. extra_env = self.extra_env)
  182. buildscript.packagedb.add(self.name, self.get_revision() or '')
  183. do_headers_install.depends = [PHASE_BUILD]
  184. do_headers_install.error_phases = [PHASE_FORCE_CHECKOUT, PHASE_CONFIGURE]
  185. def do_install(self, buildscript):
  186. pass
  187. do_install.depends = [PHASE_KERNEL_INSTALL, PHASE_MODULES_INSTALL, PHASE_HEADERS_INSTALL]
  188. def xml_tag_and_attrs(self):
  189. return 'linux', [('id', 'name', None),
  190. ('makeargs', 'makeargs', '')]
  191. def get_kconfigs(node, repositories, default_repo):
  192. id = node.getAttribute('id')
  193. kconfigs = []
  194. for childnode in node.childNodes:
  195. if childnode.nodeType != childnode.ELEMENT_NODE or childnode.nodeName != 'kconfig':
  196. continue
  197. if childnode.hasAttribute('repo'):
  198. repo_name = childnode.getAttribute('repo')
  199. try:
  200. repo = repositories[repo_name]
  201. except KeyError:
  202. raise FatalError(_('Repository=%s not found for kconfig in linux id=%s. Possible repositories are %s') % (repo_name, id, repositories))
  203. else:
  204. try:
  205. repo = repositories[default_repo]
  206. except KeyError:
  207. raise FatalError(_('Default Repository=%s not found for kconfig in module id=%s. Possible repositories are %s') % (default_repo, id, repositories))
  208. branch = repo.branch_from_xml(id, childnode, repositories, default_repo)
  209. version = childnode.getAttribute('version')
  210. if childnode.hasAttribute('config'):
  211. path = os.path.join(kconfig.srcdir, childnode.getAttribute('config'))
  212. else:
  213. path = kconfig.srcdir
  214. kconfig = LinuxConfig(version, path, branch)
  215. kconfigs.append(kconfig)
  216. if not kconfigs:
  217. kconfig = LinuxConfig('default', None, None)
  218. kconfigs.append(kconfig)
  219. return kconfigs
  220. def parse_linux(node, config, uri, repositories, default_repo):
  221. id = node.getAttribute('id')
  222. makeargs = ''
  223. if node.hasAttribute('makeargs'):
  224. makeargs = node.getAttribute('makeargs')
  225. # Make some substitutions; do special handling of '${prefix}' and '${libdir}'
  226. p = re.compile('(\${prefix})')
  227. makeargs = p.sub(config.prefix, makeargs)
  228. dependencies, after, suggests = get_dependencies(node)
  229. branch = get_branch(node, repositories, default_repo, config)
  230. kconfigs = get_kconfigs(node, repositories, default_repo)
  231. return LinuxModule(id, branch, kconfigs,
  232. makeargs, dependencies, after, suggests)
  233. register_module_type('linux', parse_linux)