blob: c5d9570de718f83fa3aa6176db4457dcd1f7e56d [file] [log] [blame]
# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import re
from contextlib import contextmanager
from recipe_engine import recipe_api
class BuildApi(recipe_api.RecipeApi):
"""Recipe module for building the Dart SDK with and without goma."""
def __init__(self, properties, *args, **kwargs):
super(BuildApi, self).__init__(*args, **kwargs)
self._timeout = properties.timeout or 50 * 60 # 50 minutes
self._goma_enabled = not properties.disable_goma
# No need to download goma if it's disabled.
self._goma_ensured = properties.disable_goma
def build(self, name='build dart', args=None):
"""Builds dart using the specified args"""
if not args: # pragma: no cover
args = []
with self.m.depot_tools.on_path(), self.m.context(
cwd=self.m.path['checkout']):
if self._goma_enabled:
self._build_with_goma(name, args)
else:
if '--no-goma' not in args:
args = args + ['--no-goma']
self._run_build_py(name, args)
def gn(self, name='gn', args=None):
"""Runs gn.py using the specified args"""
with self.m.context(env=self._build_env):
if not self._goma_enabled and '--no-goma' not in args:
args = args + ['--no-goma']
gn_py = self.m.path['checkout'].join('tools', 'gn.py')
self.m.step(name, ['python3', '-u', gn_py] + args)
@contextmanager
def goma(self):
self._ensure_goma()
with self.m.context(env=self._build_env):
try:
self._goma('restart')
try:
yield
finally:
self._goma('stat')
finally:
self._goma('stop')
@property
def _build_env(self):
if not self._goma_enabled:
return {}
self._ensure_goma()
return {
'GOMA_DIR': self._goma_dir,
}
@property
def _goma_env(self):
env = {
'GOMA_DIR':
self._goma_dir,
'GOMA_CACHE_DIR':
self._goma_cache,
'GOMACTL_CRASH_REPORT_ID_FILE':
self.m.path['cleanup'].join('crash_report_id'),
'GOMA_DUMP_STATS_FILE':
self.m.path['cleanup'].join('goma_stats'),
'GOMA_HERMETIC':
'error',
'GOMA_SERVER_HOST':
'goma.chromium.org',
}
if self.m.platform.is_linux:
env['GOMA_ARBITRARY_TOOLCHAIN_SUPPORT'] = 'true'
return env
def _run_build_py(self, name, args):
with self.m.context(infra_steps=False):
build_py = self.m.path['checkout'].join('tools', 'build.py')
self.m.step(
name, ['python3', '-u', build_py] + args, timeout=self._timeout)
def _build_with_goma(self, name, args):
with self.goma():
args = args + ['--no-start-goma', '-j200']
self._run_build_py(name, args)
def _ensure_goma(self):
if not self._goma_ensured:
self._goma_root = self.m.path['cache'].join('goma')
self._goma_dir = self._goma_root.join('client')
self._goma_ctl = self._goma_dir.join('goma_ctl.py')
safe_buildername = re.sub(r'[^a-zA-Z0-9]', '_',
self.m.buildbucket.builder_name)
self._goma_cache = self._goma_root.join('data', safe_buildername)
self.m.file.ensure_directory('goma cache directory', self._goma_cache)
goma_package = r'infra_internal/goma/client/${platform}'
ensure_file = self.m.cipd.EnsureFile().add_package(
goma_package, 'release')
self.m.cipd.ensure(self._goma_dir, ensure_file)
self._goma_ensured = True
def _goma(self, cmd):
with self.m.context(env=self._goma_env):
self.m.step(
name='goma %s' % cmd,
cmd=['python3', self._goma_ctl, cmd],
infra_step=True)