| # 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) |