選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

116 行
3.0KB

  1. import argparse
  2. import os
  3. import sys
  4. from pathlib import Path
  5. from typing import Sequence, NamedTuple
  6. import subprocess
  7. import urllib.request
  8. HERE = Path(__file__).parent.absolute()
  9. TOOLS_DIR = HERE
  10. PROJECT_ROOT = HERE.parent
  11. PREBUILT_DDS = PROJECT_ROOT / '_prebuilt/dds'
  12. class CIOptions(NamedTuple):
  13. cxx: Path
  14. toolchain: str
  15. def _do_bootstrap_build(opts: CIOptions) -> None:
  16. print('Bootstrapping by a local build of prior versions...')
  17. subprocess.check_call([
  18. sys.executable,
  19. '-u',
  20. str(TOOLS_DIR / 'bootstrap.py'),
  21. f'--cxx={opts.cxx}',
  22. ])
  23. def _do_bootstrap_download() -> None:
  24. filename = {
  25. 'win32': 'dds-win-x64.exe',
  26. 'linux': 'dds-linux-x64',
  27. 'darwin': 'dds-macos-x64',
  28. }.get(sys.platform)
  29. if filename is None:
  30. raise RuntimeError(f'We do not have a prebuilt DDS binary for the "{sys.platform}" platform')
  31. url = f'https://github.com/vector-of-bool/dds/releases/download/bootstrap-p2/{filename}'
  32. print(f'Downloading prebuilt DDS executable: {url}')
  33. stream = urllib.request.urlopen(url)
  34. PREBUILT_DDS.parent.mkdir(exist_ok=True, parents=True)
  35. with PREBUILT_DDS.open('wb') as fd:
  36. while True:
  37. buf = stream.read(1024 * 4)
  38. if not buf:
  39. break
  40. fd.write(buf)
  41. if os.name != 'nt':
  42. # Mark the binary executable. By default it won't be
  43. mode = PREBUILT_DDS.stat().st_mode
  44. mode |= 0b001_001_001
  45. PREBUILT_DDS.chmod(mode)
  46. def main(argv: Sequence[str]) -> int:
  47. parser = argparse.ArgumentParser()
  48. parser.add_argument(
  49. '-B',
  50. '--bootstrap-with',
  51. help=
  52. 'Skip the prebuild-bootstrap step. This requires a _prebuilt/dds to exist!',
  53. choices=('download', 'build'),
  54. required=True,
  55. )
  56. parser.add_argument(
  57. '--cxx',
  58. help='The name/path of the C++ compiler to use.',
  59. required=True)
  60. parser.add_argument(
  61. '--toolchain',
  62. '-T',
  63. help='The toolchain to use for the CI process',
  64. required=True)
  65. args = parser.parse_args(argv)
  66. opts = CIOptions(cxx=Path(args.cxx), toolchain=args.toolchain)
  67. if args.bootstrap_with == 'build':
  68. _do_bootstrap_build(opts)
  69. elif args.bootstrap_with == 'download':
  70. _do_bootstrap_download()
  71. else:
  72. assert False, 'impossible'
  73. subprocess.check_call([
  74. str(PREBUILT_DDS),
  75. 'deps',
  76. 'build',
  77. f'-T{opts.toolchain}',
  78. f'--repo-dir={PROJECT_ROOT / "external/repo"}',
  79. ])
  80. subprocess.check_call([
  81. str(PREBUILT_DDS),
  82. 'build',
  83. '--full',
  84. f'-T{opts.toolchain}',
  85. ])
  86. exe_suffix = '.exe' if os.name == 'nt' else ''
  87. subprocess.check_call([
  88. sys.executable,
  89. '-u',
  90. str(TOOLS_DIR / 'test.py'),
  91. f'--exe={PROJECT_ROOT / f"_build/dds{exe_suffix}"}',
  92. f'-T{opts.toolchain}',
  93. ])
  94. return 0
  95. if __name__ == "__main__":
  96. sys.exit(main(sys.argv[1:]))