build-userland 3.4 KB

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