| #!/usr/bin/env python |
| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from collections import OrderedDict |
| from os import path |
| import argparse |
| import platform |
| import sys |
| |
| EXTRA_TOOLS = ['cargo', 'clippy', 'miri'] |
| DEFAULT_TOOLS = ['cargo', 'rls', 'rustfmt', 'cargo-fmt', 'src'] |
| |
| FUCHSIA_TRIPLE_TO_ARCH = { |
| 'x86_64-fuchsia': 'x64', |
| 'aarch64-fuchsia': 'arm64', |
| } |
| FUCHSIA_TRIPLES = FUCHSIA_TRIPLE_TO_ARCH.keys() |
| |
| BUILD_CONFIG = """ |
| [llvm] |
| optimize = true |
| thin-lto = {thinlto} |
| ccache = {gomacc_quote} |
| ninja = true |
| targets = "X86;AArch64" |
| cflags = "{cflags}" |
| cxxflags = "{cxxflags}" |
| ldflags = "{ldflags}" |
| use-libcxx = true |
| |
| [build] |
| target = [{target}] |
| docs = false |
| extended = true |
| cargo-native-static = true |
| tools = [{tools}] |
| |
| [install] |
| prefix = "{prefix}" |
| sysconfdir = "etc" |
| |
| [rust] |
| optimize = true |
| channel = "nightly" |
| lld = true |
| llvm-libunwind = true |
| |
| [dist] |
| """ |
| |
| TARGET_CONFIG = """ |
| [target.{triple}] |
| cc = "{cc}" |
| cxx = "{cxx}" |
| ar = "{ar}" |
| ranlib = "{ranlib}" |
| """ |
| |
| |
| def generate_config_toml(args): |
| targets = FUCHSIA_TRIPLES + args.targets.split(',') |
| tools = EXTRA_TOOLS if args.extra_tools_only else args.tools.split(',') |
| |
| def string_list(items): |
| return ', '.join('"%s"' % item for item in items) |
| |
| config_toml = BUILD_CONFIG.format( |
| prefix=args.prefix, |
| gomacc_quote=('"%s"' % path.join(args.goma_dir, 'gomacc')) |
| if args.goma_dir else 'false', |
| thinlto=str(args.thinlto).lower(), |
| cflags='--sysroot=%s' % args.host_sysroot, |
| cxxflags='--sysroot=%s' % args.host_sysroot, |
| ldflags='--sysroot=%s' % args.host_sysroot + |
| (' -L%s' % path.join(args.clang_prefix, 'lib') |
| if args.is_mac else ' -static-libstdc++'), |
| target=string_list(targets), |
| tools=string_list(tools), |
| ) |
| for target in targets: |
| config_toml += TARGET_CONFIG.format( |
| triple=target, |
| cc=path.join(args.clang_prefix, 'bin', 'clang'), |
| cxx=path.join(args.clang_prefix, 'bin', 'clang++'), |
| ar=path.join(args.clang_prefix, 'bin', 'llvm-ar'), |
| ranlib=path.join(args.clang_prefix, 'bin', 'llvm-ranlib'), |
| ) |
| if 'fuchsia' not in target: |
| config_toml += 'linker = "%s"\n' % path.join(args.clang_prefix, 'bin', |
| 'clang++') |
| print(config_toml) |
| |
| |
| def generate_env(args): |
| env = OrderedDict() |
| env['RUST_BACKTRACE'] = 1 |
| |
| if args.revision: |
| env['CFG_VERSION'] = args.revision |
| |
| for target, gn_arch in FUCHSIA_TRIPLE_TO_ARCH.iteritems(): |
| triple_lower = target.replace('-', '_').lower() |
| triple_upper = triple_lower.upper() |
| env['CC_%s' % triple_lower] = path.join(args.clang_prefix, 'bin', 'clang') |
| env['CXX_%s' % triple_lower] = path.join(args.clang_prefix, 'bin', |
| 'clang++') |
| env['CFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s -I%s' % ( |
| target, |
| path.join(args.sdk_dir, 'arch', gn_arch, 'sysroot'), |
| path.join(args.sdk_dir, 'pkg', 'fdio', 'include'), |
| )) |
| env['CXXFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s -I%s' % ( |
| target, |
| path.join(args.sdk_dir, 'arch', gn_arch, 'sysroot'), |
| path.join(args.sdk_dir, 'pkg', 'fdio', 'include'), |
| )) |
| env['LDFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s -L%s' % ( |
| target, |
| path.join(args.sdk_dir, 'arch', gn_arch, 'sysroot'), |
| path.join(args.sdk_dir, 'arch', gn_arch, 'lib'), |
| )) |
| env['CARGO_TARGET_%s_AR' % triple_upper] = path.join( |
| args.clang_prefix, 'bin', 'llvm-ar') |
| env['CARGO_TARGET_%s_RUSTFLAGS' % triple_upper] = ' '.join([ |
| '-C link-arg=--sysroot=%s' % |
| path.join(args.sdk_dir, 'arch', gn_arch, 'sysroot'), |
| '-C link-arg=-L%s/lib' % |
| path.join(args.sdk_dir, 'arch', gn_arch, 'sysroot'), |
| '-C link-arg=-L%s' % path.join(args.sdk_dir, 'arch', gn_arch, 'lib'), |
| ]) |
| |
| target_sysroots = { |
| 'aarch64-unknown-linux-gnu': args.linux_arm64_sysroot, |
| 'x86_64-unknown-linux-gnu': args.linux_amd64_sysroot, |
| } |
| if args.darwin_sysroot: |
| target_sysroots.update({ |
| 'x86_64-apple-darwin': args.darwin_sysroot, |
| }) |
| |
| for target in args.targets.split(','): |
| sysroot = target_sysroots[target] |
| triple_lower = target.replace('-', '_').lower() |
| triple_upper = triple_lower.upper() |
| env['CC_%s' % triple_lower] = path.join(args.clang_prefix, 'bin', 'clang') |
| env['CXX_%s' % triple_lower] = path.join(args.clang_prefix, 'bin', |
| 'clang++') |
| env['CFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s' % ( |
| target, |
| sysroot, |
| )) |
| env['CXXFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s' % ( |
| target, |
| sysroot, |
| )) |
| env['LDFLAGS_%s' % triple_lower] = ('--target=%s --sysroot=%s' % ( |
| target, |
| sysroot, |
| ) + (' -fuse-ld=lld' if 'apple' not in target else '')) |
| env['CARGO_TARGET_%s_AR' % triple_upper] = path.join( |
| args.clang_prefix, 'bin', 'llvm-ar') |
| env['CARGO_TARGET_%s_RUSTFLAGS' % triple_upper] = ' '.join([ |
| '-C link-arg=--target=%s' % target, |
| '-C link-arg=--sysroot=%s' % sysroot, |
| ] + (['-C link-arg=-fuse-ld=lld'] if 'apple' not in target else [])) |
| |
| for key, val in env.iteritems(): |
| if args.eval: |
| print('export %s="%s"' % (key, val)) |
| else: |
| print('%s=%s' % (key, val)) |
| |
| |
| def main(): |
| is_mac = (platform.system() == 'Darwin') |
| default_targets = [ |
| 'x86_64-unknown-linux-gnu', |
| 'aarch64-unknown-linux-gnu', |
| ] |
| if is_mac: |
| default_targets.append('x86_64-apple-darwin') |
| |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| '--targets', |
| default=','.join(default_targets), |
| help='comma-separated list of targets to build for, in addition to Fuchsia' |
| ) |
| parser.add_argument( |
| '--clang-prefix', help='path to clang toolchain', required=True) |
| subparsers = parser.add_subparsers() |
| parser_config = subparsers.add_parser('config_toml') |
| parser_config.add_argument( |
| '--prefix', help='installation prefix', required=True) |
| parser_config.add_argument( |
| '--host-sysroot', help='path to host sysroot', required=True) |
| parser_config.add_argument('--goma-dir', help='path to goma', required=False) |
| parser_config.add_argument( |
| '--thinlto', |
| default=not is_mac, |
| action='store_true', |
| help='enable thinlto') |
| parser_config.add_argument( |
| '--extra-tools-only', |
| help='build extra tools (%s); overrides --tools' % ', '.join(EXTRA_TOOLS), |
| default=False, |
| action='store_true') |
| parser_config.add_argument( |
| '--tools', |
| help='comma-separated list of tools to build; ignored if --extra-tools-only is used', |
| default=','.join(DEFAULT_TOOLS)) |
| parser_config.set_defaults(func=generate_config_toml) |
| parser_config.set_defaults(is_mac=is_mac) |
| |
| parser_env = subparsers.add_parser('environment') |
| parser_env.add_argument( |
| '--sdk-dir', help='path to Fuchsia SDK', required=True) |
| parser_env.add_argument( |
| '--linux-amd64-sysroot', help='path to Linux amd64 sysroot') |
| parser_env.add_argument( |
| '--linux-arm64-sysroot', help='path to Linux arm64 sysroot') |
| parser_env.add_argument( |
| '--darwin-sysroot', help='path to Darwin sysroot, if building on Mac') |
| parser_env.add_argument('--revision', help='git commit of Rust repository') |
| parser_env.add_argument( |
| '--eval', |
| default=False, |
| action='store_true', |
| help='format output for evaluating in a terminal') |
| parser_env.set_defaults(func=generate_env) |
| |
| args = parser.parse_args() |
| args.func(args) |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |