blob: 478e0a83aeaaa325ba69985ef5e3525fa6fb98ed [file] [log] [blame]
#!/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())