build-userland 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/env python3
  2. import os
  3. import platform
  4. import shlex
  5. import shutil
  6. import subprocess
  7. import common
  8. class UserlandComponent(self.Component):
  9. def add_parser_arguments(self, parser):
  10. parser.add_argument(
  11. '--has-package',
  12. action='append',
  13. default=[],
  14. help='''\
  15. Indicate that a given package is present in the root filesystem, which
  16. allows us to build examples that rely on it.
  17. ''',
  18. )
  19. parser.add_argument(
  20. '--host',
  21. default=False,
  22. help='''\
  23. Build the userland programs for the host instead of guest.
  24. Use the host packaged cross toolchain.
  25. ''',
  26. )
  27. parser.add_argument(
  28. '--make-args',
  29. default='',
  30. )
  31. parser.add_argument(
  32. 'targets',
  33. default=[],
  34. help='''\
  35. Build only the given userland programs.
  36. Default: build all examples that have their package dependencies met.
  37. For example, an OpenBLAS example can only be built if the target root filesystem
  38. has the OpenBLAS libraries and headers installed.
  39. ''',
  40. nargs='*',
  41. )
  42. def do_build(self, args):
  43. build_dir = self.get_build_dir(args)
  44. os.makedirs(build_dir, exist_ok=True)
  45. if kwargs['host']:
  46. allowed_toolchains = ['host']
  47. else:
  48. allowed_toolchains = ['buildroot']
  49. cc = self.get_toolchain_tool('gcc', allowed_toolchains=allowed_toolchains)
  50. cxx = self.get_toolchain_tool('g++', allowed_toolchains=allowed_toolchains)
  51. self.sh.run_cmd(
  52. (
  53. [
  54. 'make', LF,
  55. '-j', str(kwargs['nproc']), LF,
  56. 'ARCH={}'.format(kwargs['arch']), LF,
  57. 'CCFLAGS_SCRIPT={} {}'.format('-I', kwargs['userland_src_dir']), LF,
  58. 'COMMON_DIR={}'.format(kwargs['root_dir']), LF,
  59. 'CC={}'.format(cc), LF,
  60. 'CXX={}'.format(cxx), LF,
  61. 'PKG_CONFIG={}'.format(kwargs['buildroot_pkg_config']), LF,
  62. 'STAGING_DIR={}'.format(kwargs['buildroot_staging_dir']), LF,
  63. 'OUT_DIR={}'.format(build_dir), LF,
  64. ] +
  65. self.sh.add_newlines(['HAS_{}=y'.format(package.upper()) for package in kwargs['has_package']]) +
  66. shlex.split(kwargs['make_args']) +
  67. self.sh.add_newlines([os.path.join(build_dir, os.path.splitext(os.path.split(target)[1])[0]) + kwargs['userland_build_ext'] for target in kwargs['targets']])
  68. ),
  69. cwd=kwargs['userland_src_dir'],
  70. extra_paths=[kwargs['ccache_dir']],
  71. )
  72. self.copy_dir_if_update_non_recursive(
  73. srcdir=build_dir,
  74. destdir=kwargs['out_rootfs_overlay_dir'],
  75. filter_ext=kwargs['userland_build_ext'],
  76. )
  77. def get_argparse_args(self):
  78. return {
  79. 'description': 'Build our compiled userland examples',
  80. }
  81. def get_build_dir(self, args):
  82. return kwargs['userland_build_dir']
  83. if __name__ == '__main__':
  84. UserlandComponent().build()