#!/usr/bin/python3
# Build many configurations of glibc.
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>.

"""Build many configurations of glibc.

This script takes as arguments a directory name (containing a src
subdirectory with sources of the relevant toolchain components) and a
description of what to do: 'checkout', to check out sources into that
directory, 'bot-cycle', to run a series of checkout and build steps,
'bot', to run 'bot-cycle' repeatedly, 'host-libraries', to build
libraries required by the toolchain, 'compilers', to build
cross-compilers for various configurations, or 'glibcs', to build
glibc for various configurations and run the compilation parts of the
testsuite.  Subsequent arguments name the versions of components to
check out (<component>-<version), for 'checkout', or, for actions
other than 'checkout' and 'bot-cycle', name configurations for which
compilers or glibc are to be built.

"""

import argparse
import datetime
import email.mime.text
import email.utils
import json
import os
import re
import shutil
import smtplib
import stat
import subprocess
import sys
import time
import urllib.request

try:
    os.cpu_count
except:
    import multiprocessing
    os.cpu_count = lambda: multiprocessing.cpu_count()

try:
    re.fullmatch
except:
    re.fullmatch = lambda p,s,f=0: re.match(p+"\\Z",s,f)

try:
    subprocess.run
except:
    class _CompletedProcess:
        def __init__(self, args, returncode, stdout=None, stderr=None):
            self.args = args
            self.returncode = returncode
            self.stdout = stdout
            self.stderr = stderr

    def _run(*popenargs, input=None, timeout=None, check=False, **kwargs):
        assert(timeout is None)
        with subprocess.Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input)
            except:
                process.kill()
                process.wait()
                raise
            returncode = process.poll()
            if check and returncode:
                raise subprocess.CalledProcessError(returncode, popenargs)
        return _CompletedProcess(popenargs, returncode, stdout, stderr)

    subprocess.run = _run


class Context(object):
    """The global state associated with builds in a given directory."""

    def __init__(self, topdir, parallelism, keep, replace_sources, strip,
                 action):
        """Initialize the context."""
        self.topdir = topdir
        self.parallelism = parallelism
        self.keep = keep
        self.replace_sources = replace_sources
        self.strip = strip
        self.srcdir = os.path.join(topdir, 'src')
        self.versions_json = os.path.join(self.srcdir, 'versions.json')
        self.build_state_json = os.path.join(topdir, 'build-state.json')
        self.bot_config_json = os.path.join(topdir, 'bot-config.json')
        self.installdir = os.path.join(topdir, 'install')
        self.host_libraries_installdir = os.path.join(self.installdir,
                                                      'host-libraries')
        self.builddir = os.path.join(topdir, 'build')
        self.logsdir = os.path.join(topdir, 'logs')
        self.logsdir_old = os.path.join(topdir, 'logs-old')
        self.makefile = os.path.join(self.builddir, 'Makefile')
        self.wrapper = os.path.join(self.builddir, 'wrapper')
        self.save_logs = os.path.join(self.builddir, 'save-logs')
        self.script_text = self.get_script_text()
        if action != 'checkout':
            self.build_triplet = self.get_build_triplet()
            self.glibc_version = self.get_glibc_version()
        self.configs = {}
        self.glibc_configs = {}
        self.makefile_pieces = ['.PHONY: all\n']
        self.add_all_configs()
        self.load_versions_json()
        self.load_build_state_json()
        self.status_log_list = []
        self.email_warning = False

    def get_script_text(self):
        """Return the text of this script."""
        with open(sys.argv[0], 'r') as f:
            return f.read()

    def exec_self(self):
        """Re-execute this script with the same arguments."""
        sys.stdout.flush()
        os.execv(sys.executable, [sys.executable] + sys.argv)

    def get_build_triplet(self):
        """Determine the build triplet with config.guess."""
        config_guess = os.path.join(self.component_srcdir('gcc'),
                                    'config.guess')
        cg_out = subprocess.run([config_guess], stdout=subprocess.PIPE,
                                check=True, universal_newlines=True).stdout
        return cg_out.rstrip()

    def get_glibc_version(self):
        """Determine the glibc version number (major.minor)."""
        version_h = os.path.join(self.component_srcdir('glibc'), 'version.h')
        with open(version_h, 'r') as f:
            lines = f.readlines()
        starttext = '#define VERSION "'
        for l in lines:
            if l.startswith(starttext):
                l = l[len(starttext):]
                l = l.rstrip('"\n')
                m = re.fullmatch('([0-9]+)\.([0-9]+)[.0-9]*', l)
                return '%s.%s' % m.group(1, 2)
        print('error: could not determine glibc version')
        exit(1)

    def add_all_configs(self):
        """Add all known glibc build configurations."""
        self.add_config(arch='aarch64',
                        os_name='linux-gnu',
                        extra_glibcs=[{'variant': 'disable-multi-arch',
                                       'cfg': ['--disable-multi-arch']}])
        self.add_config(arch='aarch64_be',
                        os_name='linux-gnu')
        self.add_config(arch='alpha',
                        os_name='linux-gnu')
        self.add_config(arch='arm',
                        os_name='linux-gnueabi')
        self.add_config(arch='armeb',
                        os_name='linux-gnueabi')
        self.add_config(arch='armeb',
                        os_name='linux-gnueabi',
                        variant='be8',
                        gcc_cfg=['--with-arch=armv7-a'])
        self.add_config(arch='arm',
                        os_name='linux-gnueabihf',
                        gcc_cfg=['--with-float=hard', '--with-cpu=arm926ej-s'],
                        extra_glibcs=[{'variant': 'v7a',
                                       'ccopts': '-march=armv7-a -mfpu=vfpv3'},
                                      {'variant': 'v7a-disable-multi-arch',
                                       'ccopts': '-march=armv7-a -mfpu=vfpv3',
                                       'cfg': ['--disable-multi-arch']}])
        self.add_config(arch='armeb',
                        os_name='linux-gnueabihf',
                        gcc_cfg=['--with-float=hard', '--with-cpu=arm926ej-s'])
        self.add_config(arch='armeb',
                        os_name='linux-gnueabihf',
                        variant='be8',
                        gcc_cfg=['--with-float=hard', '--with-arch=armv7-a',
                                 '--with-fpu=vfpv3'])
        self.add_config(arch='hppa',
                        os_name='linux-gnu')
        self.add_config(arch='i686',
                        os_name='gnu')
        self.add_config(arch='ia64',
                        os_name='linux-gnu',
                        first_gcc_cfg=['--with-system-libunwind'])
        self.add_config(arch='m68k',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib'])
        self.add_config(arch='m68k',
                        os_name='linux-gnu',
                        variant='coldfire',
                        gcc_cfg=['--with-arch=cf', '--disable-multilib'])
        self.add_config(arch='m68k',
                        os_name='linux-gnu',
                        variant='coldfire-soft',
                        gcc_cfg=['--with-arch=cf', '--with-cpu=54455',
                                 '--disable-multilib'])
        self.add_config(arch='microblaze',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib'])
        self.add_config(arch='microblazeel',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib'])
        self.add_config(arch='mips64',
                        os_name='linux-gnu',
                        gcc_cfg=['--with-mips-plt'],
                        glibcs=[{'variant': 'n32'},
                                {'arch': 'mips',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64',
                        os_name='linux-gnu',
                        variant='soft',
                        gcc_cfg=['--with-mips-plt', '--with-float=soft'],
                        glibcs=[{'variant': 'n32-soft'},
                                {'variant': 'soft',
                                 'arch': 'mips',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-soft',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64',
                        os_name='linux-gnu',
                        variant='nan2008',
                        gcc_cfg=['--with-mips-plt', '--with-nan=2008',
                                 '--with-arch-64=mips64r2',
                                 '--with-arch-32=mips32r2'],
                        glibcs=[{'variant': 'n32-nan2008'},
                                {'variant': 'nan2008',
                                 'arch': 'mips',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-nan2008',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64',
                        os_name='linux-gnu',
                        variant='nan2008-soft',
                        gcc_cfg=['--with-mips-plt', '--with-nan=2008',
                                 '--with-arch-64=mips64r2',
                                 '--with-arch-32=mips32r2',
                                 '--with-float=soft'],
                        glibcs=[{'variant': 'n32-nan2008-soft'},
                                {'variant': 'nan2008-soft',
                                 'arch': 'mips',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-nan2008-soft',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64el',
                        os_name='linux-gnu',
                        gcc_cfg=['--with-mips-plt'],
                        glibcs=[{'variant': 'n32'},
                                {'arch': 'mipsel',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64el',
                        os_name='linux-gnu',
                        variant='soft',
                        gcc_cfg=['--with-mips-plt', '--with-float=soft'],
                        glibcs=[{'variant': 'n32-soft'},
                                {'variant': 'soft',
                                 'arch': 'mipsel',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-soft',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64el',
                        os_name='linux-gnu',
                        variant='nan2008',
                        gcc_cfg=['--with-mips-plt', '--with-nan=2008',
                                 '--with-arch-64=mips64r2',
                                 '--with-arch-32=mips32r2'],
                        glibcs=[{'variant': 'n32-nan2008'},
                                {'variant': 'nan2008',
                                 'arch': 'mipsel',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-nan2008',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='mips64el',
                        os_name='linux-gnu',
                        variant='nan2008-soft',
                        gcc_cfg=['--with-mips-plt', '--with-nan=2008',
                                 '--with-arch-64=mips64r2',
                                 '--with-arch-32=mips32r2',
                                 '--with-float=soft'],
                        glibcs=[{'variant': 'n32-nan2008-soft'},
                                {'variant': 'nan2008-soft',
                                 'arch': 'mipsel',
                                 'ccopts': '-mabi=32'},
                                {'variant': 'n64-nan2008-soft',
                                 'ccopts': '-mabi=64'}])
        self.add_config(arch='nios2',
                        os_name='linux-gnu')
        self.add_config(arch='powerpc',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib', '--enable-secureplt'],
                        extra_glibcs=[{'variant': 'power4',
                                       'ccopts': '-mcpu=power4',
                                       'cfg': ['--with-cpu=power4']}])
        self.add_config(arch='powerpc',
                        os_name='linux-gnu',
                        variant='soft',
                        gcc_cfg=['--disable-multilib', '--with-float=soft',
                                 '--enable-secureplt'])
        self.add_config(arch='powerpc64',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib', '--enable-secureplt'])
        self.add_config(arch='powerpc64le',
                        os_name='linux-gnu',
                        gcc_cfg=['--disable-multilib', '--enable-secureplt'])
        self.add_config(arch='powerpc',
                        os_name='linux-gnuspe',
                        gcc_cfg=['--disable-multilib', '--enable-secureplt',
                                 '--enable-e500-double'])
        self.add_config(arch='powerpc',
                        os_name='linux-gnuspe',
                        variant='e500v1',
                        gcc_cfg=['--disable-multilib', '--enable-secureplt'])
        self.add_config(arch='riscv64',
                        os_name='linux-gnu',
                        variant='rv64imac-lp64',
                        gcc_cfg=['--with-arch=rv64imac', '--with-abi=lp64',
                                 '--disable-multilib'])
        self.add_config(arch='riscv64',
                        os_name='linux-gnu',
                        variant='rv64imafdc-lp64',
                        gcc_cfg=['--with-arch=rv64imafdc', '--with-abi=lp64',
                                 '--disable-multilib'])
        self.add_config(arch='riscv64',
                        os_name='linux-gnu',
                        variant='rv64imafdc-lp64d',
                        gcc_cfg=['--with-arch=rv64imafdc', '--with-abi=lp64d',
                                 '--disable-multilib'])
        self.add_config(arch='s390x',
                        os_name='linux-gnu',
                        glibcs=[{},
                                {'arch': 's390', 'ccopts': '-m31'}])
        self.add_config(arch='sh3',
                        os_name='linux-gnu')
        self.add_config(arch='sh3eb',
                        os_name='linux-gnu')
        self.add_config(arch='sh4',
                        os_name='linux-gnu')
        self.add_config(arch='sh4eb',
                        os_name='linux-gnu')
        self.add_config(arch='sh4',
                        os_name='linux-gnu',
                        variant='soft',
                        gcc_cfg=['--without-fp'])
        self.add_config(arch='sh4eb',
                        os_name='linux-gnu',
                        variant='soft',
                        gcc_cfg=['--without-fp'])
        self.add_config(arch='sparc64',
                        os_name='linux-gnu',
                        glibcs=[{},
                                {'arch': 'sparcv9',
                                 'ccopts': '-m32 -mlong-double-128'}],
                        extra_glibcs=[{'variant': 'disable-multi-arch',
                                       'cfg': ['--disable-multi-arch']},
                                      {'variant': 'disable-multi-arch',
                                       'arch': 'sparcv9',
                                       'ccopts': '-m32 -mlong-double-128',
                                       'cfg': ['--disable-multi-arch']}])
        self.add_config(arch='tilegx',
                        os_name='linux-gnu',
                        glibcs=[{},
                                {'variant': '32', 'ccopts': '-m32'}])
        self.add_config(arch='tilegxbe',
                        os_name='linux-gnu',
                        glibcs=[{},
                                {'variant': '32', 'ccopts': '-m32'}])
        self.add_config(arch='x86_64',
                        os_name='linux-gnu',
                        gcc_cfg=['--with-multilib-list=m64,m32,mx32'],
                        glibcs=[{},
                                {'variant': 'x32', 'ccopts': '-mx32'},
                                {'arch': 'i686', 'ccopts': '-m32 -march=i686'}],
                        extra_glibcs=[{'variant': 'disable-multi-arch',
                                       'cfg': ['--disable-multi-arch']},
                                      {'variant': 'static-pie',
                                       'cfg': ['--enable-static-pie']},
                                      {'variant': 'x32-static-pie',
                                       'ccopts': '-mx32',
                                       'cfg': ['--enable-static-pie']},
                                      {'variant': 'static-pie',
                                       'arch': 'i686',
                                       'ccopts': '-m32 -march=i686',
                                       'cfg': ['--enable-static-pie']},
                                      {'variant': 'disable-multi-arch',
                                       'arch': 'i686',
                                       'ccopts': '-m32 -march=i686',
                                       'cfg': ['--disable-multi-arch']},
                                      {'arch': 'i486',
                                       'ccopts': '-m32 -march=i486'},
                                      {'arch': 'i586',
                                       'ccopts': '-m32 -march=i586'}])

    def add_config(self, **args):
        """Add an individual build configuration."""
        cfg = Config(self, **args)
        if cfg.name in self.configs:
            print('error: duplicate config %s' % cfg.name)
            exit(1)
        self.configs[cfg.name] = cfg
        for c in cfg.all_glibcs:
            if c.name in self.glibc_configs:
                print('error: duplicate glibc config %s' % c.name)
                exit(1)
            self.glibc_configs[c.name] = c

    def component_srcdir(self, component):
        """Return the source directory for a given component, e.g. gcc."""
        return os.path.join(self.srcdir, component)

    def component_builddir(self, action, config, component, subconfig=None):
        """Return the directory to use for a build."""
        if config is None:
            # Host libraries.
            assert subconfig is None
            return os.path.join(self.builddir, action, component)
        if subconfig is None:
            return os.path.join(self.builddir, action, config, component)
        else:
            # glibc build as part of compiler build.
            return os.path.join(self.builddir, action, config, component,
                                subconfig)

    def compiler_installdir(self, config):
        """Return the directory in which to install a compiler."""
        return os.path.join(self.installdir, 'compilers', config)

    def compiler_bindir(self, config):
        """Return the directory in which to find compiler binaries."""
        return os.path.join(self.compiler_installdir(config), 'bin')

    def compiler_sysroot(self, config):
        """Return the sysroot directory for a compiler."""
        return os.path.join(self.compiler_installdir(config), 'sysroot')

    def glibc_installdir(self, config):
        """Return the directory in which to install glibc."""
        return os.path.join(self.installdir, 'glibcs', config)

    def run_builds(self, action, configs):
        """Run the requested builds."""
        if action == 'checkout':
            self.checkout(configs)
            return
        if action == 'bot-cycle':
            if configs:
                print('error: configurations specified for bot-cycle')
                exit(1)
            self.bot_cycle()
            return
        if action == 'bot':
            if configs:
                print('error: configurations specified for bot')
                exit(1)
            self.bot()
            return
        if action == 'host-libraries' and configs:
            print('error: configurations specified for host-libraries')
            exit(1)
        self.clear_last_build_state(action)
        build_time = datetime.datetime.utcnow()
        if action == 'host-libraries':
            build_components = ('gmp', 'mpfr', 'mpc')
            old_components = ()
            old_versions = {}
            self.build_host_libraries()
        elif action == 'compilers':
            build_components = ('binutils', 'gcc', 'glibc', 'linux', 'mig',
                                'gnumach', 'hurd')
            old_components = ('gmp', 'mpfr', 'mpc')
            old_versions = self.build_state['host-libraries']['build-versions']
            self.build_compilers(configs)
        else:
            build_components = ('glibc',)
            old_components = ('gmp', 'mpfr', 'mpc', 'binutils', 'gcc', 'linux',
                              'mig', 'gnumach', 'hurd')
            old_versions = self.build_state['compilers']['build-versions']
            self.build_glibcs(configs)
        self.write_files()
        self.do_build()
        if configs:
            # Partial build, do not update stored state.
            return
        build_versions = {}
        for k in build_components:
            if k in self.versions:
                build_versions[k] = {'version': self.versions[k]['version'],
                                     'revision': self.versions[k]['revision']}
        for k in old_components:
            if k in old_versions:
                build_versions[k] = {'version': old_versions[k]['version'],
                                     'revision': old_versions[k]['revision']}
        self.update_build_state(action, build_time, build_versions)

    @staticmethod
    def remove_dirs(*args):
        """Remove directories and their contents if they exist."""
        for dir in args:
            shutil.rmtree(dir, ignore_errors=True)

    @staticmethod
    def remove_recreate_dirs(*args):
        """Remove directories if they exist, and create them as empty."""
        Context.remove_dirs(*args)
        for dir in args:
            os.makedirs(dir, exist_ok=True)

    def add_makefile_cmdlist(self, target, cmdlist, logsdir):
        """Add makefile text for a list of commands."""
        commands = cmdlist.makefile_commands(self.wrapper, logsdir)
        self.makefile_pieces.append('all: %s\n.PHONY: %s\n%s:\n%s\n' %
                                    (target, target, target, commands))
        self.status_log_list.extend(cmdlist.status_logs(logsdir))

    def write_files(self):
        """Write out the Makefile and wrapper script."""
        mftext = ''.join(self.makefile_pieces)
        with open(self.makefile, 'w') as f:
            f.write(mftext)
        wrapper_text = (
            '#!/bin/sh\n'
            'prev_base=$1\n'
            'this_base=$2\n'
            'desc=$3\n'
            'dir=$4\n'
            'path=$5\n'
            'shift 5\n'
            'prev_status=$prev_base-status.txt\n'
            'this_status=$this_base-status.txt\n'
            'this_log=$this_base-log.txt\n'
            'date > "$this_log"\n'
            'echo >> "$this_log"\n'
            'echo "Description: $desc" >> "$this_log"\n'
            'printf "%s" "Command:" >> "$this_log"\n'
            'for word in "$@"; do\n'
            '  if expr "$word" : "[]+,./0-9@A-Z_a-z-]\\\\{1,\\\\}\\$" > /dev/null; then\n'
            '    printf " %s" "$word"\n'
            '  else\n'
            '    printf " \'"\n'
            '    printf "%s" "$word" | sed -e "s/\'/\'\\\\\\\\\'\'/"\n'
            '    printf "\'"\n'
            '  fi\n'
            'done >> "$this_log"\n'
            'echo >> "$this_log"\n'
            'echo "Directory: $dir" >> "$this_log"\n'
            'echo "Path addition: $path" >> "$this_log"\n'
            'echo >> "$this_log"\n'
            'record_status ()\n'
            '{\n'
            '  echo >> "$this_log"\n'
            '  echo "$1: $desc" > "$this_status"\n'
            '  echo "$1: $desc" >> "$this_log"\n'
            '  echo >> "$this_log"\n'
            '  date >> "$this_log"\n'
            '  echo "$1: $desc"\n'
            '  exit 0\n'
            '}\n'
            'check_error ()\n'
            '{\n'
            '  if [ "$1" != "0" ]; then\n'
            '    record_status FAIL\n'
            '  fi\n'
            '}\n'
            'if [ "$prev_base" ] && ! grep -q "^PASS" "$prev_status"; then\n'
            '    record_status UNRESOLVED\n'
            'fi\n'
            'if [ "$dir" ]; then\n'
            '  cd "$dir"\n'
            '  check_error "$?"\n'
            'fi\n'
            'if [ "$path" ]; then\n'
            '  PATH=$path:$PATH\n'
            'fi\n'
            '"$@" < /dev/null >> "$this_log" 2>&1\n'
            'check_error "$?"\n'
            'record_status PASS\n')
        with open(self.wrapper, 'w') as f:
            f.write(wrapper_text)
        # Mode 0o755.
        mode_exec = (stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|
                     stat.S_IROTH|stat.S_IXOTH)
        os.chmod(self.wrapper, mode_exec)
        save_logs_text = (
            '#!/bin/sh\n'
            'if ! [ -f tests.sum ]; then\n'
            '  echo "No test summary available."\n'
            '  exit 0\n'
            'fi\n'
            'save_file ()\n'
            '{\n'
            '  echo "Contents of $1:"\n'
            '  echo\n'
            '  cat "$1"\n'
            '  echo\n'
            '  echo "End of contents of $1."\n'
            '  echo\n'
            '}\n'
            'save_file tests.sum\n'
            'non_pass_tests=$(grep -v "^PASS: " tests.sum | sed -e "s/^PASS: //")\n'
            'for t in $non_pass_tests; do\n'
            '  if [ -f "$t.out" ]; then\n'
            '    save_file "$t.out"\n'
            '  fi\n'
            'done\n')
        with open(self.save_logs, 'w') as f:
            f.write(save_logs_text)
        os.chmod(self.save_logs, mode_exec)

    def do_build(self):
        """Do the actual build."""
        cmd = ['make', '-j%d' % self.parallelism]
        subprocess.run(cmd, cwd=self.builddir, check=True)

    def build_host_libraries(self):
        """Build the host libraries."""
        installdir = self.host_libraries_installdir
        builddir = os.path.join(self.builddir, 'host-libraries')
        logsdir = os.path.join(self.logsdir, 'host-libraries')
        self.remove_recreate_dirs(installdir, builddir, logsdir)
        cmdlist = CommandList('host-libraries', self.keep)
        self.build_host_library(cmdlist, 'gmp')
        self.build_host_library(cmdlist, 'mpfr',
                                ['--with-gmp=%s' % installdir])
        self.build_host_library(cmdlist, 'mpc',
                                ['--with-gmp=%s' % installdir,
                                '--with-mpfr=%s' % installdir])
        cmdlist.add_command('done', ['touch', os.path.join(installdir, 'ok')])
        self.add_makefile_cmdlist('host-libraries', cmdlist, logsdir)

    def build_host_library(self, cmdlist, lib, extra_opts=None):
        """Build one host library."""
        srcdir = self.component_srcdir(lib)
        builddir = self.component_builddir('host-libraries', None, lib)
        installdir = self.host_libraries_installdir
        cmdlist.push_subdesc(lib)
        cmdlist.create_use_dir(builddir)
        cfg_cmd = [os.path.join(srcdir, 'configure'),
                   '--prefix=%s' % installdir,
                   '--disable-shared']
        if extra_opts:
            cfg_cmd.extend (extra_opts)
        cmdlist.add_command('configure', cfg_cmd)
        cmdlist.add_command('build', ['make'])
        cmdlist.add_command('check', ['make', 'check'])
        cmdlist.add_command('install', ['make', 'install'])
        cmdlist.cleanup_dir()
        cmdlist.pop_subdesc()

    def build_compilers(self, configs):
        """Build the compilers."""
        if not configs:
            self.remove_dirs(os.path.join(self.builddir, 'compilers'))
            self.remove_dirs(os.path.join(self.installdir, 'compilers'))
            self.remove_dirs(os.path.join(self.logsdir, 'compilers'))
            configs = sorted(self.configs.keys())
        for c in configs:
            self.configs[c].build()

    def build_glibcs(self, configs):
        """Build the glibcs."""
        if not configs:
            self.remove_dirs(os.path.join(self.builddir, 'glibcs'))
            self.remove_dirs(os.path.join(self.installdir, 'glibcs'))
            self.remove_dirs(os.path.join(self.logsdir, 'glibcs'))
            configs = sorted(self.glibc_configs.keys())
        for c in configs:
            self.glibc_configs[c].build()

    def load_versions_json(self):
        """Load information about source directory versions."""
        if not os.access(self.versions_json, os.F_OK):
            self.versions = {}
            return
        with open(self.versions_json, 'r') as f:
            self.versions = json.load(f)

    def store_json(self, data, filename):
        """Store information in a JSON file."""
        filename_tmp = filename + '.tmp'
        with open(filename_tmp, 'w') as f:
            json.dump(data, f, indent=2, sort_keys=True)
        os.rename(filename_tmp, filename)

    def store_versions_json(self):
        """Store information about source directory versions."""
        self.store_json(self.versions, self.versions_json)

    def set_component_version(self, component, version, explicit, revision):
        """Set the version information for a component."""
        self.versions[component] = {'version': version,
                                    'explicit': explicit,
                                    'revision': revision}
        self.store_versions_json()

    def checkout(self, versions):
        """Check out the desired component versions."""
        default_versions = {'binutils': 'vcs-2.30',
                            'gcc': 'vcs-7',
                            'glibc': 'vcs-mainline',
                            'gmp': '6.1.2',
                            'linux': '4.15',
                            'mpc': '1.1.0',
                            'mpfr': '4.0.0',
                            'mig': 'vcs-mainline',
                            'gnumach': 'vcs-mainline',
                            'hurd': 'vcs-mainline'}
        use_versions = {}
        explicit_versions = {}
        for v in versions:
            found_v = False
            for k in default_versions.keys():
                kx = k + '-'
                if v.startswith(kx):
                    vx = v[len(kx):]
                    if k in use_versions:
                        print('error: multiple versions for %s' % k)
                        exit(1)
                    use_versions[k] = vx
                    explicit_versions[k] = True
                    found_v = True
                    break
            if not found_v:
                print('error: unknown component in %s' % v)
                exit(1)
        for k in default_versions.keys():
            if k not in use_versions:
                if k in self.versions and self.versions[k]['explicit']:
                    use_versions[k] = self.versions[k]['version']
                    explicit_versions[k] = True
                else:
                    use_versions[k] = default_versions[k]
                    explicit_versions[k] = False
        os.makedirs(self.srcdir, exist_ok=True)
        for k in sorted(default_versions.keys()):
            update = os.access(self.component_srcdir(k), os.F_OK)
            v = use_versions[k]
            if (update and
                k in self.versions and
                v != self.versions[k]['version']):
                if not self.replace_sources:
                    print('error: version of %s has changed from %s to %s, '
                          'use --replace-sources to check out again' %
                          (k, self.versions[k]['version'], v))
                    exit(1)
                shutil.rmtree(self.component_srcdir(k))
                update = False
            if v.startswith('vcs-'):
                revision = self.checkout_vcs(k, v[4:], update)
            else:
                self.checkout_tar(k, v, update)
                revision = v
            self.set_component_version(k, v, explicit_versions[k], revision)
        if self.get_script_text() != self.script_text:
            # Rerun the checkout process in case the updated script
            # uses different default versions or new components.
            self.exec_self()

    def checkout_vcs(self, component, version, update):
        """Check out the given version of the given component from version
        control.  Return a revision identifier."""
        if component == 'binutils':
            git_url = 'git://sourceware.org/git/binutils-gdb.git'
            if version == 'mainline':
                git_branch = 'master'
            else:
                trans = str.maketrans({'.': '_'})
                git_branch = 'binutils-%s-branch' % version.translate(trans)
            return self.git_checkout(component, git_url, git_branch, update)
        elif component == 'gcc':
            if version == 'mainline':
                branch = 'trunk'
            else:
                trans = str.maketrans({'.': '_'})
                branch = 'branches/gcc-%s-branch' % version.translate(trans)
            svn_url = 'svn://gcc.gnu.org/svn/gcc/%s' % branch
            return self.gcc_checkout(svn_url, update)
        elif component == 'glibc':
            git_url = 'git://sourceware.org/git/glibc.git'
            if version == 'mainline':
                git_branch = 'master'
            else:
                git_branch = 'release/%s/master' % version
            r = self.git_checkout(component, git_url, git_branch, update)
            self.fix_glibc_timestamps()
            return r
        elif component == 'gnumach':
            git_url = 'git://git.savannah.gnu.org/hurd/gnumach.git'
            git_branch = 'master'
            r = self.git_checkout(component, git_url, git_branch, update)
            subprocess.run(['autoreconf', '-i'],
                           cwd=self.component_srcdir(component), check=True)
            return r
        elif component == 'mig':
            git_url = 'git://git.savannah.gnu.org/hurd/mig.git'
            git_branch = 'master'
            r = self.git_checkout(component, git_url, git_branch, update)
            subprocess.run(['autoreconf', '-i'],
                           cwd=self.component_srcdir(component), check=True)
            return r
        elif component == 'hurd':
            git_url = 'git://git.savannah.gnu.org/hurd/hurd.git'
            git_branch = 'master'
            r = self.git_checkout(component, git_url, git_branch, update)
            subprocess.run(['autoconf'],
                           cwd=self.component_srcdir(component), check=True)
            return r
        else:
            print('error: component %s coming from VCS' % component)
            exit(1)

    def git_checkout(self, component, git_url, git_branch, update):
        """Check out a component from git.  Return a commit identifier."""
        if update:
            subprocess.run(['git', 'remote', 'prune', 'origin'],
                           cwd=self.component_srcdir(component), check=True)
            if self.replace_sources:
                subprocess.run(['git', 'clean', '-dxfq'],
                               cwd=self.component_srcdir(component), check=True)
            subprocess.run(['git', 'pull', '-q'],
                           cwd=self.component_srcdir(component), check=True)
        else:
            subprocess.run(['git', 'clone', '-q', '-b', git_branch, git_url,
                            self.component_srcdir(component)], check=True)
        r = subprocess.run(['git', 'rev-parse', 'HEAD'],
                           cwd=self.component_srcdir(component),
                           stdout=subprocess.PIPE,
                           check=True, universal_newlines=True).stdout
        return r.rstrip()

    def fix_glibc_timestamps(self):
        """Fix timestamps in a glibc checkout."""
        # Ensure that builds do not try to regenerate generated files
        # in the source tree.
        srcdir = self.component_srcdir('glibc')
        for dirpath, dirnames, filenames in os.walk(srcdir):
            for f in filenames:
                if (f == 'configure' or
                    f == 'preconfigure' or
                    f.endswith('-kw.h')):
                    to_touch = os.path.join(dirpath, f)
                    subprocess.run(['touch', to_touch], check=True)

    def gcc_checkout(self, svn_url, update):
        """Check out GCC from SVN.  Return the revision number."""
        if not update:
            subprocess.run(['svn', 'co', '-q', svn_url,
                            self.component_srcdir('gcc')], check=True)
        subprocess.run(['contrib/gcc_update', '--silent'],
                       cwd=self.component_srcdir('gcc'), check=True)
        r = subprocess.run(['svnversion', self.component_srcdir('gcc')],
                           stdout=subprocess.PIPE,
                           check=True, universal_newlines=True).stdout
        return r.rstrip()

    def checkout_tar(self, component, version, update):
        """Check out the given version of the given component from a
        tarball."""
        if update:
            return
        url_map = {'binutils': 'https://ftp.gnu.org/gnu/binutils/binutils-%(version)s.tar.bz2',
                   'gcc': 'https://ftp.gnu.org/gnu/gcc/gcc-%(version)s/gcc-%(version)s.tar.bz2',
                   'gmp': 'https://ftp.gnu.org/gnu/gmp/gmp-%(version)s.tar.xz',
                   'linux': 'https://www.kernel.org/pub/linux/kernel/v4.x/linux-%(version)s.tar.xz',
                   'mpc': 'https://ftp.gnu.org/gnu/mpc/mpc-%(version)s.tar.gz',
                   'mpfr': 'https://ftp.gnu.org/gnu/mpfr/mpfr-%(version)s.tar.xz',
                   'mig': 'https://ftp.gnu.org/gnu/mig/mig-%(version)s.tar.bz2',
                   'gnumach': 'https://ftp.gnu.org/gnu/gnumach/gnumach-%(version)s.tar.bz2',
                   'hurd': 'https://ftp.gnu.org/gnu/hurd/hurd-%(version)s.tar.bz2'}
        if component not in url_map:
            print('error: component %s coming from tarball' % component)
            exit(1)
        url = url_map[component] % {'version': version}
        filename = os.path.join(self.srcdir, url.split('/')[-1])
        response = urllib.request.urlopen(url)
        data = response.read()
        with open(filename, 'wb') as f:
            f.write(data)
        subprocess.run(['tar', '-C', self.srcdir, '-x', '-f', filename],
                       check=True)
        os.rename(os.path.join(self.srcdir, '%s-%s' % (component, version)),
                  self.component_srcdir(component))
        os.remove(filename)

    def load_build_state_json(self):
        """Load information about the state of previous builds."""
        if os.access(self.build_state_json, os.F_OK):
            with open(self.build_state_json, 'r') as f:
                self.build_state = json.load(f)
        else:
            self.build_state = {}
        for k in ('host-libraries', 'compilers', 'glibcs'):
            if k not in self.build_state:
                self.build_state[k] = {}
            if 'build-time' not in self.build_state[k]:
                self.build_state[k]['build-time'] = ''
            if 'build-versions' not in self.build_state[k]:
                self.build_state[k]['build-versions'] = {}
            if 'build-results' not in self.build_state[k]:
                self.build_state[k]['build-results'] = {}
            if 'result-changes' not in self.build_state[k]:
                self.build_state[k]['result-changes'] = {}
            if 'ever-passed' not in self.build_state[k]:
                self.build_state[k]['ever-passed'] = []

    def store_build_state_json(self):
        """Store information about the state of previous builds."""
        self.store_json(self.build_state, self.build_state_json)

    def clear_last_build_state(self, action):
        """Clear information about the state of part of the build."""
        # We clear the last build time and versions when starting a
        # new build.  The results of the last build are kept around,
        # as comparison is still meaningful if this build is aborted
        # and a new one started.
        self.build_state[action]['build-time'] = ''
        self.build_state[action]['build-versions'] = {}
        self.store_build_state_json()

    def update_build_state(self, action, build_time, build_versions):
        """Update the build state after a build."""
        build_time = build_time.replace(microsecond=0)
        self.build_state[action]['build-time'] = str(build_time)
        self.build_state[action]['build-versions'] = build_versions
        build_results = {}
        for log in self.status_log_list:
            with open(log, 'r') as f:
                log_text = f.read()
            log_text = log_text.rstrip()
            m = re.fullmatch('([A-Z]+): (.*)', log_text)
            result = m.group(1)
            test_name = m.group(2)
            assert test_name not in build_results
            build_results[test_name] = result
        old_build_results = self.build_state[action]['build-results']
        self.build_state[action]['build-results'] = build_results
        result_changes = {}
        all_tests = set(old_build_results.keys()) | set(build_results.keys())
        for t in all_tests:
            if t in old_build_results:
                old_res = old_build_results[t]
            else:
                old_res = '(New test)'
            if t in build_results:
                new_res = build_results[t]
            else:
                new_res = '(Test removed)'
            if old_res != new_res:
                result_changes[t] = '%s -> %s' % (old_res, new_res)
        self.build_state[action]['result-changes'] = result_changes
        old_ever_passed = {t for t in self.build_state[action]['ever-passed']
                           if t in build_results}
        new_passes = {t for t in build_results if build_results[t] == 'PASS'}
        self.build_state[action]['ever-passed'] = sorted(old_ever_passed |
                                                         new_passes)
        self.store_build_state_json()

    def load_bot_config_json(self):
        """Load bot configuration."""
        with open(self.bot_config_json, 'r') as f:
            self.bot_config = json.load(f)

    def part_build_old(self, action, delay):
        """Return whether the last build for a given action was at least a
        given number of seconds ago, or does not have a time recorded."""
        old_time_str = self.build_state[action]['build-time']
        if not old_time_str:
            return True
        old_time = datetime.datetime.strptime(old_time_str,
                                              '%Y-%m-%d %H:%M:%S')
        new_time = datetime.datetime.utcnow()
        delta = new_time - old_time
        return delta.total_seconds() >= delay

    def bot_cycle(self):
        """Run a single round of checkout and builds."""
        print('Bot cycle starting %s.' % str(datetime.datetime.utcnow()))
        self.load_bot_config_json()
        actions = ('host-libraries', 'compilers', 'glibcs')
        self.bot_run_self(['--replace-sources'], 'checkout')
        self.load_versions_json()
        if self.get_script_text() != self.script_text:
            print('Script changed, re-execing.')
            # On script change, all parts of the build should be rerun.
            for a in actions:
                self.clear_last_build_state(a)
            self.exec_self()
        check_components = {'host-libraries': ('gmp', 'mpfr', 'mpc'),
                            'compilers': ('binutils', 'gcc', 'glibc', 'linux',
                                          'mig', 'gnumach', 'hurd'),
                            'glibcs': ('glibc',)}
        must_build = {}
        for a in actions:
            build_vers = self.build_state[a]['build-versions']
            must_build[a] = False
            if not self.build_state[a]['build-time']:
                must_build[a] = True
            old_vers = {}
            new_vers = {}
            for c in check_components[a]:
                if c in build_vers:
                    old_vers[c] = build_vers[c]
                new_vers[c] = {'version': self.versions[c]['version'],
                               'revision': self.versions[c]['revision']}
            if new_vers == old_vers:
                print('Versions for %s unchanged.' % a)
            else:
                print('Versions changed or rebuild forced for %s.' % a)
                if a == 'compilers' and not self.part_build_old(
                        a, self.bot_config['compilers-rebuild-delay']):
                    print('Not requiring rebuild of compilers this soon.')
                else:
                    must_build[a] = True
        if must_build['host-libraries']:
            must_build['compilers'] = True
        if must_build['compilers']:
            must_build['glibcs'] = True
        for a in actions:
            if must_build[a]:
                print('Must rebuild %s.' % a)
                self.clear_last_build_state(a)
            else:
                print('No need to rebuild %s.' % a)
        if os.access(self.logsdir, os.F_OK):
            shutil.rmtree(self.logsdir_old, ignore_errors=True)
            shutil.copytree(self.logsdir, self.logsdir_old)
        for a in actions:
            if must_build[a]:
                build_time = datetime.datetime.utcnow()
                print('Rebuilding %s at %s.' % (a, str(build_time)))
                self.bot_run_self([], a)
                self.load_build_state_json()
                self.bot_build_mail(a, build_time)
        print('Bot cycle done at %s.' % str(datetime.datetime.utcnow()))

    def bot_build_mail(self, action, build_time):
        """Send email with the results of a build."""
        if not ('email-from' in self.bot_config and
                'email-server' in self.bot_config and
                'email-subject' in self.bot_config and
                'email-to' in self.bot_config):
            if not self.email_warning:
                print("Email not configured, not sending.")
                self.email_warning = True
            return

        build_time = build_time.replace(microsecond=0)
        subject = (self.bot_config['email-subject'] %
                   {'action': action,
                    'build-time': str(build_time)})
        results = self.build_state[action]['build-results']
        changes = self.build_state[action]['result-changes']
        ever_passed = set(self.build_state[action]['ever-passed'])
        versions = self.build_state[action]['build-versions']
        new_regressions = {k for k in changes if changes[k] == 'PASS -> FAIL'}
        all_regressions = {k for k in ever_passed if results[k] == 'FAIL'}
        all_fails = {k for k in results if results[k] == 'FAIL'}
        if new_regressions:
            new_reg_list = sorted(['FAIL: %s' % k for k in new_regressions])
            new_reg_text = ('New regressions:\n\n%s\n\n' %
                            '\n'.join(new_reg_list))
        else:
            new_reg_text = ''
        if all_regressions:
            all_reg_list = sorted(['FAIL: %s' % k for k in all_regressions])
            all_reg_text = ('All regressions:\n\n%s\n\n' %
                            '\n'.join(all_reg_list))
        else:
            all_reg_text = ''
        if all_fails:
            all_fail_list = sorted(['FAIL: %s' % k for k in all_fails])
            all_fail_text = ('All failures:\n\n%s\n\n' %
                             '\n'.join(all_fail_list))
        else:
            all_fail_text = ''
        if changes:
            changes_list = sorted(changes.keys())
            changes_list = ['%s: %s' % (changes[k], k) for k in changes_list]
            changes_text = ('All changed results:\n\n%s\n\n' %
                            '\n'.join(changes_list))
        else:
            changes_text = ''
        results_text = (new_reg_text + all_reg_text + all_fail_text +
                        changes_text)
        if not results_text:
            results_text = 'Clean build with unchanged results.\n\n'
        versions_list = sorted(versions.keys())
        versions_list = ['%s: %s (%s)' % (k, versions[k]['version'],
                                          versions[k]['revision'])
                         for k in versions_list]
        versions_text = ('Component versions for this build:\n\n%s\n' %
                         '\n'.join(versions_list))
        body_text = results_text + versions_text
        msg = email.mime.text.MIMEText(body_text)
        msg['Subject'] = subject
        msg['From'] = self.bot_config['email-from']
        msg['To'] = self.bot_config['email-to']
        msg['Message-ID'] = email.utils.make_msgid()
        msg['Date'] = email.utils.format_datetime(datetime.datetime.utcnow())
        with smtplib.SMTP(self.bot_config['email-server']) as s:
            s.send_message(msg)

    def bot_run_self(self, opts, action, check=True):
        """Run a copy of this script with given options."""
        cmd = [sys.executable, sys.argv[0], '--keep=none',
               '-j%d' % self.parallelism]
        cmd.extend(opts)
        cmd.extend([self.topdir, action])
        sys.stdout.flush()
        subprocess.run(cmd, check=check)

    def bot(self):
        """Run repeated rounds of checkout and builds."""
        while True:
            self.load_bot_config_json()
            if not self.bot_config['run']:
                print('Bot exiting by request.')
                exit(0)
            self.bot_run_self([], 'bot-cycle', check=False)
            self.load_bot_config_json()
            if not self.bot_config['run']:
                print('Bot exiting by request.')
                exit(0)
            time.sleep(self.bot_config['delay'])
            if self.get_script_text() != self.script_text:
                print('Script changed, bot re-execing.')
                self.exec_self()


class Config(object):
    """A configuration for building a compiler and associated libraries."""

    def __init__(self, ctx, arch, os_name, variant=None, gcc_cfg=None,
                 first_gcc_cfg=None, glibcs=None, extra_glibcs=None):
        """Initialize a Config object."""
        self.ctx = ctx
        self.arch = arch
        self.os = os_name
        self.variant = variant
        if variant is None:
            self.name = '%s-%s' % (arch, os_name)
        else:
            self.name = '%s-%s-%s' % (arch, os_name, variant)
        self.triplet = '%s-glibc-%s' % (arch, os_name)
        if gcc_cfg is None:
            self.gcc_cfg = []
        else:
            self.gcc_cfg = gcc_cfg
        if first_gcc_cfg is None:
            self.first_gcc_cfg = []
        else:
            self.first_gcc_cfg = first_gcc_cfg
        if glibcs is None:
            glibcs = [{'variant': variant}]
        if extra_glibcs is None:
            extra_glibcs = []
        glibcs = [Glibc(self, **g) for g in glibcs]
        extra_glibcs = [Glibc(self, **g) for g in extra_glibcs]
        self.all_glibcs = glibcs + extra_glibcs
        self.compiler_glibcs = glibcs
        self.installdir = ctx.compiler_installdir(self.name)
        self.bindir = ctx.compiler_bindir(self.name)
        self.sysroot = ctx.compiler_sysroot(self.name)
        self.builddir = os.path.join(ctx.builddir, 'compilers', self.name)
        self.logsdir = os.path.join(ctx.logsdir, 'compilers', self.name)

    def component_builddir(self, component):
        """Return the directory to use for a (non-glibc) build."""
        return self.ctx.component_builddir('compilers', self.name, component)

    def build(self):
        """Generate commands to build this compiler."""
        self.ctx.remove_recreate_dirs(self.installdir, self.builddir,
                                      self.logsdir)
        cmdlist = CommandList('compilers-%s' % self.name, self.ctx.keep)
        cmdlist.add_command('check-host-libraries',
                            ['test', '-f',
                             os.path.join(self.ctx.host_libraries_installdir,
                                          'ok')])
        cmdlist.use_path(self.bindir)
        self.build_cross_tool(cmdlist, 'binutils', 'binutils',
                              ['--disable-gdb',
                               '--disable-libdecnumber',
                               '--disable-readline',
                               '--disable-sim'])
        if self.os.startswith('linux'):
            self.install_linux_headers(cmdlist)
        self.build_gcc(cmdlist, True)
        if self.os == 'gnu':
            self.install_gnumach_headers(cmdlist)
            self.build_cross_tool(cmdlist, 'mig', 'mig')
            self.install_hurd_headers(cmdlist)
        for g in self.compiler_glibcs:
            cmdlist.push_subdesc('glibc')
            cmdlist.push_subdesc(g.name)
            g.build_glibc(cmdlist, True)
            cmdlist.pop_subdesc()
            cmdlist.pop_subdesc()
        self.build_gcc(cmdlist, False)
        cmdlist.add_command('done', ['touch',
                                     os.path.join(self.installdir, 'ok')])
        self.ctx.add_makefile_cmdlist('compilers-%s' % self.name, cmdlist,
                                      self.logsdir)

    def build_cross_tool(self, cmdlist, tool_src, tool_build, extra_opts=None):
        """Build one cross tool."""
        srcdir = self.ctx.component_srcdir(tool_src)
        builddir = self.component_builddir(tool_build)
        cmdlist.push_subdesc(tool_build)
        cmdlist.create_use_dir(builddir)
        cfg_cmd = [os.path.join(srcdir, 'configure'),
                   '--prefix=%s' % self.installdir,
                   '--build=%s' % self.ctx.build_triplet,
                   '--host=%s' % self.ctx.build_triplet,
                   '--target=%s' % self.triplet,
                   '--with-sysroot=%s' % self.sysroot]
        if extra_opts:
            cfg_cmd.extend(extra_opts)
        cmdlist.add_command('configure', cfg_cmd)
        cmdlist.add_command('build', ['make'])
        # Parallel "make install" for GCC has race conditions that can
        # cause it to fail; see
        # <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42980>.  Such
        # problems are not known for binutils, but doing the
        # installation in parallel within a particular toolchain build
        # (as opposed to installation of one toolchain from
        # build-many-glibcs.py running in parallel to the installation
        # of other toolchains being built) is not known to be
        # significantly beneficial, so it is simplest just to disable
        # parallel install for cross tools here.
        cmdlist.add_command('install', ['make', '-j1', 'install'])
        cmdlist.cleanup_dir()
        cmdlist.pop_subdesc()

    def install_linux_headers(self, cmdlist):
        """Install Linux kernel headers."""
        arch_map = {'aarch64': 'arm64',
                    'alpha': 'alpha',
                    'arm': 'arm',
                    'hppa': 'parisc',
                    'i486': 'x86',
                    'i586': 'x86',
                    'i686': 'x86',
                    'i786': 'x86',
                    'ia64': 'ia64',
                    'm68k': 'm68k',
                    'microblaze': 'microblaze',
                    'mips': 'mips',
                    'nios2': 'nios2',
                    'powerpc': 'powerpc',
                    's390': 's390',
                    'riscv32': 'riscv',
                    'riscv64': 'riscv',
                    'sh': 'sh',
                    'sparc': 'sparc',
                    'tile': 'tile',
                    'x86_64': 'x86'}
        linux_arch = None
        for k in arch_map:
            if self.arch.startswith(k):
                linux_arch = arch_map[k]
                break
        assert linux_arch is not None
        srcdir = self.ctx.component_srcdir('linux')
        builddir = self.component_builddir('linux')
        headers_dir = os.path.join(self.sysroot, 'usr')
        cmdlist.push_subdesc('linux')
        cmdlist.create_use_dir(builddir)
        cmdlist.add_command('install-headers',
                            ['make', '-C', srcdir, 'O=%s' % builddir,
                             'ARCH=%s' % linux_arch,
                             'INSTALL_HDR_PATH=%s' % headers_dir,
                             'headers_install'])
        cmdlist.cleanup_dir()
        cmdlist.pop_subdesc()

    def install_gnumach_headers(self, cmdlist):
        """Install GNU Mach headers."""
        srcdir = self.ctx.component_srcdir('gnumach')
        builddir = self.component_builddir('gnumach')
        cmdlist.push_subdesc('gnumach')
        cmdlist.create_use_dir(builddir)
        cmdlist.add_command('configure',
                            [os.path.join(srcdir, 'configure'),
                             '--build=%s' % self.ctx.build_triplet,
                             '--host=%s' % self.triplet,
                             '--prefix=',
                             'CC=%s-gcc -nostdlib' % self.triplet])
        cmdlist.add_command('install', ['make', 'DESTDIR=%s' % self.sysroot,
                                        'install-data'])
        cmdlist.cleanup_dir()
        cmdlist.pop_subdesc()

    def install_hurd_headers(self, cmdlist):
        """Install Hurd headers."""
        srcdir = self.ctx.component_srcdir('hurd')
        builddir = self.component_builddir('hurd')
        cmdlist.push_subdesc('hurd')
        cmdlist.create_use_dir(builddir)
        cmdlist.add_command('configure',
                            [os.path.join(srcdir, 'configure'),
                             '--build=%s' % self.ctx.build_triplet,
                             '--host=%s' % self.triplet,
                             '--prefix=',
                             '--disable-profile', '--without-parted',
                             'CC=%s-gcc -nostdlib' % self.triplet])
        cmdlist.add_command('install', ['make', 'prefix=%s' % self.sysroot,
                                        'no_deps=t', 'install-headers'])
        cmdlist.cleanup_dir()
        cmdlist.pop_subdesc()

    def build_gcc(self, cmdlist, bootstrap):
        """Build GCC."""
        # libsanitizer commonly breaks because of glibc header
        # changes, or on unusual targets.  libssp is of little
        # relevance with glibc's own stack checking support.
        # libcilkrts does not support GNU/Hurd (and has been removed
        # in GCC 8, so --disable-libcilkrts can be removed once glibc
        # no longer supports building with older GCC versions).
        cfg_opts = list(self.gcc_cfg)
        cfg_opts += ['--disable-libsanitizer', '--disable-libssp',
                     '--disable-libcilkrts']
        host_libs = self.ctx.host_libraries_installdir
        cfg_opts += ['--with-gmp=%s' % host_libs,
                     '--with-mpfr=%s' % host_libs,
                     '--with-mpc=%s' % host_libs]
        if bootstrap:
            tool_build = 'gcc-first'
            # Building a static-only, C-only compiler that is
            # sufficient to build glibc.  Various libraries and
            # features that may require libc headers must be disabled.
            # When configuring with a sysroot, --with-newlib is
            # required to define inhibit_libc (to stop some parts of
            # libgcc including libc headers); --without-headers is not
            # sufficient.
            cfg_opts += ['--enable-languages=c', '--disable-shared',
                         '--disable-threads',
                         '--disable-libatomic',
                         '--disable-decimal-float',
                         '--disable-libffi',
                         '--disable-libgomp',
                         '--disable-libitm',
                         '--disable-libmpx',
                         '--disable-libquadmath',
                         '--without-headers', '--with-newlib',
                         '--with-glibc-version=%s' % self.ctx.glibc_version
                         ]
            cfg_opts += self.first_gcc_cfg
        else:
            tool_build = 'gcc'
            cfg_opts += ['--enable-languages=c,c++', '--enable-shared',
                         '--enable-threads']
        self.build_cross_tool(cmdlist, 'gcc', tool_build, cfg_opts)


class Glibc(object):
    """A configuration for building glibc."""

    def __init__(self, compiler, arch=None, os_name=None, variant=None,
                 cfg=None, ccopts=None):
        """Initialize a Glibc object."""
        self.ctx = compiler.ctx
        self.compiler = compiler
        if arch is None:
            self.arch = compiler.arch
        else:
            self.arch = arch
        if os_name is None:
            self.os = compiler.os
        else:
            self.os = os_name
        self.variant = variant
        if variant is None:
            self.name = '%s-%s' % (self.arch, self.os)
        else:
            self.name = '%s-%s-%s' % (self.arch, self.os, variant)
        self.triplet = '%s-glibc-%s' % (self.arch, self.os)
        if cfg is None:
            self.cfg = []
        else:
            self.cfg = cfg
        self.ccopts = ccopts

    def tool_name(self, tool):
        """Return the name of a cross-compilation tool."""
        ctool = '%s-%s' % (self.compiler.triplet, tool)
        if self.ccopts and (tool == 'gcc' or tool == 'g++'):
            ctool = '%s %s' % (ctool, self.ccopts)
        return ctool

    def build(self):
        """Generate commands to build this glibc."""
        builddir = self.ctx.component_builddir('glibcs', self.name, 'glibc')
        installdir = self.ctx.glibc_installdir(self.name)
        logsdir = os.path.join(self.ctx.logsdir, 'glibcs', self.name)
        self.ctx.remove_recreate_dirs(installdir, builddir, logsdir)
        cmdlist = CommandList('glibcs-%s' % self.name, self.ctx.keep)
        cmdlist.add_command('check-compilers',
                            ['test', '-f',
                             os.path.join(self.compiler.installdir, 'ok')])
        cmdlist.use_path(self.compiler.bindir)
        self.build_glibc(cmdlist, False)
        self.ctx.add_makefile_cmdlist('glibcs-%s' % self.name, cmdlist,
                                      logsdir)

    def build_glibc(self, cmdlist, for_compiler):
        """Generate commands to build this glibc, either as part of a compiler
        build or with the bootstrapped compiler (and in the latter case, run
        tests as well)."""
        srcdir = self.ctx.component_srcdir('glibc')
        if for_compiler:
            builddir = self.ctx.component_builddir('compilers',
                                                   self.compiler.name, 'glibc',
                                                   self.name)
            installdir = self.compiler.sysroot
            srcdir_copy = self.ctx.component_builddir('compilers',
                                                      self.compiler.name,
                                                      'glibc-src',
                                                      self.name)
        else:
            builddir = self.ctx.component_builddir('glibcs', self.name,
                                                   'glibc')
            installdir = self.ctx.glibc_installdir(self.name)
            srcdir_copy = self.ctx.component_builddir('glibcs', self.name,
                                                      'glibc-src')
        cmdlist.create_use_dir(builddir)
        # glibc builds write into the source directory, and even if
        # not intentionally there is a risk of bugs that involve
        # writing into the working directory.  To avoid possible
        # concurrency issues, copy the source directory.
        cmdlist.create_copy_dir(srcdir, srcdir_copy)
        use_usr = self.os != 'gnu'
        prefix = '/usr' if use_usr else ''
        cfg_cmd = [os.path.join(srcdir_copy, 'configure'),
                   '--prefix=%s' % prefix,
                   '--enable-profile',
                   '--build=%s' % self.ctx.build_triplet,
                   '--host=%s' % self.triplet,
                   'CC=%s' % self.tool_name('gcc'),
                   'CXX=%s' % self.tool_name('g++'),
                   'AR=%s' % self.tool_name('ar'),
                   'AS=%s' % self.tool_name('as'),
                   'LD=%s' % self.tool_name('ld'),
                   'NM=%s' % self.tool_name('nm'),
                   'OBJCOPY=%s' % self.tool_name('objcopy'),
                   'OBJDUMP=%s' % self.tool_name('objdump'),
                   'RANLIB=%s' % self.tool_name('ranlib'),
                   'READELF=%s' % self.tool_name('readelf'),
                   'STRIP=%s' % self.tool_name('strip')]
        if self.os == 'gnu':
            cfg_cmd += ['MIG=%s' % self.tool_name('mig')]
        cfg_cmd += self.cfg
        cmdlist.add_command('configure', cfg_cmd)
        cmdlist.add_command('build', ['make'])
        cmdlist.add_command('install', ['make', 'install',
                                        'install_root=%s' % installdir])
        # GCC uses paths such as lib/../lib64, so make sure lib
        # directories always exist.
        mkdir_cmd = ['mkdir', '-p',
                     os.path.join(installdir, 'lib')]
        if use_usr:
            mkdir_cmd += [os.path.join(installdir, 'usr', 'lib')]
        cmdlist.add_command('mkdir-lib', mkdir_cmd)
        if not for_compiler:
            if self.ctx.strip:
                cmdlist.add_command('strip',
                                    ['sh', '-c',
                                     ('%s $(find %s/lib* -name "*.so")' %
                                      (self.tool_name('strip'), installdir))])
            cmdlist.add_command('check', ['make', 'check'])
            cmdlist.add_command('save-logs', [self.ctx.save_logs],
                                always_run=True)
        cmdlist.cleanup_dir('cleanup-src', srcdir_copy)
        cmdlist.cleanup_dir()


class Command(object):
    """A command run in the build process."""

    def __init__(self, desc, num, dir, path, command, always_run=False):
        """Initialize a Command object."""
        self.dir = dir
        self.path = path
        self.desc = desc
        trans = str.maketrans({' ': '-'})
        self.logbase = '%03d-%s' % (num, desc.translate(trans))
        self.command = command
        self.always_run = always_run

    @staticmethod
    def shell_make_quote_string(s):
        """Given a string not containing a newline, quote it for use by the
        shell and make."""
        assert '\n' not in s
        if re.fullmatch('[]+,./0-9@A-Z_a-z-]+', s):
            return s
        strans = str.maketrans({"'": "'\\''"})
        s = "'%s'" % s.translate(strans)
        mtrans = str.maketrans({'$': '$$'})
        return s.translate(mtrans)

    @staticmethod
    def shell_make_quote_list(l, translate_make):
        """Given a list of strings not containing newlines, quote them for use
        by the shell and make, returning a single string.  If translate_make
        is true and the first string is 'make', change it to $(MAKE)."""
        l = [Command.shell_make_quote_string(s) for s in l]
        if translate_make and l[0] == 'make':
            l[0] = '$(MAKE)'
        return ' '.join(l)

    def shell_make_quote(self):
        """Return this command quoted for the shell and make."""
        return self.shell_make_quote_list(self.command, True)


class CommandList(object):
    """A list of commands run in the build process."""

    def __init__(self, desc, keep):
        """Initialize a CommandList object."""
        self.cmdlist = []
        self.dir = None
        self.path = None
        self.desc = [desc]
        self.keep = keep

    def desc_txt(self, desc):
        """Return the description to use for a command."""
        return '%s %s' % (' '.join(self.desc), desc)

    def use_dir(self, dir):
        """Set the default directory for subsequent commands."""
        self.dir = dir

    def use_path(self, path):
        """Set a directory to be prepended to the PATH for subsequent
        commands."""
        self.path = path

    def push_subdesc(self, subdesc):
        """Set the default subdescription for subsequent commands (e.g., the
        name of a component being built, within the series of commands
        building it)."""
        self.desc.append(subdesc)

    def pop_subdesc(self):
        """Pop a subdescription from the list of descriptions."""
        self.desc.pop()

    def create_use_dir(self, dir):
        """Remove and recreate a directory and use it for subsequent
        commands."""
        self.add_command_dir('rm', None, ['rm', '-rf', dir])
        self.add_command_dir('mkdir', None, ['mkdir', '-p', dir])
        self.use_dir(dir)

    def create_copy_dir(self, src, dest):
        """Remove a directory and recreate it as a copy from the given
        source."""
        self.add_command_dir('copy-rm', None, ['rm', '-rf', dest])
        parent = os.path.dirname(dest)
        self.add_command_dir('copy-mkdir', None, ['mkdir', '-p', parent])
        self.add_command_dir('copy', None, ['cp', '-a', src, dest])

    def add_command_dir(self, desc, dir, command, always_run=False):
        """Add a command to run in a given directory."""
        cmd = Command(self.desc_txt(desc), len(self.cmdlist), dir, self.path,
                      command, always_run)
        self.cmdlist.append(cmd)

    def add_command(self, desc, command, always_run=False):
        """Add a command to run in the default directory."""
        cmd = Command(self.desc_txt(desc), len(self.cmdlist), self.dir,
                      self.path, command, always_run)
        self.cmdlist.append(cmd)

    def cleanup_dir(self, desc='cleanup', dir=None):
        """Clean up a build directory.  If no directory is specified, the
        default directory is cleaned up and ceases to be the default
        directory."""
        if dir is None:
            dir = self.dir
            self.use_dir(None)
        if self.keep != 'all':
            self.add_command_dir(desc, None, ['rm', '-rf', dir],
                                 always_run=(self.keep == 'none'))

    def makefile_commands(self, wrapper, logsdir):
        """Return the sequence of commands in the form of text for a Makefile.
        The given wrapper script takes arguments: base of logs for
        previous command, or empty; base of logs for this command;
        description; directory; PATH addition; the command itself."""
        # prev_base is the base of the name for logs of the previous
        # command that is not always-run (that is, a build command,
        # whose failure should stop subsequent build commands from
        # being run, as opposed to a cleanup command, which is run
        # even if previous commands failed).
        prev_base = ''
        cmds = []
        for c in self.cmdlist:
            ctxt = c.shell_make_quote()
            if prev_base and not c.always_run:
                prev_log = os.path.join(logsdir, prev_base)
            else:
                prev_log = ''
            this_log = os.path.join(logsdir, c.logbase)
            if not c.always_run:
                prev_base = c.logbase
            if c.dir is None:
                dir = ''
            else:
                dir = c.dir
            if c.path is None:
                path = ''
            else:
                path = c.path
            prelims = [wrapper, prev_log, this_log, c.desc, dir, path]
            prelim_txt = Command.shell_make_quote_list(prelims, False)
            cmds.append('\t@%s %s' % (prelim_txt, ctxt))
        return '\n'.join(cmds)

    def status_logs(self, logsdir):
        """Return the list of log files with command status."""
        return [os.path.join(logsdir, '%s-status.txt' % c.logbase)
                for c in self.cmdlist]


def get_parser():
    """Return an argument parser for this module."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-j', dest='parallelism',
                        help='Run this number of jobs in parallel',
                        type=int, default=os.cpu_count())
    parser.add_argument('--keep', dest='keep',
                        help='Whether to keep all build directories, '
                        'none or only those from failed builds',
                        default='none', choices=('none', 'all', 'failed'))
    parser.add_argument('--replace-sources', action='store_true',
                        help='Remove and replace source directories '
                        'with the wrong version of a component')
    parser.add_argument('--strip', action='store_true',
                        help='Strip installed glibc libraries')
    parser.add_argument('topdir',
                        help='Toplevel working directory')
    parser.add_argument('action',
                        help='What to do',
                        choices=('checkout', 'bot-cycle', 'bot',
                                 'host-libraries', 'compilers', 'glibcs'))
    parser.add_argument('configs',
                        help='Versions to check out or configurations to build',
                        nargs='*')
    return parser


def main(argv):
    """The main entry point."""
    parser = get_parser()
    opts = parser.parse_args(argv)
    topdir = os.path.abspath(opts.topdir)
    ctx = Context(topdir, opts.parallelism, opts.keep, opts.replace_sources,
                  opts.strip, opts.action)
    ctx.run_builds(opts.action, opts.configs)


if __name__ == '__main__':
    main(sys.argv[1:])
