瀏覽代碼

New CI script can download a prebuilt phase-2 bootstrapped executable

default_compile_flags
vector-of-bool 5 年之前
父節點
當前提交
ea3c3dc69c
共有 3 個檔案被更改,包括 58 行新增22 行删除
  1. +3
    -3
      azure-pipelines.yml
  2. +11
    -8
      tools/bootstrap.py
  3. +44
    -11
      tools/ci.py

+ 3
- 3
azure-pipelines.yml 查看文件

echo Loading VS environment echo Loading VS environment
call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1
echo Executing Build and Tests echo Executing Build and Tests
python -u tools/ci.py --cxx cl.exe -T tools\\msvc.dds || exit 1
python -u tools/ci.py -B download --cxx cl.exe -T tools\\msvc.dds || exit 1
displayName: Full CI displayName: Full CI
- publish: _build/dds.exe - publish: _build/dds.exe
artifact: DDS Executable - Windows VS2019 artifact: DDS Executable - Windows VS2019
steps: steps:
- script: sudo apt update -y && sudo apt install -y python3-minimal g++-8 - script: sudo apt update -y && sudo apt install -y python3-minimal g++-8
displayName: Prepare System displayName: Prepare System
- script: python3 -u tools/ci.py --cxx g++-8 -T tools/gcc-8.dds
- script: python3 -u tools/ci.py -B download --cxx g++-8 -T tools/gcc-8.dds
displayName: Full CI displayName: Full CI
- publish: _build/dds - publish: _build/dds
artifact: DDS Executable - Linux artifact: DDS Executable - Linux
steps: steps:
- script: brew install gcc@8 - script: brew install gcc@8
displayName: Prepare System displayName: Prepare System
- script: python3 -u tools/ci.py --cxx g++-8 -T tools/gcc-8.dds
- script: python3 -u tools/ci.py -B download --cxx g++-8 -T tools/gcc-8.dds
displayName: Build and Run Unit Tests displayName: Build and Run Unit Tests
- publish: _build/dds - publish: _build/dds
artifact: DDS Executable - macOS artifact: DDS Executable - macOS

+ 11
- 8
tools/bootstrap.py 查看文件

EXE_SUFFIX = '.exe' if os.name == 'nt' else '' EXE_SUFFIX = '.exe' if os.name == 'nt' else ''




def _run_quiet(args) -> None:
cmd = [str(s) for s in args]
res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def _run_quiet(cmd, **kwargs) -> None:
cmd = [str(s) for s in cmd]
res = subprocess.run(
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
if res.returncode != 0: if res.returncode != 0:
print(f'Subprocess command {cmd} failed ' print(f'Subprocess command {cmd} failed '
f'[{res.returncode}]:\n{res.stdout.decode()}') f'[{res.returncode}]:\n{res.stdout.decode()}')




def _clone_bootstrap_phase(ph: str) -> Path: def _clone_bootstrap_phase(ph: str) -> Path:
print(f'Cloning: {ph}')
print(f'Clone revision: {ph}')
bts_dir = BOOTSTRAP_BASE_DIR / ph bts_dir = BOOTSTRAP_BASE_DIR / ph
if bts_dir.exists(): if bts_dir.exists():
shutil.rmtree(bts_dir) shutil.rmtree(bts_dir)
return bts_dir return bts_dir




def _build_bootstrap_phase(ph: str, bts_dir: Path, args: argparse.Namespace) -> None:
print(f'Running build: {ph} (Please wait a moment...)')
def _build_bootstrap_phase(ph: str, bts_dir: Path,
args: argparse.Namespace) -> None:
print(f'Build revision: {ph} [This may take a moment]')
env = os.environ.copy() env = os.environ.copy()
env['DDS_BOOTSTRAP_PREV_EXE'] = str(PREBUILT_DIR / 'dds') env['DDS_BOOTSTRAP_PREV_EXE'] = str(PREBUILT_DIR / 'dds')
subprocess.check_call(
_run_quiet(
[ [
sys.executable, sys.executable,
'-u', '-u',
parser.add_argument( parser.add_argument(
'--cxx', help='The C++ compiler to use for the build', required=True) '--cxx', help='The C++ compiler to use for the build', required=True)
args = parser.parse_args(argv) args = parser.parse_args(argv)
for phase in BOOTSTRAP_PHASES:
for idx, phase in enumerate(BOOTSTRAP_PHASES):
print(f'Bootstrap phase [{idx+1}/{len(BOOTSTRAP_PHASES)}]')
exe = _run_boot_phase(phase, args) exe = _run_boot_phase(phase, args)


print(f'A bootstrapped DDS executable has been generated: {exe}') print(f'A bootstrapped DDS executable has been generated: {exe}')

+ 44
- 11
tools/ci.py 查看文件

import argparse import argparse
import os
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Sequence, NamedTuple from typing import Sequence, NamedTuple
import subprocess import subprocess
import urllib.request


HERE = Path(__file__).parent.absolute() HERE = Path(__file__).parent.absolute()
TOOLS_DIR = HERE TOOLS_DIR = HERE




class CIOptions(NamedTuple): class CIOptions(NamedTuple):
skip_bootstrap: bool
cxx: Path cxx: Path
toolchain: str toolchain: str




def _do_bootstrap(opts: CIOptions) -> None:
print('Running bootstrap')
def _do_bootstrap_build(opts: CIOptions) -> None:
print('Bootstrapping by a local build of prior versions...')
subprocess.check_call([ subprocess.check_call([
sys.executable, sys.executable,
'-u', '-u',
]) ])




def _do_bootstrap_download() -> None:
filename = {
'win32': 'dds-win-x64.exe',
'linux': 'dds-linux-x64',
'darwin': 'dds-macos-x64',
}.get(sys.platform)
if filename is None:
raise RuntimeError(f'We do not have a prebuilt DDS binary for the "{sys.platform}" platform')
url = f'https://github.com/vector-of-bool/dds/releases/download/bootstrap-p2/{filename}'

print(f'Downloading prebuilt DDS executable: {url}')
stream = urllib.request.urlopen(url)
PREBUILT_DDS.parent.mkdir(exist_ok=True, parents=True)
with PREBUILT_DDS.open('wb') as fd:
while True:
buf = stream.read(1024 * 4)
if not buf:
break
fd.write(buf)

if os.name != 'nt':
# Mark the binary executable. By default it won't be
mode = PREBUILT_DDS.stat().st_mode
mode |= 0b001_001_001
PREBUILT_DDS.chmod(mode)


def main(argv: Sequence[str]) -> int: def main(argv: Sequence[str]) -> int:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
'--skip-bootstrap',
action='store_true',
'-B',
'--bootstrap-with',
help= help=
'Skip the prebuild-bootstrap step. This requires a _prebuilt/dds to exist!', 'Skip the prebuild-bootstrap step. This requires a _prebuilt/dds to exist!',
choices=('download', 'build'),
required=True,
) )
parser.add_argument( parser.add_argument(
'--cxx', '--cxx',
help='The toolchain to use for the CI process', help='The toolchain to use for the CI process',
required=True) required=True)
args = parser.parse_args(argv) args = parser.parse_args(argv)
opts = CIOptions(
skip_bootstrap=args.skip_bootstrap,
cxx=Path(args.cxx),
toolchain=args.toolchain)
if not opts.skip_bootstrap:
_do_bootstrap(opts)

opts = CIOptions(cxx=Path(args.cxx), toolchain=args.toolchain)

if args.bootstrap_with == 'build':
_do_bootstrap_build(opts)
elif args.bootstrap_with == 'download':
_do_bootstrap_download()
else:
assert False, 'impossible'


subprocess.check_call([ subprocess.check_call([
str(PREBUILT_DDS), str(PREBUILT_DDS),

Loading…
取消
儲存