blob: 11482939c3612fc5d72da49678c622aa2669df13 [file] [log] [blame]
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for building Dart toolchain."""
from recipe_engine.config import Enum
from recipe_engine.recipe_api import Property
DEPS = [
'fuchsia/macos_sdk',
'fuchsia/git',
'fuchsia/goma',
'fuchsia/upload',
'recipe_engine/buildbucket',
'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/file',
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/raw_io',
'recipe_engine/step',
]
DEPOT_TOOLS_GIT = 'https://chromium.googlesource.com/chromium/tools/depot_tools'
DART_SDK_GIT = 'https://dart.googlesource.com/sdk.git'
PROPERTIES = {
'repository':
Property(kind=str, help='Git repository URL', default=DART_SDK_GIT),
'revision':
Property(kind=str, help='Revision', default=None),
'host_cpu':
Property(
kind=Enum('arm64', 'x64'),
help='GN $host_cpu toolchain will run on',
default=None),
'host_os':
Property(
kind=Enum('linux', 'mac'),
help='GN $host_os toolchain will run on',
default=None),
}
# Fuchsia targets the toolchain must support.
FUCHSIA_TARGETS = [
'arm64',
'x64',
]
GN_CIPD_CPU_MAP = {
'x64': 'amd64',
}
def RunSteps(api, repository, revision, host_cpu, host_os):
api.goma.ensure()
gitiles_commit = api.buildbucket.build_input.gitiles_commit
if gitiles_commit.host and gitiles_commit.project and gitiles_commit.id:
repository = 'https://%s/%s' % (gitiles_commit.host, gitiles_commit.project)
revision = gitiles_commit.id
if not host_cpu:
# TODO(mcgrathr): Native bots are all x64 and api.platform.arch is useless.
host_cpu = 'x64'
if not host_os:
host_os = api.platform.name
cipd_platform = '%s-%s' % (host_os, GN_CIPD_CPU_MAP.get(host_cpu, host_cpu))
with api.step.nest('ensure_packages'):
with api.context(infra_steps=True):
pkgs = api.cipd.EnsureFile()
pkgs.add_package('infra/ninja/${platform}', 'version:1.8.2')
if host_os == 'linux':
pkgs.add_package('fuchsia/sysroot/%s' % cipd_platform, 'latest')
cipd_dir = api.path['start_dir'].join('cipd')
api.cipd.ensure(cipd_dir, pkgs)
ninja = [cipd_dir.join('ninja'), '-j%d' % api.goma.jobs]
with api.context(infra_steps=True):
with api.step.nest('depot_tools'):
# TODO(phosek): Move this to a named cache so it's shared across builds.
depot_tools_dir = api.path['start_dir'].join('depot_tools')
api.git.checkout(DEPOT_TOOLS_GIT, depot_tools_dir, submodules=False)
with api.step.nest('dart-sdk'):
sdk_dir = api.path['start_dir'].join('dart', 'sdk')
revision = api.git.checkout(
repository, sdk_dir, ref=revision, submodules=False)
# Use gclient to fetch the DEPS, but don't let it change dart/sdk itself.
dart_dir = api.path['start_dir'].join('dart')
with api.context(
infra_steps=True, cwd=dart_dir, env_prefixes={'PATH': [depot_tools_dir]}):
api.step(
'gclient config',
[
'gclient',
'config',
'--unmanaged',
# TODO(mcgrathr): Set --cache-dir?
'-v',
DART_SDK_GIT,
])
api.step('gclient sync', [
'gclient',
'sync',
'--no-history',
'-v',
'--output-json',
api.json.output(),
])
dart_targets = sorted(
set([host_cpu] +
['sim' + cpu if cpu != host_cpu else cpu for cpu in FUCHSIA_TARGETS]))
def out_dir(cpu):
return sdk_dir.join('xcodebuild' if api.platform.is_mac else 'out',
'Release' + cpu.upper())
with api.macos_sdk(), api.goma.build_with_goma(), api.context(cwd=sdk_dir):
# TODO(mcgrathr): Move this logic into a host_build recipe module shared
# with gcc_toolchain.py and others.
if host_os == 'linux':
host_sysroot = cipd_dir
elif host_os == 'mac':
with api.context(infra_steps=True):
step_result = api.step(
'xcrun', ['xcrun', '--show-sdk-path'],
stdout=api.raw_io.output(name='sdk-path', add_output_log=True),
step_test_data=lambda: api.raw_io.test_api.stream_output(
'/some/xcode/path'))
host_sysroot = step_result.stdout.strip()
else: # pragma: no cover
assert False, 'what platform?'
gn_common = [
'tools/gn.py',
'-v',
'--mode=release',
'--goma',
# It actually wants a sysroot for the build host regardless of what
# Dart target CPU the build is configured for, but wants it in the
# form `%(target_cpu)s=%(host_sysroot)s`.
'--target-sysroot=' +
','.join('%s=%s' % (cpu, host_sysroot) for cpu in dart_targets),
]
api.step('gn host (%s)' % host_cpu,
gn_common + ['--arch=%s' % host_cpu, '--platform-sdk'])
for cpu in dart_targets:
if cpu != host_cpu:
api.step('gn %s' % cpu, gn_common + ['--arch=%s' % cpu])
api.step(
'build host (%s) SDK' % host_cpu, ninja + [
'-C',
out_dir(host_cpu),
'create_sdk',
'gen_snapshot',
'gen_snapshot_product',
])
for cpu in dart_targets:
api.step(
'build %s' % cpu, ninja + [
'-C',
out_dir(cpu),
'gen_snapshot_fuchsia',
'gen_snapshot_product_fuchsia',
'runtime',
])
for cpu in dart_targets:
remote_config = 'dartk-linux-release-%s' % cpu
local_config = 'dartk-%s-release-%s' % (host_os, cpu)
api.step('run tests', [
'tools/sdks/dart-sdk/bin/dart',
'tools/test.dart',
'-n',
remote_config,
'-N',
local_config,
'--',
'--progress=line',
'--report',
'--time',
'vm',
'language',
])
with api.step.nest('install'):
pkg_dir = api.path['cleanup'].join('dart-sdk')
api.file.copytree(
'install dart-sdk',
out_dir(host_cpu).join('dart-sdk'),
pkg_dir,
symlinks=True)
for cpu, is_host in [(host_cpu, True)
] + [(cpu, False) for cpu in dart_targets]:
exe_dir = out_dir(cpu).join('exe.stripped')
if not is_host and cpu.startswith('sim'):
cpu = cpu[3:]
for tool in ['gen_snapshot', 'gen_snapshot_product']:
src = exe_dir.join(tool + ('' if is_host else '_fuchsia'))
dst_name = '%s.%s-%s' % (tool, host_os if is_host else 'fuchsia', cpu)
dst = pkg_dir.join('bin', dst_name)
api.file.copy('install %s' % dst_name, src, dst)
dart_sdk_version = api.file.read_text(
'read dart-sdk version',
pkg_dir.join('version'),
test_data='2.0.0-edge.' + revision + '\n',
).strip()
api.upload.cipd_package(
'fuchsia/dart-sdk/' + cipd_platform,
pkg_dir, [api.upload.DirectoryPath(pkg_dir)], {'git_revision': revision},
repository,
extra_tags={'dart_sdk_version': dart_sdk_version})
def GenTests(api):
revision = '301b5a1f16414bc031091eb214ddd6c589e6ed9a'
for platform in ('linux', 'mac'):
yield (api.test(platform) + api.platform.name(platform) + api.step_data(
'dart-sdk.git rev-parse', api.raw_io.stream_output(revision)) +
api.buildbucket.ci_build(git_repo=DART_SDK_GIT, revision=revision))
yield (api.test(platform + '_new') + api.platform.name(platform) +
api.buildbucket.ci_build(git_repo=DART_SDK_GIT, revision=revision) +
api.step_data('dart-sdk.git rev-parse',
api.raw_io.stream_output(revision)) +
api.step_data(
'cipd.cipd search fuchsia/dart-sdk/' + platform + '-amd64 ' +
'git_revision:' + revision, api.json.output({'result': []})) +
api.step_data('gclient sync', api.json.output({'solutions': {}})))
for host_os, host_cpu, cipd_host_cpu in [('linux', 'arm64', 'arm64')]:
cipd_platform = host_os + '-' + cipd_host_cpu
yield (api.test(host_os + '_cross') + api.platform.name(host_os) +
api.properties(host_cpu=host_cpu, host_os=host_os) +
api.buildbucket.ci_build(git_repo=DART_SDK_GIT, revision=revision) +
api.step_data('dart-sdk.git rev-parse',
api.raw_io.stream_output(revision)) +
api.step_data(
'cipd.cipd search fuchsia/dart-sdk/' + cipd_platform + ' ' +
'git_revision:' + revision, api.json.output({'result': []})) +
api.step_data('gclient sync', api.json.output({'solutions': {}})))