build-linux 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #!/usr/bin/env python3
  2. import os
  3. import shutil
  4. import common
  5. class LinuxComponent(common.Component):
  6. def add_parser_arguments(self, parser):
  7. parser.add_argument(
  8. '--config', default=[], action='append',
  9. help='''\
  10. Add a single kernel config configs to the current build. Sample value:
  11. 'CONFIG_FORTIFY_SOURCE=y'. Can be used multiple times to add multiple
  12. configs. Takes precedence over any config files.
  13. '''
  14. )
  15. parser.add_argument(
  16. '--config-fragment', default=[], action='append',
  17. help='''\
  18. Also use the given kernel configuration fragment file.
  19. Pass multiple times to use multiple fragment files.
  20. '''
  21. )
  22. parser.add_argument(
  23. '--custom-config-file',
  24. help='''\
  25. Ignore all default kernel configurations and use this file instead.
  26. Still uses options explicitly passed with `--config` and
  27. `--config-fragment` on top of it.
  28. '''
  29. )
  30. parser.add_argument(
  31. '--config-only', default=False, action='store_true',
  32. help='''\
  33. Configure the kernel, but don't build it.
  34. '''
  35. )
  36. parser.add_argument(
  37. '--initramfs', default=False, action='store_true',
  38. )
  39. parser.add_argument(
  40. '--initrd', default=False, action='store_true',
  41. )
  42. parser.add_argument(
  43. 'extra_make_args',
  44. default=[],
  45. metavar='extra-make-args',
  46. nargs='*'
  47. )
  48. def do_build(self, args):
  49. build_dir = self.get_build_dir(args)
  50. if args.initrd or args.initramfs:
  51. raise Exception('just trolling, --initrd and --initramfs are broken for now')
  52. os.makedirs(build_dir, exist_ok=True)
  53. tool = 'gcc'
  54. gcc = common.get_toolchain_tool(tool)
  55. prefix = gcc[:-len(tool)]
  56. common_args = {
  57. 'cwd': common.linux_src_dir,
  58. }
  59. ccache = shutil.which('ccache')
  60. if ccache is not None:
  61. cc = '{} {}'.format(ccache, gcc)
  62. else:
  63. cc = gcc
  64. common_make_args = [
  65. 'make',
  66. '-j', str(args.nproc),
  67. 'ARCH={}'.format(common.linux_arch),
  68. 'CROSS_COMPILE={}'.format(prefix),
  69. 'CC={}'.format(cc),
  70. 'O={}'.format(build_dir),
  71. ]
  72. if args.verbose:
  73. verbose = ['V=1']
  74. else:
  75. verbose = []
  76. if args.custom_config_file is not None:
  77. if not os.path.exists(args.custom_config_file):
  78. raise Exception('config fragment file does not exist: {}'.format(args.custom_config_file))
  79. base_config_file = args.custom_config_file
  80. config_fragments = []
  81. else:
  82. base_config_file = os.path.join(common.linux_config_dir, 'buildroot-{}'.format(args.arch))
  83. config_fragments = ['min', 'default']
  84. for i, config_fragment in enumerate(config_fragments):
  85. config_fragments[i] = os.path.join(common.linux_config_dir, config_fragment)
  86. config_fragments.extend(args.config_fragment)
  87. if args.config != []:
  88. cli_config_fragment_path = os.path.join(build_dir, 'lkmc_cli_config_fragment')
  89. cli_config_str = '\n'.join(args.config)
  90. common.write_string_to_file(cli_config_fragment_path, cli_config_str)
  91. config_fragments.append(cli_config_fragment_path)
  92. common.cp(
  93. base_config_file,
  94. os.path.join(build_dir, '.config'),
  95. )
  96. common.run_cmd(
  97. [
  98. os.path.join(common.linux_src_dir, 'scripts', 'kconfig', 'merge_config.sh'),
  99. '-m',
  100. '-O', build_dir,
  101. os.path.join(build_dir, '.config'),
  102. ] +
  103. config_fragments
  104. )
  105. common.run_cmd(
  106. (
  107. common_make_args +
  108. ['olddefconfig']
  109. ),
  110. **common_args
  111. )
  112. if not args.config_only:
  113. common.run_cmd(
  114. (
  115. common_make_args +
  116. args.extra_make_args
  117. ),
  118. **common_args
  119. )
  120. def get_argparse_args(self):
  121. return {
  122. 'description': '''\
  123. Build the Linux kernel.
  124. '''
  125. }
  126. def get_build_dir(self, args):
  127. return common.linux_build_dir
  128. if __name__ == '__main__':
  129. LinuxComponent().build()