# 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 GCC toolchain."""

from recipe_engine.config import Enum, ReturnSchema, Single
from recipe_engine.recipe_api import Property, StepFailure

import re


DEPS = [
  'infra/git',
  'infra/gitiles',
  'infra/goma',
  'infra/hash',
  'infra/jiri',
  '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',
  'recipe_engine/tempfile',
  'recipe_engine/url',
]

BINUTILS_GIT = 'https://gnu.googlesource.com/binutils-gdb'
BINUTILS_REF = 'refs/heads/binutils-2_31-branch'

GCC_GIT = 'https://gnu.googlesource.com/gcc'
GCC_REF = 'refs/tags/gcc-8_2_0-release'

PROPERTIES = {
  'binutils_revision': Property(kind=str, help='Revision in binutils repo',
                                default=None),
  'gcc_revision': Property(kind=str, help='Revision in GCC repo', default=None),
}


# binutils and gcc both have a daily robocommit to a specific file that
# just updates a date stamp.  If that's the only change since the last
# revision we built, this new revision is not worth building.
def DoCheckout(api, url, checkout_dir, revision, last_revision, useless_file):
  api.git.checkout(url, checkout_dir, revision)
  with api.context(cwd=checkout_dir):
    try:
      step = api.git(
          'diff', '--name-only', '%s..%s' % (last_revision, revision),
          name='check for changes other than %s' % useless_file,
          stdout=api.raw_io.output(name='changed files', add_output_log=True))
    except StepFailure as error:
      # If the old revision is no longer in the repo or something like that,
      # git can fail.  But that shouldn't make the build fail, it should just
      # not trigger the "useless change" short-circuit.
      return False
  changed_files = set(step.stdout.splitlines()) - set([useless_file])
  return changed_files == set()


def RunSteps(api, binutils_revision, gcc_revision):
  api.gitiles.ensure_gitiles()
  api.goma.ensure_goma()

  if binutils_revision is None:
    binutils_revision = api.gitiles.refs(
        BINUTILS_GIT, step_name='binutils refs').get(BINUTILS_REF, None)
  if gcc_revision is None:
    gcc_revision = api.gitiles.refs(
        GCC_GIT, step_name='gcc refs').get(GCC_REF, None)

  cipd_pkg_name = 'fuchsia/gcc/${platform}'
  cipd_git_revision = ','.join([gcc_revision, binutils_revision])

  pins = api.cipd.search(cipd_pkg_name, 'git_revision:' + cipd_git_revision)
  if len(pins) > 0:
    api.step('Package is up-to-date', cmd=None)
    return

  with api.step.nest('ensure_packages'):
    with api.context(infra_steps=True):
      pkgs = api.cipd.EnsureFile()
      pkgs.add_package('fuchsia/clang/${platform}', 'goma')
      if api.platform.name == 'linux':
        pkgs.add_package('fuchsia/sysroot/${platform}', 'latest')
      cipd_dir = api.path['start_dir'].join('cipd')
      api.cipd.ensure(cipd_dir, pkgs)

  if api.platform.name == 'linux':
    host_sysroot = cipd_dir
  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'))
    host_sysroot = step_result.stdout.strip()
  else: # pragma: no cover
    assert false, "what platform?"

  description = api.cipd.describe(
      cipd_pkg_name, 'latest', test_data_tags=[
        'git_revision:b824b5a2484202f6eabbe118b1cf7682ce77b76e,5898623efb820fc56123da2e316756a9a32cb59b'])

  [last_tag] = [cipd_tag.tag
                for cipd_tag in description.tags
                if cipd_tag.tag.startswith('git_revision:')]
  [last_gcc_revision, last_binutils_revision] = last_tag[
      len('git_revision:'):].split(',')

  with api.context(infra_steps=True):
    binutils_dir = api.path['start_dir'].join('binutils-gdb')
    binutils_no_change = DoCheckout(api, BINUTILS_GIT, binutils_dir,
                                    binutils_revision, last_binutils_revision,
                                    'bfd/version.h')
    gcc_dir = api.path['start_dir'].join('gcc')
    gcc_no_change = DoCheckout(api, GCC_GIT, gcc_dir,
                               gcc_revision, last_gcc_revision,
                               'gcc/DATESTAMP')
    if binutils_no_change and gcc_no_change:
      api.step('Revisions contain no useful changes', cmd=None)
      return

  with api.context(cwd=gcc_dir):
    # download GCC dependencies: GMP, ISL, MPC and MPFR libraries
    api.step('download prerequisites', [
      gcc_dir.join('contrib', 'download_prerequisites')
    ])

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

  host_clang = '%s %s' % (api.goma.goma_dir.join('gomacc'),
                          cipd_dir.join('bin', 'clang'))
  host_cflags = '-O3 --sysroot=%s' % host_sysroot
  if api.platform.name != 'mac':
    # LTO works for binutils on Linux but fails on macOS.
    host_cflags += ' -flto'
  host_compiler_args = {
      'CC': host_clang,
      'CXX': '%s++' % host_clang,
      'CFLAGS': host_cflags,
      'CXXFLAGS': host_cflags,
  }

  if api.platform.name != 'mac':
    # TODO(mcgrathr): Our host toolchain is currently broken on non-Mac
    # where we provide only static libc++.a that depends on other libraries
    # but we require linking to them explicitly on the command line to
    # satisfy libc++.a's implicit dependencies.
    host_compiler_args['CXXFLAGS'] += ' -lpthread -ldl'

  host_compiler_args = sorted('%s=%s' % item
                              for item in host_compiler_args.iteritems())

  with api.goma.build_with_goma():
    for target, enable_targets in [('aarch64', 'arm-eabi'),
                                   ('x86_64', 'x86_64-pep')]:
      # configure arguments that are the same for binutils and gcc.
      common_args =  host_compiler_args + [
          '--prefix=', # we're building a relocatable package
          '--target=%s-elf' % target,
          '--enable-initfini-array', # Fuchsia uses .init/.fini arrays
          '--enable-gold', # Zircon uses gold for userspace build
          # Enable plugins and threading for Gold.
          # This also happens to make it explicitly link in -lpthread and -dl,
          # which are required by host_clang's static libc++.
          '--enable-plugins',
          '--enable-threads',
          '--disable-werror', # ignore warnings reported by Clang
          '--disable-nls', # no need for localization
          '--with-included-gettext', # use include gettext library
      ]

      # build binutils
      binutils_build_dir = staging_dir.join('binutils_%s_build_dir' % target)
      api.file.ensure_directory('create binutils %s build dir' % target,
                                binutils_build_dir)

      with api.context(cwd=binutils_build_dir):
        def binutils_make_step(name, prefix, jobs, make_args=[], logs=[]):
          return api.step('%s %s binutils' % (name, target),
                          ['make','-j%s' % jobs] + make_args +
                          ['%s-%s' % (prefix, component)
                           for component in ['binutils', 'gas', 'ld', 'gold']])
        api.step('configure %s binutils' % target, [
          binutils_dir.join('configure'),
          '--enable-deterministic-archives', # more deterministic builds
          '--enable-targets=%s' % enable_targets,
        ] + common_args)
        binutils_make_step('build', 'all', api.goma.jobs)
        try:
          binutils_make_step('test', 'check', api.platform.cpu_count, ['-k'])
        except StepFailure as error:
          logs = {
            l[0]: api.file.read_text('binutils %s %s' % (target, '/'.join(l)),
                                     binutils_build_dir.join(*l)).splitlines()
            for l in [
              ('gas', 'testsuite', 'gas.log'),
              ('binutils', 'binutils.log'),
              ('ld', 'ld.log'),
              ('gold', 'testsuite', 'test-suite.log'),
            ]
          }
          step_result = api.step('binutils test failure', cmd=None)
          for name, text in logs.iteritems():
            step_result.presentation.logs[name] = text
          raise error
        binutils_make_step('install', 'install-strip', 1,
                           ['DESTDIR=%s' % pkg_dir])

      # build gcc
      gcc_build_dir = staging_dir.join('gcc_%s_build_dir' % target)
      api.file.ensure_directory('create gcc %s build dir' % target,
                                gcc_build_dir)

      with api.context(cwd=gcc_build_dir,
                       env_prefixes={'PATH': [pkg_dir.join('bin')]}):
        gcc_goals = ['gcc', 'target-libgcc']
        def gcc_make_step(name, jobs, args):
          cmd = [
              'make',
              '-j%s' % jobs,
              'MAKEOVERRIDES=USE_GCC_STDINT=provide',
          ]
          return api.step('%s %s gcc' % (name, target), cmd + args)
        api.step('configure %s gcc' % target, [
          gcc_dir.join('configure'),
          '--enable-languages=c,c++',
          '--disable-libstdcxx', # we don't need libstdc++
          '--disable-libssp', # we don't need libssp either
          '--disable-libquadmath', # and nor do we need libquadmath
        ] + common_args)
        gcc_make_step('build', api.goma.jobs,
                      ['all-%s' % goal for goal in gcc_goals])
        try:
          gcc_make_step('test', api.platform.cpu_count, ['check-gcc'])
        finally:
          logs = {
            l[-1]: api.file.read_text('gcc %s %s' % (target, '/'.join(l)),
                                      gcc_build_dir.join(*l)).splitlines()
            for l in [
              ('gcc', 'testsuite', 'gcc', 'gcc.log'),
              ('gcc', 'testsuite', 'g++', 'g++.log'),
            ]
          }
          step_result = api.step('test %s gcc logs' % target, cmd=None)
          for name, text in logs.iteritems():
            step_result.presentation.logs[name] = text
        gcc_make_step('install', 1,
                      ['DESTDIR=%s' % pkg_dir] +
                      ['install-strip-%s' % goal for goal in gcc_goals])

  binutils_version = api.file.read_text('binutils version',
                                        binutils_dir.join('bfd', 'version.m4'))
  m = re.match(r'm4_define\(\[BFD_VERSION\], \[([^]]+)\]\)', binutils_version)
  assert m and m.group(1), 'bfd/version.m4 has unexpected format'
  binutils_version = m.group(1)
  gcc_version = api.file.read_text('gcc version',
                                   gcc_dir.join('gcc', 'BASE-VER')).rstrip()

  pkg_def = api.cipd.PackageDefinition(
      package_name=cipd_pkg_name,
      package_root=pkg_dir,
      install_mode='copy')
  pkg_def.add_dir(pkg_dir)
  pkg_def.add_version_file('.versions/gcc.cipd_version')

  cipd_pkg_file = api.path['cleanup'].join('gcc.cipd')

  api.cipd.build_from_pkg(
      pkg_def=pkg_def,
      output_package=cipd_pkg_file,
  )
  step_result = api.cipd.register(
      package_name=cipd_pkg_name,
      package_path=cipd_pkg_file,
      refs=['latest'],
      tags={
        'version': ','.join([gcc_version, binutils_version]),
        'git_repository': ','.join([GCC_GIT, BINUTILS_GIT]),
        'git_revision': cipd_git_revision,
      },
  )


def GenTests(api):
  binutils_revision = '3d861fdb826c2f5cf270dd5f585d0e6057e1bf4f'
  gcc_revision = '4b5e15daff8b54440e3fda451c318ad31e532fab'
  cipd_revision = ','.join([gcc_revision, binutils_revision])
  for platform in ('linux', 'mac'):
    yield (api.test(platform) +
           api.platform.name(platform) +
           api.gitiles.refs('binutils refs',
                            (BINUTILS_REF, binutils_revision)) +
           api.gitiles.refs('gcc refs',
                            (GCC_REF, gcc_revision)))
    yield (api.test(platform + '_new') +
           api.platform.name(platform) +
           api.gitiles.refs('binutils refs',
                            (BINUTILS_REF, binutils_revision)) +
           api.gitiles.refs('gcc refs',
                            (GCC_REF, gcc_revision)) +
           api.step_data('cipd search fuchsia/gcc/${platform} ' +
                         'git_revision:' + cipd_revision,
                         api.json.output({'result': []})) +
           api.step_data('check for changes other than bfd/version.h',
                         api.raw_io.stream_output('bfd/version.h\nothers\n',
                                                  name='changed files')) +
           api.step_data('check for changes other than gcc/DATESTAMP',
                         api.raw_io.stream_output('gcc/DATESTAMP\nothers\n',
                                                  name='changed files')) +
           api.step_data('binutils version', api.file.read_text(
               'm4_define([BFD_VERSION], [2.27.0])')) +
           api.step_data('gcc version', api.file.read_text('7.1.2\n')))
    yield (api.test(platform + '_binutils_test_fail') +
           api.platform.name(platform) +
           api.gitiles.refs('binutils refs',
                            (BINUTILS_REF, binutils_revision)) +
           api.gitiles.refs('gcc refs',
                            (GCC_REF, gcc_revision)) +
           api.step_data('cipd search fuchsia/gcc/${platform} ' +
                         'git_revision:' + cipd_revision,
                         api.json.output({'result': []})) +
           api.step_data('check for changes other than bfd/version.h',
                         api.raw_io.stream_output('bfd/version.h\nothers\n',
                                                  name='changed files')) +
           api.step_data('check for changes other than gcc/DATESTAMP',
                         api.raw_io.stream_output('gcc/DATESTAMP\nothers\n',
                                                  name='changed files')) +
           api.step_data('test x86_64 binutils', retcode=1))
    yield (api.test(platform + '_gcc_test_fail') +
           api.platform.name(platform) +
           api.gitiles.refs('binutils refs',
                            (BINUTILS_REF, binutils_revision)) +
           api.gitiles.refs('gcc refs',
                            (GCC_REF, gcc_revision)) +
           api.step_data('cipd search fuchsia/gcc/${platform} ' +
                         'git_revision:' + cipd_revision,
                         api.json.output({'result': []})) +
           api.step_data('check for changes other than bfd/version.h',
                         api.raw_io.stream_output('bfd/version.h\nothers\n',
                                                  name='changed files')) +
           api.step_data('check for changes other than gcc/DATESTAMP',
                         api.raw_io.stream_output('', retcode=1,
                                                  name='changed files')) +
           api.step_data('test aarch64 gcc', retcode=1))
    yield (api.test(platform + '_useless') +
           api.platform.name(platform) +
           api.gitiles.refs('binutils refs',
                            (BINUTILS_REF, binutils_revision)) +
           api.gitiles.refs('gcc refs',
                            (GCC_REF, gcc_revision)) +
           api.step_data('cipd search fuchsia/gcc/${platform} ' +
                         'git_revision:' + cipd_revision,
                         api.json.output({'result': []})) +
           api.step_data('check for changes other than bfd/version.h',
                         api.raw_io.stream_output('bfd/version.h\n',
                                                  name='changed files')) +
           api.step_data('check for changes other than gcc/DATESTAMP',
                         api.raw_io.stream_output('gcc/DATESTAMP\n',
                                                  name='changed files')))
