2 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Recipes for NativeClient toolchain packages.
8 The real entry plumbing is in toolchain_main.py.
21 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
22 NACL_DIR = os.path.dirname(SCRIPT_DIR)
25 'binutils': '38dbda270a4248ab5b7facc012b9c8d8527f6fb2',
26 'gcc': '145a627d95b98f54915d037dddbcbb0f7b283494',
27 'newlib': 'cc9ce45891a45ecfbc671f4a6f1b06ba60a55ad9',
31 'gmp': command.path.join('gmp', 'gmp-5.1.3.tar.bz2'),
32 'mpfr': command.path.join('mpfr', 'mpfr-3.1.2.tar.bz2'),
33 'mpc': command.path.join('mpc', 'mpc-1.0.2.tar.gz'),
34 'isl': command.path.join('cloog', 'isl-0.12.1.tar.bz2'),
35 'cloog': command.path.join('cloog', 'cloog-0.18.1.tar.gz'),
38 GIT_BASE_URL = 'https://chromium.googlesource.com/native_client'
44 for package in TAR_FILES:
45 tar_file = TAR_FILES[package]
46 if fnmatch.fnmatch(tar_file, '*.bz2'):
47 extract = EXTRACT_STRIP_TBZ2
48 elif fnmatch.fnmatch(tar_file, '*.gz'):
49 extract = EXTRACT_STRIP_TGZ
51 raise Exception('unexpected file name pattern in TAR_FILES[%r]' % package)
55 command.Command(extract + [command.path.join('%(abs_top_srcdir)s',
62 for package in GIT_REVISIONS:
66 command.SyncGitRepo('%s/nacl-%s.git' % (GIT_BASE_URL, package),
67 '%(output)s', GIT_REVISIONS[package])
71 # The gcc_libs component gets the whole GCC source tree.
72 sources['gcc_libs'] = sources['gcc']
74 # The gcc component omits all the source directories that are used solely
75 # for building target libraries. We don't want those included in the
76 # input hash calculation so that we don't rebuild the compiler when the
77 # the only things that have changed are target libraries.
80 'dependencies': ['gcc_libs'],
81 'commands': [command.CopyTree('%(gcc_libs)s', '%(output)s', [
101 # We have to populate the newlib source tree with the "exported" form of
102 # some headers from the native_client source tree. The newlib build
103 # needs these to be in the expected place. By doing this in the source
104 # target, these files will be part of the input hash and so we don't need
105 # to do anything else to keep track of when they might have changed in
106 # the native_client source tree.
107 newlib_sys_nacl = command.path.join('%(output)s',
108 'newlib', 'libc', 'sys', 'nacl')
109 newlib_unpack = [command.RemoveDirectory(command.path.join(newlib_sys_nacl,
111 for dirname in ['bits', 'sys', 'machine']]
112 newlib_unpack.append(command.Command([
114 command.path.join('%(top_srcdir)s', 'src',
115 'trusted', 'service_runtime', 'export_header.py'),
116 command.path.join('%(top_srcdir)s', 'src',
117 'trusted', 'service_runtime', 'include'),
120 sources['newlib']['commands'] += newlib_unpack
125 # Map of native host tuple to extra tuples that it cross-builds for.
128 'arm-linux-gnueabihf',
129 # TODO(mcgrathr): Enable this if the binaries are proven to
130 # actually work, and bots get needed mingw* packages installed.
135 # The list of targets to build toolchains for.
136 TARGET_LIST = ['arm', 'i686']
138 # These are extra arguments to pass gcc's configure that vary by target.
139 TARGET_GCC_CONFIG = {
140 # TODO(mcgrathr): Disabled tuning for now, tickling a constant-pool layout bug.
141 # 'arm': ['--with-tune=cortex-a15'],
144 PACKAGE_NAME = 'Native Client SDK [%(build_signature)s]'
145 BUG_URL = 'http://gonacl.com/reportissue'
147 TAR_XV = ['tar', '-x', '-v']
148 EXTRACT_STRIP_TGZ = TAR_XV + ['--gzip', '--strip-components=1', '-f']
149 EXTRACT_STRIP_TBZ2 = TAR_XV + ['--bzip2', '--strip-components=1', '-f']
150 CONFIGURE_CMD = ['sh', '%(src)s/configure']
151 MAKE_PARALLEL_CMD = ['make', '-j%(cores)s']
152 MAKE_CHECK_CMD = MAKE_PARALLEL_CMD + ['check']
153 MAKE_DESTDIR_CMD = ['make', 'DESTDIR=%(abs_output)s']
155 # This file gets installed by multiple packages' install steps, but it is
156 # never useful when installed in isolation. So we remove it from the
157 # installation directories before packaging up.
158 REMOVE_INFO_DIR = command.Remove(command.path.join('%(output)s',
159 'share', 'info', 'dir'))
161 def ConfigureHostArch(host):
164 native, extra_cc_args = NativeTuple()
165 is_cross = host != native
169 configure_args.append('--host=' + host)
171 # The host we've chosen is "native enough", such as x86-32 on x86-64.
172 # But it's not what config.guess will yield, so we need to supply
173 # a --build switch to ensure things build correctly.
174 configure_args.append('--build=' + host)
176 extra_cxx_args = list(extra_cc_args)
177 if fnmatch.fnmatch(host, '*-linux*'):
178 # Avoid shipping binaries with a runtime dependency on
179 # a particular version of the libstdc++ shared library.
180 # TODO(mcgrathr): Do we want this for MinGW and/or Mac too?
181 extra_cxx_args.append('-static-libstdc++')
184 # These are the defaults when there is no setting, but we will add
185 # additional switches, so we must supply the command name too.
190 configure_args.append('CC=' + ' '.join([cc] + extra_cc_args))
193 # These are the defaults when there is no setting, but we will add
194 # additional switches, so we must supply the command name too.
199 configure_args.append('CXX=' + ' '.join([cxx] + extra_cxx_args))
201 if HostIsWindows(host):
202 # The i18n support brings in runtime dependencies on MinGW DLLs
203 # that we don't want to have to distribute alongside our binaries.
204 # So just disable it, and compiler messages will always be in US English.
205 configure_args.append('--disable-nls')
207 return configure_args
210 def ConfigureHostCommon(host):
211 return ConfigureHostArch(host) + [
213 '--disable-silent-rules',
214 '--without-gcc-arch',
218 def ConfigureHostLib(host):
219 return ConfigureHostCommon(host) + [
224 def ConfigureHostTool(host):
225 return ConfigureHostCommon(host) + [
226 '--with-pkgversion=' + PACKAGE_NAME,
227 '--with-bugurl=' + BUG_URL,
232 def MakeCommand(host, extra_args=[]):
233 if HostIsWindows(host):
234 # There appears to be nothing we can pass at top-level configure time
235 # that will prevent the configure scripts from finding MinGW's libiconv
236 # and using it. We have to force this variable into the environment
237 # of the sub-configure runs, which are run via make.
238 make_command = MAKE_PARALLEL_CMD + ['HAVE_LIBICONV=no']
240 make_command = MAKE_PARALLEL_CMD
241 return make_command + extra_args
244 # Return the 'make check' command to run.
245 # When cross-compiling, don't try to run test suites.
246 def MakeCheckCommand(host):
247 native, _ = NativeTuple()
250 return MAKE_CHECK_CMD
253 def InstallDocFiles(subdir, files):
254 doc_dir = command.path.join('%(output)s', 'share', 'doc', subdir)
255 dirs = sorted(set([command.path.dirname(command.path.join(doc_dir, file))
257 commands = ([command.Mkdir(dir, parents=True) for dir in dirs] +
258 [command.Copy(command.path.join('%(' + subdir + ')s', file),
259 command.path.join(doc_dir, file))
264 def NewlibLibcScript(arch):
266 * This is a linker script that gets installed as libc.a for the
267 * newlib-based NaCl toolchain. It brings in the constituent
268 * libraries that make up what -lc means semantically.
271 GROUP ( libcrt_common.a libnacl.a )
274 # Listing three formats instead of one makes -EL/-EB switches work
275 # for the endian-switchable ARM backend.
276 format_list = ['elf32-littlearm-nacl',
278 'elf32-littlearm-nacl']
280 format_list = 'elf32-i386-nacl'
281 elif arch == 'x86_64':
282 format_list = 'elf32-x86_64-nacl'
284 raise Exception('TODO(mcgrathr): OUTPUT_FORMAT for %s' % arch)
285 return template % ', '.join(['"' + fmt + '"' for fmt in format_list])
288 # The default strip behavior removes debugging and symbol table
289 # sections, but it leaves the .comment section. This contains the
290 # compiler version string, and so it changes when the compiler changes
291 # even if the actual machine code it produces is completely identical.
292 # Hence, the target library packages will always change when the
293 # compiler changes unless these sections are removed. Doing this
294 # requires somehow teaching the makefile rules to pass the
295 # --remove-section=.comment switch to TARGET-strip. For the GCC
296 # target libraries, setting STRIP_FOR_TARGET is sufficient. But
297 # quoting nightmares make it difficult to pass a command with a space
298 # in it as the STRIP_FOR_TARGET value. So the build writes a little
299 # script that can be invoked with a simple name.
301 # Though the gcc target libraries' makefiles are smart enough to obey
302 # STRIP_FOR_TARGET for library files, the newlib makefiles just
303 # blindly use $(INSTALL_DATA) for both header (text) files and library
304 # files. Hence it's necessary to override its INSTALL_DATA setting to
305 # one that will do stripping using this script, and thus the script
306 # must silently do nothing to non-binary files.
307 def ConfigureTargetPrep(arch):
308 script_file = 'strip_for_target'
310 config_target = arch + '-nacl'
311 script_contents = """\
318 type=`file --brief --mime-type "$arg"`
320 application/x-executable|application/x-sharedlib) ;;
321 application/x-archive|application/x-object) mode=--strip-debug ;;
327 exec %s-strip $mode --remove-section=.comment "$@"
331 command.WriteData(script_contents, script_file),
332 command.Command(['chmod', '+x', script_file]),
336 def ConfigureTargetArgs(arch):
337 config_target = arch + '-nacl'
339 '--target=' + config_target,
340 '--with-sysroot=/' + config_target,
341 'STRIP_FOR_TARGET=%(cwd)s/strip_for_target',
345 def CommandsInBuild(command_lines):
347 command.RemoveDirectory('build'),
348 command.Mkdir('build'),
349 ] + [command.Command(cmd, cwd='build')
350 for cmd in command_lines]
353 def PopulateDeps(dep_dirs):
354 commands = [command.RemoveDirectory('all_deps'),
355 command.Mkdir('all_deps')]
356 commands += [command.Command('cp -r "%s/"* all_deps' % dirname, shell=True)
357 for dirname in dep_dirs]
361 def WithDepsOptions(options, component=None):
362 if component is None:
363 directory = command.path.join('%(cwd)s', 'all_deps')
365 directory = '%(abs_' + component + ')s'
366 return ['--with-' + option + '=' + directory
367 for option in options]
370 # Return the component name we'll use for a base component name and
371 # a host tuple. The component names cannot contain dashes or other
372 # non-identifier characters, because the names of the files uploaded
373 # to Google Storage are constrained. GNU configuration tuples contain
374 # dashes, which we translate to underscores.
375 def ForHost(component_name, host):
376 return component_name + '_' + gsd_storage.LegalizeName(host)
379 # These are libraries that go into building the compiler itself.
380 def HostGccLibs(host):
381 def H(component_name):
382 return ForHost(component_name, host)
386 'dependencies': ['gmp'],
388 command.Command(ConfigureCommand('gmp') +
389 ConfigureHostLib(host) + [
390 '--with-sysroot=%(abs_output)s',
392 # Without this, the built library will
393 # assume the instruction set details
394 # available on the build machine. With
395 # this, it dynamically chooses what code
396 # to use based on the details of the
397 # actual host CPU at runtime.
400 command.Command(MakeCommand(host)),
401 command.Command(MakeCheckCommand(host)),
402 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
407 'dependencies': ['mpfr', H('gmp')],
409 command.Command(ConfigureCommand('mpfr') +
410 ConfigureHostLib(host) +
411 WithDepsOptions(['sysroot', 'gmp'], H('gmp'))),
412 command.Command(MakeCommand(host)),
413 command.Command(MakeCheckCommand(host)),
414 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
419 'dependencies': ['mpc', H('gmp'), H('mpfr')],
420 'commands': PopulateDeps(['%(' + H('gmp') + ')s',
421 '%(' + H('mpfr') + ')s']) + [
422 command.Command(ConfigureCommand('mpc') +
423 ConfigureHostLib(host) +
424 WithDepsOptions(['sysroot', 'gmp', 'mpfr'])),
425 command.Command(MakeCommand(host)),
426 command.Command(MakeCheckCommand(host)),
427 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
432 'dependencies': ['isl', H('gmp')],
434 command.Command(ConfigureCommand('isl') +
435 ConfigureHostLib(host) +
436 WithDepsOptions(['sysroot', 'gmp-prefix'],
438 command.Command(MakeCommand(host)),
439 command.Command(MakeCheckCommand(host)),
440 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
441 # The .pc files wind up containing some absolute paths
442 # that make the output depend on the build directory name.
443 # The dependents' configure scripts don't need them anyway.
444 command.RemoveDirectory(command.path.join(
445 '%(output)s', 'lib', 'pkgconfig')),
450 'dependencies': ['cloog', H('gmp'), H('isl')],
451 'commands': PopulateDeps(['%(' + H('gmp') + ')s',
452 '%(' + H('isl') + ')s']) + [
453 command.Command(ConfigureCommand('cloog') +
454 ConfigureHostLib(host) + [
457 ] + WithDepsOptions(['sysroot',
460 command.Command(MakeCommand(host)),
461 command.Command(MakeCheckCommand(host)),
462 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
463 # The .pc files wind up containing some absolute paths
464 # that make the output depend on the build directory name.
465 # The dependents' configure scripts don't need them anyway.
466 command.RemoveDirectory(command.path.join(
467 '%(output)s', 'lib', 'pkgconfig')),
474 HOST_GCC_LIBS_DEPS = ['gmp', 'mpfr', 'mpc', 'isl', 'cloog']
476 def HostGccLibsDeps(host):
477 return [ForHost(package, host) for package in HOST_GCC_LIBS_DEPS]
480 def ConfigureCommand(source_component):
481 return [command % {'src': '%(' + source_component + ')s'}
482 for command in CONFIGURE_CMD]
485 # When doing a Canadian cross, we need native-hosted cross components
486 # to do the GCC build.
487 def GccDeps(host, target):
488 native, _ = NativeTuple()
489 components = ['binutils_' + target]
491 components.append('gcc_' + target)
493 return [ForHost(component, host) for component in components]
496 def GccCommand(host, target, cmd):
497 components_for_path = GccDeps(host, target)
498 return command.Command(
499 cmd, path_dirs=[command.path.join('%(abs_' + component + ')s', 'bin')
500 for component in components_for_path])
503 def ConfigureGccCommand(source_component, host, target, extra_args=[]):
504 target_cflagstr = ' '.join(CommonTargetCflags(target))
508 ConfigureCommand(source_component) +
509 ConfigureHostTool(host) +
510 ConfigureTargetArgs(target) +
511 TARGET_GCC_CONFIG.get(target, []) + [
512 '--with-gmp=%(abs_' + ForHost('gmp', host) + ')s',
513 '--with-mpfr=%(abs_' + ForHost('mpfr', host) + ')s',
514 '--with-mpc=%(abs_' + ForHost('mpc', host) + ')s',
515 '--with-isl=%(abs_' + ForHost('isl', host) + ')s',
516 '--with-cloog=%(abs_' + ForHost('cloog', host) + ')s',
517 '--enable-cloog-backend=isl',
521 '--with-linker-hash-style=gnu',
522 '--enable-linker-build-id',
523 '--enable-languages=c,c++,lto',
524 'CFLAGS_FOR_TARGET=' + target_cflagstr,
525 'CXXFLAGS_FOR_TARGET=' + target_cflagstr,
530 def HostTools(host, target):
531 def H(component_name):
532 return ForHost(component_name, host)
534 H('binutils_' + target): {
536 'dependencies': ['binutils'],
537 'commands': ConfigureTargetPrep(target) + [
539 ConfigureCommand('binutils') +
540 ConfigureHostTool(host) +
541 ConfigureTargetArgs(target) + [
542 '--enable-deterministic-archives',
544 ] + ([] if HostIsWindows(host) else [
547 command.Command(MakeCommand(host)),
548 command.Command(MakeCheckCommand(host)),
549 command.Command(MAKE_DESTDIR_CMD + ['install-strip']),
551 ] + InstallDocFiles('binutils',
553 [command.path.join(subdir, 'NEWS')
555 ['binutils', 'gas', 'ld', 'gold']]) +
556 # The top-level lib* directories contain host libraries
557 # that we don't want to include in the distribution.
558 [command.RemoveDirectory(command.path.join('%(output)s', name))
559 for name in ['lib', 'lib32', 'lib64']],
562 H('gcc_' + target): {
564 'dependencies': (['gcc'] + HostGccLibsDeps(host) +
565 GccDeps(host, target)),
566 'commands': ConfigureTargetPrep(target) + [
567 ConfigureGccCommand('gcc', host, target),
568 # GCC's configure step writes configargs.h with some strings
569 # including the configure command line, which get embedded
570 # into the gcc driver binary. The build only works if we use
571 # absolute paths in some of the configure switches, but
572 # embedding those paths makes the output differ in repeated
573 # builds done in different directories, which we do not want.
574 # So force the generation of that file early and then edit it
575 # in place to replace the absolute paths with something that
576 # never varies. Note that the 'configure-gcc' target will
577 # actually build some components before running gcc/configure.
578 GccCommand(host, target,
579 MakeCommand(host, ['configure-gcc'])),
580 command.Command(['sed', '-i', '-e',
581 ';'.join(['s@%%(abs_%s)s@.../%s_install@g' %
582 (component, component)
584 HostGccLibsDeps(host)] +
585 ['s@%(cwd)s@...@g']),
586 command.path.join('gcc', 'configargs.h')]),
587 # gcc/Makefile's install rules ordinarily look at the
588 # installed include directory for a limits.h to decide
589 # whether the lib/gcc/.../include-fixed/limits.h header
590 # should be made to expect a libc-supplied limits.h or not.
591 # Since we're doing this build in a clean environment without
592 # any libc installed, we need to force its hand here.
593 GccCommand(host, target,
594 MakeCommand(host, ['all-gcc', 'LIMITS_H_TEST=true'])),
595 # gcc/Makefile's install targets populate this directory
596 # only if it already exists.
597 command.Mkdir(command.path.join('%(output)s',
598 target + '-nacl', 'bin'),
600 GccCommand(host, target,
601 MAKE_DESTDIR_CMD + ['install-strip-gcc']),
603 # Note we include COPYING.RUNTIME here and not with gcc_libs.
604 ] + InstallDocFiles('gcc', ['COPYING3', 'COPYING.RUNTIME']),
610 # configure defaults to -g -O2 but passing an explicit option overrides that.
611 # So we have to list -g -O2 explicitly since we need to add -mtp=soft.
612 def CommonTargetCflags(target):
613 options = ['-g', '-O2']
615 options.append('-mtp=soft')
619 def TargetCommands(host, target, command_list):
620 # First we have to copy the host tools into a common directory.
621 # We can't just have both directories in our PATH, because the
622 # compiler looks for the assembler and linker relative to itself.
623 commands = PopulateDeps(['%(' + ForHost('binutils_' + target, host) + ')s',
624 '%(' + ForHost('gcc_' + target, host) + ')s'])
625 bindir = command.path.join('%(cwd)s', 'all_deps', 'bin')
626 commands += [command.Command(cmd, path_dirs=[bindir])
627 for cmd in command_list]
631 def TargetLibs(host, target):
632 lib_deps = [ForHost(component + '_' + target, host)
633 for component in ['binutils', 'gcc']]
635 def NewlibFile(subdir, name):
636 return command.path.join('%(output)s', target + '-nacl', subdir, name)
638 newlib_sysroot = '%(abs_newlib_' + target + ')s'
639 newlib_tooldir = '%s/%s-nacl' % (newlib_sysroot, target)
641 # See the comment at ConfigureTargetPrep, above.
642 newlib_install_data = ' '.join(['STRIPPROG=%(cwd)s/strip_for_target',
643 '%(abs_newlib)s/install-sh',
644 '-c', '-s', '-m', '644'])
646 iconv_encodings = 'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4'
647 newlib_configure_args = [
648 '--disable-libgloss',
649 '--enable-newlib-iconv',
650 '--enable-newlib-iconv-from-encodings=' + iconv_encodings,
651 '--enable-newlib-iconv-to-encodings=' + iconv_encodings,
652 '--enable-newlib-io-long-long',
653 '--enable-newlib-io-long-double',
654 '--enable-newlib-io-c99-formats',
655 '--enable-newlib-mb',
657 'CFLAGS_FOR_TARGET=' + ' '.join(CommonTargetCflags(target)),
658 'INSTALL_DATA=' + newlib_install_data,
661 newlib_post_install = [
662 command.Rename(NewlibFile('lib', 'libc.a'),
663 NewlibFile('lib', 'libcrt_common.a')),
664 command.WriteData(NewlibLibcScript(target),
665 NewlibFile('lib', 'libc.a')),
668 command.path.join('%(pthread_headers)s', header),
669 NewlibFile('include', header))
670 for header in ('pthread.h', 'semaphore.h')
675 'newlib_' + target: {
677 'dependencies': ['newlib'] + lib_deps,
678 'inputs': { 'pthread_headers':
679 os.path.join(NACL_DIR, 'src', 'untrusted',
681 'commands': (ConfigureTargetPrep(target) +
682 TargetCommands(host, target, [
683 ConfigureCommand('newlib') +
684 ConfigureHostTool(host) +
685 ConfigureTargetArgs(target) +
686 newlib_configure_args,
688 MAKE_DESTDIR_CMD + ['install-strip'],
690 newlib_post_install +
691 InstallDocFiles('newlib', ['COPYING.NEWLIB'])),
694 'gcc_libs_' + target: {
696 'dependencies': (['gcc_libs'] + lib_deps + ['newlib_' + target] +
697 HostGccLibsDeps(host)),
698 # This actually builds the compiler again and uses that compiler
699 # to build the target libraries. That's by far the easiest thing
700 # to get going given the interdependencies of the target
701 # libraries (especially libgcc) on the gcc subdirectory, and
702 # building the compiler doesn't really take all that long in the
703 # grand scheme of things.
704 # TODO(mcgrathr): If upstream ever cleans up all their
705 # interdependencies better, unpack the compiler, configure with
706 # --disable-gcc, and just build all-target.
707 'commands': ConfigureTargetPrep(target) + [
708 ConfigureGccCommand('gcc_libs', host, target, [
709 '--with-build-sysroot=' + newlib_sysroot,
711 GccCommand(host, target,
712 MakeCommand(host) + [
713 'build_tooldir=' + newlib_tooldir,
716 GccCommand(host, target,
717 MAKE_DESTDIR_CMD + ['install-strip-target']),
726 if sys.platform.startswith('linux'):
727 machine = platform.machine().lower()
728 if machine.startswith('arm'):
729 return ('arm-linux-gnueabihf', [])
730 if any(fnmatch.fnmatch(machine, pattern) for pattern in
731 ['x86_64*', 'amd64*', 'x64*', 'i?86*']):
732 # We build the tools for x86-32 hosts so they will run on either x86-32
733 # or x86-64 hosts (with the right compatibility libraries installed).
734 # So for an x86-64 host, we call x86-32 the "native" machine.
735 return ('i686-linux', ['-m32'])
736 raise Exception('Machine %s not recognized' % machine)
737 elif sys.platform.startswith('win'):
738 return ('i686-w64-mingw32', [])
739 elif sys.platform.startswith('darwin'):
740 return ('x86_64-apple-darwin', [])
741 raise Exception('Platform %s not recognized' % sys.platform)
744 def HostIsWindows(host):
745 return host == 'i686-w64-mingw32'
748 # We build target libraries only on Linux for two reasons:
749 # 1. We only need to build them once.
750 # 2. Linux is the fastest to build.
751 # TODO(mcgrathr): In future set up some scheme whereby non-Linux
752 # bots can build target libraries but not archive them, only verifying
753 # that the results came out the same as the ones archived by the
754 # official builder bot. That will serve as a test of the host tools
755 # on the other host platforms.
756 def BuildTargetLibsOn(host):
757 return host == 'i686-linux'
760 def CollectPackagesForHost(host, targets):
761 packages = HostGccLibs(host).copy()
762 for target in targets:
763 packages.update(HostTools(host, target))
764 if BuildTargetLibsOn(host):
765 packages.update(TargetLibs(host, target))
769 def CollectPackages(targets):
770 packages = CollectSources()
772 native, _ = NativeTuple()
773 packages.update(CollectPackagesForHost(native, targets))
775 for host in EXTRA_HOSTS_MAP.get(native, []):
776 packages.update(CollectPackagesForHost(host, targets))
781 PACKAGES = CollectPackages(TARGET_LIST)
784 if __name__ == '__main__':
785 tb = toolchain_main.PackageBuilder(PACKAGES, sys.argv[1:])
786 # TODO(mcgrathr): The bot ought to run some native_client tests
787 # using the new toolchain, like the old x86 toolchain bots do.