# Copyright 2017 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 Clang toolchain."""

from contextlib import contextmanager
from recipe_engine.recipe_api import Property
from PB.go.chromium.org.luci.common.proto.srcman.manifest import Manifest

from google.protobuf import json_format

import re

DEPS = [
    'fuchsia/git',
    'fuchsia/gitiles',
    'fuchsia/goma',
    'fuchsia/gsutil',
    'fuchsia/macos_sdk',
    'fuchsia/upload',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/isolated',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/runtime',
    'recipe_engine/raw_io',
    'recipe_engine/scheduler',
    'recipe_engine/source_manifest',
    'recipe_engine/step',
]

TARGET_TO_ARCH = {
    'x64': 'x86_64',
    'arm64': 'aarch64',
}
TARGETS = TARGET_TO_ARCH.keys()

PLATFORM_TO_TRIPLE = {
    'linux-amd64': 'x86_64-linux-gnu',
    'linux-arm64': 'aarch64-linux-gnu',
    'mac-amd64': 'x86_64-apple-darwin',
}
PLATFORMS = PLATFORM_TO_TRIPLE.keys()

# TODO(TC-476): remove this and switch to normalized triples.
TRIPLE_TO_NORMALIZED_TRIPLE = {
    'x86_64-linux-gnu': 'x86_64-unknown-linux-gnu',
    'aarch64-linux-gnu': 'aarch64-unknown-linux-gnu',
    'x86_64-apple-darwin': 'x86_64-apple-darwin',
}

LIBXML2_GIT = 'https://fuchsia.googlesource.com/third_party/libxml2'
ZLIB_GIT = 'https://fuchsia.googlesource.com/third_party/zlib'

CIPD_SERVER_HOST = 'chrome-infra-packages.appspot.com'

PROPERTIES = {
    'repository':
        Property(
            kind=str,
            help='Git repository URL',
            default='https://fuchsia.googlesource.com/third_party/llvm-project'
        ),
    'revision':
        Property(kind=str, help='Git revision', default=None),
    'platform':
        Property(kind=str, help='CIPD platform for the target', default=None),
}


def build_zlib(api, destdir, jobs, manifest, env=None):
  zlib_dir = api.path['start_dir'].join('zlib')
  src_dir = zlib_dir.join('src')
  revision = api.git.checkout(ZLIB_GIT, src_dir, ref='refs/tags/v1.2.9')
  git_checkout = manifest.directories[str(src_dir)].git_checkout
  git_checkout.repo_url = ZLIB_GIT
  git_checkout.revision = revision
  git_checkout.fetch_ref = 'refs/tags/v1.2.9'
  obj_dir = zlib_dir.join('obj')
  api.file.ensure_directory('make objdir', obj_dir)
  with api.context(cwd=obj_dir, env=env):
    api.step('configure', [
        src_dir.join('configure'),
        '--prefix=',
        '--static',
    ])
    api.step('build', ['make', '-j%d' % jobs])
    api.step('install', ['make', 'install', 'DESTDIR=%s' % destdir])


def build_libxml2(api,
                  host,
                  target,
                  destdir,
                  zlib_dir,
                  jobs,
                  manifest,
                  env=None):
  libxml2_dir = api.path['start_dir'].join('libxml2')
  src_dir = libxml2_dir.join('src')
  revision = api.git.checkout(LIBXML2_GIT, src_dir, ref='refs/tags/v2.9.8')
  git_checkout = manifest.directories[str(src_dir)].git_checkout
  git_checkout.repo_url = LIBXML2_GIT
  git_checkout.revision = revision
  git_checkout.fetch_ref = 'refs/tags/v2.9.8'
  with api.context(cwd=src_dir):
    api.step('autoconf', ['autoreconf', '-i', '-f'])
  obj_dir = libxml2_dir.join('obj')
  api.file.ensure_directory('make objdir', obj_dir)
  with api.context(cwd=obj_dir):
    api.step('configure', [
        src_dir.join('configure'),
        '--prefix=',
        '--build=%s' % host,
        '--host=%s' % target,
        '--disable-shared',
        '--enable-static',
        # TODO(phosek): libxml2 is now being built with zlib support, but lld
        # is only linking the former, not the latter, and in case of static
        # linking, this fails
        '--with-zlib=%s' % destdir,
        '--without-icu',
        '--without-lzma',
        '--without-python',
    ] + ['%s=%s' % (k, v) for k, v in env.iteritems()])
    api.step('build', ['make', '-j%d' % jobs])
    api.step('install', ['make', 'install', 'DESTDIR=%s' % destdir])


def RunSteps(api, repository, revision, platform):
  use_goma = not api.platform.arch == 'arm' and api.platform.bits == 64
  if use_goma:
    api.goma.ensure()
    ninja_jobs = api.goma.jobs
    goma_context = lambda: api.goma.build_with_goma()
  else:
    ninja_jobs = api.platform.cpu_count

    @contextmanager
    def null_context():
      yield

    goma_context = null_context

  prod = api.buildbucket.builder_id.bucket == 'prod'
  ci = api.buildbucket.builder_id.bucket == 'ci'

  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

  # TODO: factor this out into a host_build recipe module.
  host_platform = '%s-%s' % (api.platform.name.replace('win', 'windows'), {
      'intel': {
          32: '386',
          64: 'amd64',
      },
      'arm': {
          32: 'armv6',
          64: 'arm64',
      },
  }[api.platform.arch][api.platform.bits])
  target_platform = platform or host_platform

  manifest = Manifest()

  with api.step.nest('ensure_packages'):
    with api.context(infra_steps=True):
      cipd_dir = api.path['start_dir'].join('cipd')
      pkgs = api.cipd.EnsureFile()
      if api.platform.arch == 'arm' and api.platform.bits == 64:
        pkgs.add_package(
            'fuchsia/third_party/clang/${platform}',
            'git_revision:ea93d7d6421612e9ea51b321eaf97fbdd64fe39b')
        pkgs.add_package('fuchsia/sdk/core/linux-amd64', 'latest', 'sdk')
      else:
        pkgs.add_package('fuchsia/third_party/clang/${platform}', 'goma')
        pkgs.add_package('fuchsia/sdk/core/${platform}', 'latest', 'sdk')
      pkgs.add_package('infra/3pp/tools/cmake/${platform}', 'version:3.13.5')
      pkgs.add_package('infra/3pp/tools/ninja/${platform}', 'version:1.9.0')
      pkgs.add_package('fuchsia/sysroot/linux-386', 'latest', 'linux-i386')
      pkgs.add_package('fuchsia/sysroot/linux-amd64', 'latest', 'linux-amd64')
      pkgs.add_package('fuchsia/sysroot/linux-arm64', 'latest', 'linux-arm64')
      pkgs.add_package('fuchsia/sysroot/linux-armv6l', 'latest', 'linux-armhf')
      ensured = api.cipd.ensure(cipd_dir, pkgs)
      for subdir, pins in ensured.iteritems():
        directory = manifest.directories[str(cipd_dir.join(subdir))]
        directory.cipd_server_host = CIPD_SERVER_HOST
        for pin in pins:
          directory.cipd_package[pin.package].instance_id = pin.instance_id

  staging_dir = api.path.mkdtemp('clang')
  pkg_name = 'clang-%s' % api.platform.name.replace('mac', 'darwin')
  pkg_dir = staging_dir.join(pkg_name)
  api.file.ensure_directory('create pkg dir', pkg_dir)

  with api.context(infra_steps=True):
    llvm_dir = api.path['start_dir'].join('llvm-project')
    revision = api.git.checkout(
        repository,
        path=llvm_dir,
        ref=revision,
        step_test_data=lambda: api.raw_io.test_api.stream_output(revision))
    git_checkout = manifest.directories[str(llvm_dir)].git_checkout
    git_checkout.repo_url = repository
    git_checkout.revision = revision

  target_triple = PLATFORM_TO_TRIPLE[target_platform]
  host_triple = PLATFORM_TO_TRIPLE[host_platform]

  with api.macos_sdk(), goma_context():
    if api.platform.name == 'linux':
      host_sysroot = cipd_dir.join(host_platform)
      target_sysroot = cipd_dir.join(target_platform)
    elif api.platform.name == 'mac':
      # TODO(IN-148): Eventually use our own hermetic sysroot as for Linux.
      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'))
      target_sysroot = host_sysroot = step_result.stdout.strip()
    else:  # pragma: no cover
      assert False, 'unsupported platform'

    env = {
        'CC': ('%s %s' % (api.goma.goma_dir.join('gomacc'),
                          cipd_dir.join('bin', 'clang')))
              if use_goma else cipd_dir.join('bin', 'clang'),
        'CFLAGS':
            '-O3 -fPIC --target=%s --sysroot=%s' % (target_triple,
                                                    target_sysroot),
        'AR':
            cipd_dir.join('bin', 'llvm-ar'),
        'NM':
            cipd_dir.join('bin', 'llvm-nm'),
        'RANLIB':
            cipd_dir.join('bin', 'llvm-ranlib'),
    }

    with api.step.nest('zlib'):
      zlib_install_dir = staging_dir.join('zlib_install')
      api.file.ensure_directory('create zlib_install_dir', zlib_install_dir)
      build_zlib(api, zlib_install_dir, ninja_jobs, manifest, env)
    with api.step.nest('libxml2'):
      libxml2_install_dir = staging_dir.join('libxml2_install')
      api.file.ensure_directory('create libxml2_install_dir',
                                libxml2_install_dir)
      build_libxml2(api, host_triple, target_triple, libxml2_install_dir,
                    zlib_install_dir, ninja_jobs, manifest, env)

    json_manifest = json_format.MessageToJson(
        manifest, preserving_proto_field_name=True)
    api.file.write_text('source manifest', pkg_dir.join('source_manifest.json'),
                        json_manifest)
    api.source_manifest.set_json_manifest('checkout', json_manifest)

    # build clang+llvm
    build_dir = staging_dir.join('llvm_build_dir')
    api.file.ensure_directory('create llvm build dir', build_dir)

    arguments = {
        'cc': cipd_dir.join('bin', 'clang'),
        'cxx': cipd_dir.join('bin', 'clang++'),
        'ar': cipd_dir.join('bin', 'llvm-ar'),
        'ld': cipd_dir.join('bin', 'ld.lld'),
        'nm': cipd_dir.join('bin', 'llvm-nm'),
        'objcopy': cipd_dir.join('bin', 'llvm-objcopy'),
        'objdump': cipd_dir.join('bin', 'llvm-objdump'),
        'ranlib': cipd_dir.join('bin', 'llvm-ranlib'),
        'strip': cipd_dir.join('bin', 'llvm-strip'),
        'ninja': cipd_dir.join('ninja'),
        'target_triple': TRIPLE_TO_NORMALIZED_TRIPLE[target_triple],
        'host_triple': host_triple,
        'target_sysroot': target_sysroot,
        'host_sysroot': host_sysroot,
        'linux_arm64_sysroot': cipd_dir.join('linux-arm64'),
        'linux_armhf_sysroot': cipd_dir.join('linux-armhf'),
        'linux_i386_sysroot': cipd_dir.join('linux-i386'),
        'linux_amd64_sysroot': cipd_dir.join('linux-amd64'),
        'fuchsia_sdk': cipd_dir.join('sdk'),
    }
    if use_goma:
      arguments.update({
          'gomacc': api.goma.goma_dir.join('gomacc'),
      })

    arguments.update({
        'BOOTSTRAP_': 'BOOTSTRAP_',
        'STAGE2_': 'STAGE2_',
        'stage2_': 'stage2-',
        '_stage2': '',
    } if prod else {
        'BOOTSTRAP_': '',
        'STAGE2_': '',
        'stage2_': '',
        '_stage2': '-stage2',
    })

    llvm_projects = ['clang', 'clang-tools-extra', 'lld']
    llvm_runtimes = ['compiler-rt', 'libcxx', 'libcxxabi', 'libunwind']

    options = [
        '-GNinja',
        '-DCMAKE_C_COMPILER={cc}',
        '-DCMAKE_CXX_COMPILER={cxx}',
        '-DCMAKE_ASM_COMPILER={cc}',
        '-DCMAKE_MAKE_PROGRAM={ninja}',
        '-DCMAKE_INSTALL_PREFIX=',
        '-DLLVM_ENABLE_PROJECTS=%s' % ';'.join(llvm_projects),
        '-DLLVM_ENABLE_RUNTIMES=%s' % ';'.join(llvm_runtimes),
    ]
    if use_goma:
      options.extend([
          '-DCMAKE_C_COMPILER_LAUNCHER={gomacc}',
          '-DCMAKE_CXX_COMPILER_LAUNCHER={gomacc}',
          '-DCMAKE_ASM_COMPILER_LAUNCHER={gomacc}',
      ])

    options.extend({
        'linux': [
            '-DCMAKE_AR={ar}',
            '-DCMAKE_LINKER={ld}',
            '-DCMAKE_NM={nm}',
            '-DCMAKE_OBJCOPY={objcopy}',
            '-DCMAKE_OBJDUMP={objdump}',
            '-DCMAKE_RANLIB={ranlib}',
            '-DCMAKE_STRIP={strip}',
        ],
        'mac': [],
    }[api.platform.name])

    if api.platform.name == 'linux':
      options.extend([
          '-D{BOOTSTRAP_}CMAKE_C_FLAGS=-I%s' % zlib_install_dir.join('include'),
          '-D{BOOTSTRAP_}CMAKE_CXX_FLAGS=-I%s' %
          zlib_install_dir.join('include'),
          '-D{BOOTSTRAP_}ZLIB_ROOT=%s' % zlib_install_dir,
          '-D{BOOTSTRAP_}LIBXML2_INCLUDE_DIR=%s' % libxml2_install_dir.join(
              'include', 'libxml2'),
          '-D{BOOTSTRAP_}LIBXML2_LIBRARY=%s' % libxml2_install_dir.join(
              'lib', 'libxml2.a'),
      ])

      if prod:
        options.extend([
            '-DCMAKE_C_FLAGS=-I%s' % zlib_install_dir.join('include'),
            '-DCMAKE_CXX_FLAGS=-I%s' % zlib_install_dir.join('include'),
            '-DZLIB_ROOT=%s' % zlib_install_dir,
            '-DLIBXML2_INCLUDE_DIR=%s' % libxml2_install_dir.join(
                'include', 'libxml2'),
            '-DLIBXML2_LIBRARY=%s' % libxml2_install_dir.join(
                'lib', 'libxml2.a'),
        ])

      options.extend([
          # BOOTSTRAP_ prefixed flags are passed to the second stage compiler.
          '-D{BOOTSTRAP_}CMAKE_SHARED_LINKER_FLAGS=-static-libstdc++',
          '-D{BOOTSTRAP_}CMAKE_MODULE_LINKER_FLAGS=-static-libstdc++',
          '-D{BOOTSTRAP_}CMAKE_EXE_LINKER_FLAGS=-static-libstdc++',
          '-D{BOOTSTRAP_}CMAKE_SYSROOT={target_sysroot}',
      ])

      if prod:
        options.extend([
            # Unprefixed flags are used by the first stage compiler.
            '-DCMAKE_SHARED_LINKER_FLAGS=-static-libstdc++',
            '-DCMAKE_MODULE_LINKER_FLAGS=-static-libstdc++',
            '-DCMAKE_EXE_LINKER_FLAGS=-static-libstdc++',
            '-DCMAKE_SYSROOT={host_sysroot}',
        ])
      else:
        options.extend([
            '-DLLVM_ENABLE_LTO=OFF',
        ])

      if host_triple != target_triple:  # pragma: no cover
        options.extend([
            '-D{BOOTSTRAP_}CMAKE_SYSTEM_NAME=Linux',
            '-D{BOOTSTRAP_}CMAKE_C_COMPILER_TARGET={target_triple}',
            '-D{BOOTSTRAP_}CMAKE_CXX_COMPILER_TARGET={target_triple}',
            '-D{BOOTSTRAP_}LLVM_DEFAULT_TARGET_TRIPLE={target_triple}',
        ])
    elif api.platform.name == 'mac':
      options.extend([
          '-D{BOOTSTRAP_}CMAKE_%s_LINKER_FLAGS=-nostdlib++ %s' %
          (mode, cipd_dir.join('lib', 'libc++.a'))
          for mode in ['SHARED', 'MODULE', 'EXE']
      ])

      if prod:
        options.extend([
            '-DCMAKE_%s_LINKER_FLAGS=-nostdlib++ %s' %
            (mode, cipd_dir.join('lib', 'libc++.a'))
            for mode in ['SHARED', 'MODULE', 'EXE']
        ])
      else:
        options.extend([
            '-DLLVM_ENABLE_LTO=OFF',
        ])

    # STAGE2_ prefixed flags are passed to the second stage by the first stage build.
    if ci:
      options.extend([
          '-D{STAGE2_}LLVM_ENABLE_ASSERTIONS=ON',
      ])

    options.extend([
        '-D{STAGE2_}LINUX_aarch64-unknown-linux-gnu_SYSROOT={linux_arm64_sysroot}',
        '-D{STAGE2_}LINUX_armv7-unknown-linux-gnueabihf_SYSROOT={linux_armhf_sysroot}',
        '-D{STAGE2_}LINUX_i386-unknown-linux-gnu_SYSROOT={linux_i386_sysroot}',
        '-D{STAGE2_}LINUX_x86_64-unknown-linux-gnu_SYSROOT={linux_amd64_sysroot}',
        '-D{STAGE2_}FUCHSIA_SDK={fuchsia_sdk}',
    ])

    with api.step.nest('clang'), api.context(cwd=build_dir):
      api.step('configure', [cipd_dir.join('bin', 'cmake')] +
               [option.format(**arguments) for option in options] + [
                   '-C',
                   llvm_dir.join('clang', 'cmake', 'caches',
                                 'Fuchsia{_stage2}.cmake'.format(**arguments)),
                   llvm_dir.join('llvm')
               ])
      # Build the full (two-stage) distribution.
      api.step(
          'build',
          [
              cipd_dir.join('ninja'),
              # This only applies to the first stage, second stage is invoked by
              # CMake as a subprocess and will use Ninja's default.
              '-j%d' % ninja_jobs,
              '{stage2_}distribution'.format(**arguments),
          ])
      # Run the tests.
      projects = ['llvm', 'clang', 'lld']
      # TODO(phosek): run runtime tests
      #   + [(runtime + '-{target_triple}').format(**arguments)
      #      for runtime in ['unwind', 'cxxabi', 'cxx']]
      api.step('test', [cipd_dir.join('ninja'),
                        '-j%d' % api.goma.jobs] +
               [('{stage2_}check-' + project).format(**arguments)
                for project in projects])
      with api.context(env={'DESTDIR': pkg_dir}):
        api.step('install', [
            cipd_dir.join('ninja'),
            '{stage2_}install-distribution-stripped'.format(**arguments),
        ])

  step_result = api.file.read_text(
      'Version.inc',
      build_dir.join(*(
          (['tools', 'clang', 'stage2-bins'] if prod else []) +
          ['tools', 'clang', 'include', 'clang', 'Basic', 'Version.inc'])),
      test_data='#define CLANG_VERSION_STRING "8.0.0"')
  m = re.search(r'CLANG_VERSION_STRING "([a-zA-Z0-9.-]+)"', step_result)
  assert m, 'Cannot determine Clang version'
  clang_version = m.group(1)

  # TODO(TC-366): Ideally this would be done by the cmake build itself.
  # //zircon/public/gn/toolchain/clang.gni:clang_runtime sets the JSON schema.
  resource_dir_switch = '--resource-dir=clang/%s' % clang_version
  runtime_targets = [[
      '--target',
      '%s-unknown-fuchsia' % arch,
      '--alias',
      '%s-fuchsia' % arch,
  ] for arch in TARGET_TO_ARCH.itervalues()]
  api.python(
      'generate runtimes.json',
      script=api.resource('runtimes.py'),
      args=[
          '--dir', pkg_dir, '--readelf',
          cipd_dir.join('bin', 'llvm-readelf'), resource_dir_switch
      ] + [t for ts in runtime_targets for t in ts],
      stdout=api.json.output(
          leak_to=pkg_dir.join('lib', 'runtime.json'), name='runtime.json'))
  for target in runtime_targets:
    api.python(
        'generate %s.manifest' % target[-1],
        script=api.resource('runtimes.py'),
        args=[
            '--dir', pkg_dir, '--readelf',
            cipd_dir.join('bin', 'llvm-readelf'), resource_dir_switch,
            '--manifest'
        ] + target,
        stdout=api.raw_io.output(
            leak_to=pkg_dir.join('lib', '%s.manifest' % target[-1])))

  api.python(
      'generate license',
      api.resource('generate_license.py'),
      args=['--include'] + [
          llvm_dir.join(project, 'LICENSE.TXT')
          for project in llvm_projects + ['llvm'] + llvm_runtimes
      ] + [
          '--extract',
          api.path['start_dir'].join('libxml2', 'src', 'Copyright'),
          '-',
          '--extract',
          api.path['start_dir'].join('zlib', 'src', 'zlib.h'),
          '4-22',
      ],
      stdout=api.raw_io.output(leak_to=pkg_dir.join('LICENSE')))

  isolated = api.upload.upload_isolated(pkg_dir)

  if prod:
    # The published package has the same name for every platform.
    pkg_name = 'clang'
    api.upload.cipd_package(
        'fuchsia/third_party/%s/%s' % (pkg_name, target_platform),
        pkg_dir, [api.upload.DirectoryPath(pkg_dir)],
        {'git_revision': revision},
        repository=repository,
        extra_tags={'version': clang_version})

    # TODO(phosek): move this logic to clang_trigger.py recipe.
    if target_platform != 'linux-arm64':
      host = 'fuchsia.googlesource.com'
      project = 'fuchsia'
      refs = api.gitiles.refs('https://%s/%s' % (host, project))
      ref = 'refs/heads/master'
      fuchsia_rev = refs.get(ref, 'HEAD')

      # Do a full integration build. This will use the just-built toolchain
      # to build all of Fuchsia to check whether there are any regressions.
      api.scheduler.emit_trigger(
          api.scheduler.BuildbucketTrigger(
              properties={
                  'clang_toolchain': {
                      'git_repository': repository,
                      'git_revision': revision,
                  },
                  'build.clang_toolchain': {
                      'type': 'isolated',
                      'instance': isolated,
                  },
                  'checkout.buildset':
                      'commit/gitiles/%s/%s/+/%s' % (host, project,
                                                     fuchsia_rev),
              },
              tags={
                  'buildset':
                      'commit/gitiles/%s/+/%s' % (repository.split('://')[1],
                                                  revision),
                  'gitiles_ref':
                      ref,
              }),
          project='fuchsia',
          jobs={
              'linux-amd64': (
                  'clang_toolchain.fuchsia-arm64-debug',
                  'clang_toolchain.fuchsia-arm64-release',
                  'clang_toolchain.fuchsia-x64-debug',
                  'clang_toolchain.fuchsia-x64-release',
              ),
              'mac-amd64': ('clang_toolchain.fuchsia-host-mac',),
          }[target_platform])


def GenTests(api):
  for os in ('linux', 'mac'):
    yield (api.test('ci-%s-x64' % os) + api.buildbucket.ci_build(
        project='fuchsia',
        bucket='ci',
        git_repo='https://fuchsia.googlesource.com/third_party/llvm-project',
        revision='a' * 40,
    ) + api.runtime(is_luci=True, is_experimental=False) + api.platform.name(os)
           + api.properties(platform=os + '-amd64'))

    yield (api.test('prod-%s-x64' % os) + api.buildbucket.ci_build(
        project='fuchsia',
        bucket='prod',
        git_repo='https://fuchsia.googlesource.com/third_party/llvm-project',
        revision='a' * 40,
    ) + api.runtime(is_luci=True, is_experimental=False) + api.platform.name(os)
           + api.properties(platform=os + '-amd64') + api.gitiles.refs(
               'refs', ('refs/heads/master', 'b' * 40)))

  yield (api.test('linux-arm64') + api.buildbucket.ci_build(
      project='fuchsia',
      bucket='ci',
      git_repo='https://fuchsia.googlesource.com/third_party/llvm-project',
      revision='a' * 40,
  ) + api.runtime(is_luci=True, is_experimental=False) +
         api.platform.name('linux') + api.platform.arch('arm') +
         api.platform.bits(64) + api.properties(platform='linux-arm64'))
