You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.1KB

  1. import argparse
  2. from pathlib import Path
  3. import subprocess
  4. import os
  5. from typing import Sequence
  6. import sys
  7. import shutil
  8. BOOTSTRAP_PHASES = [
  9. 'bootstrap-p1',
  10. ]
  11. HERE = Path(__file__).parent.absolute()
  12. PROJECT_ROOT = HERE.parent
  13. BUILD_DIR = PROJECT_ROOT / '_build'
  14. BOOTSTRAP_DIR = BUILD_DIR / '_bootstrap'
  15. PREBUILT_DIR = PROJECT_ROOT / '_prebuilt'
  16. def _run_quiet(args) -> None:
  17. cmd = [str(s) for s in args]
  18. res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  19. if res.returncode != 0:
  20. print(f'Subprocess command {cmd} failed '
  21. f'[{res.returncode}]:\n{res.stdout.decode()}')
  22. raise subprocess.CalledProcessError(res.returncode, cmd)
  23. def _clone_bootstrap_phase(ph: str) -> None:
  24. print(f'Cloning: {ph}')
  25. if BOOTSTRAP_DIR.exists():
  26. shutil.rmtree(BOOTSTRAP_DIR)
  27. _run_quiet([
  28. 'git',
  29. 'clone',
  30. '--depth=1',
  31. f'--branch={ph}',
  32. f'file://{PROJECT_ROOT}',
  33. BOOTSTRAP_DIR,
  34. ])
  35. def _build_bootstrap_phase(ph: str, args: argparse.Namespace) -> None:
  36. print(f'Running build: {ph} (Please wait a moment...)')
  37. env = os.environ.copy()
  38. env['DDS_BOOTSTRAP_PREV_EXE'] = PREBUILT_DIR / 'dds'
  39. subprocess.check_call(
  40. [
  41. sys.executable,
  42. str(BOOTSTRAP_DIR / 'tools/build.py'),
  43. f'--cxx={args.cxx}',
  44. ],
  45. env=env,
  46. )
  47. def _pull_executable() -> None:
  48. prebuild_dir = (PROJECT_ROOT / '_prebuilt')
  49. prebuild_dir.mkdir(exist_ok=True)
  50. exe, = list(BOOTSTRAP_DIR.glob('_build/dds*'))
  51. exe.rename(prebuild_dir / exe.name)
  52. def _run_boot_phase(phase: str, args: argparse.Namespace) -> None:
  53. _clone_bootstrap_phase(phase)
  54. _build_bootstrap_phase(phase, args)
  55. _pull_executable()
  56. def main(argv: Sequence[str]) -> int:
  57. parser = argparse.ArgumentParser()
  58. parser.add_argument(
  59. '--cxx', help='The C++ compiler to use for the build', required=True)
  60. args = parser.parse_args(argv)
  61. for phase in BOOTSTRAP_PHASES:
  62. _run_boot_phase(phase, args)
  63. return 0
  64. if __name__ == "__main__":
  65. sys.exit(main(sys.argv[1:]))