aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/build-many-glibcs.py1142
1 files changed, 1142 insertions, 0 deletions
diff --git a/scripts/build-many-glibcs.py b/scripts/build-many-glibcs.py
new file mode 100755
index 0000000000..4b4e15ca0b
--- /dev/null
+++ b/scripts/build-many-glibcs.py
@@ -0,0 +1,1142 @@
+#!/usr/bin/python3
+# Build many configurations of glibc.
+# Copyright (C) 2016 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, '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', name
+configurations for which compilers or glibc are to be built.
+"""
+
+import argparse
+import os
+import os.path
+import re
+import shutil
+import stat
+import subprocess
+import sys
+import urllib.request
+
+
+class Context:
+
+ """The global state associated with builds in a given directory."""
+
+ def __init__(self, topdir, parallelism, keep, action):
+ """Initialize the context."""
+ self.topdir = topdir
+ self.parallelism = parallelism
+ self.keep = keep
+ self.srcdir = os.path.join(topdir, 'src')
+ 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.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')
+ 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()
+
+ 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')
+ 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')
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabihf')
+ self.add_config(arch='armeb',
+ os_name='linux-gnueabihf',
+ variant='be8',
+ gcc_cfg=['--with-arch=armv7-a'])
+ self.add_config(arch='hppa',
+ os_name='linux-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='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',
+ 'cfg': ['--without-fp']},
+ {'variant': 'soft',
+ 'arch': 'mips',
+ 'ccopts': '-mabi=32',
+ 'cfg': ['--without-fp']},
+ {'variant': 'n64-soft',
+ 'ccopts': '-mabi=64',
+ 'cfg': ['--without-fp']}])
+ 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',
+ 'cfg': ['--without-fp']},
+ {'variant': 'nan2008-soft',
+ 'arch': 'mips',
+ 'ccopts': '-mabi=32',
+ 'cfg': ['--without-fp']},
+ {'variant': 'n64-nan2008-soft',
+ 'ccopts': '-mabi=64',
+ 'cfg': ['--without-fp']}])
+ 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',
+ 'cfg': ['--without-fp']},
+ {'variant': 'soft',
+ 'arch': 'mipsel',
+ 'ccopts': '-mabi=32',
+ 'cfg': ['--without-fp']},
+ {'variant': 'n64-soft',
+ 'ccopts': '-mabi=64',
+ 'cfg': ['--without-fp']}])
+ 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',
+ 'cfg': ['--without-fp']},
+ {'variant': 'nan2008-soft',
+ 'arch': 'mipsel',
+ 'ccopts': '-mabi=32',
+ 'cfg': ['--without-fp']},
+ {'variant': 'n64-nan2008-soft',
+ 'ccopts': '-mabi=64',
+ 'cfg': ['--without-fp']}])
+ self.add_config(arch='nios2',
+ os_name='linux-gnu')
+ self.add_config(arch='powerpc',
+ os_name='linux-gnu',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt'])
+ self.add_config(arch='powerpc',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--disable-multilib', '--with-float=soft',
+ '--enable-secureplt'],
+ glibcs=[{'variant': 'soft', 'cfg': ['--without-fp']}])
+ 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'],
+ glibcs=[{'cfg': ['--without-fp']}])
+ self.add_config(arch='powerpc',
+ os_name='linux-gnuspe',
+ variant='e500v1',
+ gcc_cfg=['--disable-multilib', '--enable-secureplt'],
+ glibcs=[{'variant': 'e500v1', 'cfg': ['--without-fp']}])
+ self.add_config(arch='s390x',
+ os_name='linux-gnu',
+ glibcs=[{},
+ {'arch': 's390', 'ccopts': '-m31'}])
+ # SH is missing __builtin_trap support, so work around this;
+ # see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70216>.
+ no_isolate = ('-fno-isolate-erroneous-paths-dereference'
+ ' -fno-isolate-erroneous-paths-attribute')
+ self.add_config(arch='sh3',
+ os_name='linux-gnu',
+ glibcs=[{'ccopts': no_isolate}])
+ self.add_config(arch='sh3eb',
+ os_name='linux-gnu',
+ glibcs=[{'ccopts': no_isolate}])
+ self.add_config(arch='sh4',
+ os_name='linux-gnu',
+ glibcs=[{'ccopts': no_isolate}])
+ self.add_config(arch='sh4eb',
+ os_name='linux-gnu',
+ glibcs=[{'ccopts': no_isolate}])
+ self.add_config(arch='sh4',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--without-fp'],
+ glibcs=[{'variant': 'soft',
+ 'cfg': ['--without-fp'],
+ 'ccopts': no_isolate}])
+ self.add_config(arch='sh4eb',
+ os_name='linux-gnu',
+ variant='soft',
+ gcc_cfg=['--without-fp'],
+ glibcs=[{'variant': 'soft',
+ 'cfg': ['--without-fp'],
+ 'ccopts': no_isolate}])
+ self.add_config(arch='sparc64',
+ os_name='linux-gnu',
+ glibcs=[{},
+ {'arch': 'sparcv9',
+ 'ccopts': '-m32 -mlong-double-128'}])
+ 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='tilepro',
+ os_name='linux-gnu')
+ 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': '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
+ elif action == 'host-libraries':
+ if configs:
+ print('error: configurations specified for host-libraries')
+ exit(1)
+ self.build_host_libraries()
+ elif action == 'compilers':
+ self.build_compilers(configs)
+ else:
+ self.build_glibcs(configs)
+ self.write_files()
+ self.do_build()
+
+ @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))
+
+ 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'
+ 'echo "Command: $*" >> "$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)
+ os.chmod(self.wrapper,
+ (stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|
+ stat.S_IROTH|stat.S_IXOTH))
+ 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,
+ (stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|
+ stat.S_IROTH|stat.S_IXOTH))
+
+ 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 checkout(self, versions):
+ """Check out the desired component versions."""
+ default_versions = {'binutils': 'vcs-2.27',
+ 'gcc': 'vcs-6',
+ 'glibc': 'vcs-mainline',
+ 'gmp': '6.1.1',
+ 'linux': '4.8.6',
+ 'mpc': '1.0.3',
+ 'mpfr': '3.1.5'}
+ use_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
+ 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:
+ use_versions[k] = default_versions[k]
+ 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 v.startswith('vcs-'):
+ self.checkout_vcs(k, v[4:], update)
+ else:
+ self.checkout_tar(k, v, update)
+
+ def checkout_vcs(self, component, version, update):
+ """Check out the given version of the given component from version
+ control."""
+ if component == 'binutils':
+ git_url = 'git://sourceware.org/git/binutils-gdb.git'<