| #!/usr/bin/env python2.7 |
| # Copyright 2018 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. |
| |
| import argparse |
| import os |
| import subprocess |
| import sys |
| |
| |
| FUCHSIA_ROOT = os.path.dirname( # $root |
| os.path.dirname( # scripts |
| os.path.dirname( # rust |
| os.path.abspath(__file__)))) |
| |
| BUILD_CONFIG = ''' |
| [llvm] |
| optimize = true |
| static-libstdcpp = true |
| ninja = true |
| targets = "X86;AArch64" |
| |
| [build] |
| target = ["{target}-fuchsia"] |
| docs = false |
| extended = true |
| openssl-static = true |
| |
| [install] |
| prefix = "{prefix}" |
| sysconfdir = "etc" |
| |
| [rust] |
| optimize = true |
| |
| [target.{target}-fuchsia] |
| cc = "{cc}" |
| cxx = "{cxx}" |
| ar = "{ar}" |
| linker = "{cc}" |
| |
| [dist] |
| ''' |
| |
| CARGO_CONFIG = ''' |
| [target.{target}-fuchsia] |
| linker = "{linker}" |
| ar = "{ar}" |
| rustflags = [ |
| "-C", "link-arg=--target={target}-fuchsia", |
| "-C", "link-arg=--sysroot={sysroot}", |
| "-C", "link-arg=-L{shared_libs_root}", |
| ] |
| ''' |
| |
| def ensure_dir(dir): |
| if not os.path.exists(dir): |
| os.makedirs(dir) |
| return dir |
| |
| def main(): |
| parser = argparse.ArgumentParser(description='Build a Rust toolchain for Fuchsia') |
| parser.add_argument( |
| '--rust-root', |
| help='root directory of Rust checkout', |
| required=True) |
| parser.add_argument( |
| '--sysroot', |
| help='zircon sysroot (possibly //out/release-x64/sdk/exported/zircon_sysroot/sysroot)', |
| required=True) |
| parser.add_argument( |
| '--shared-libs-root', |
| help='shared libs root (possibly //out/release-x64/x64-shared)', |
| required=True) |
| parser.add_argument( |
| '--host-os', |
| help='host operating system', |
| choices=['linux', 'mac'], |
| default='linux') |
| parser.add_argument( |
| '--target', |
| help='target architecture', |
| choices=['x86_64', 'aarch64'], |
| default='x86_64') |
| parser.add_argument( |
| '--staging-dir', |
| help='directory in which to stage Rust build configuration artifacts', |
| default='/tmp/fuchsia_rustc_staging') |
| parser.add_argument( |
| '--debug', |
| help='turn on debug mode, with extra logs', |
| action='store_true') |
| args = parser.parse_args() |
| |
| rust_root = os.path.abspath(args.rust_root) |
| sysroot = os.path.abspath(args.sysroot) |
| shared_libs_root = os.path.abspath(args.shared_libs_root) |
| host_os = args.host_os |
| target = args.target |
| staging_dir = os.path.abspath(args.staging_dir) |
| debug = args.debug |
| |
| build_dir = ensure_dir(os.path.join(staging_dir, 'build')) |
| toolchain_dir = ensure_dir(os.path.join(staging_dir, 'toolchain')) |
| clang_dir = os.path.join(FUCHSIA_ROOT, 'buildtools', host_os + '-x64', |
| 'clang') |
| |
| config_file = os.path.join(build_dir, 'config.toml') |
| with open(config_file, 'w') as file: |
| file.write(BUILD_CONFIG.format( |
| target=target, |
| prefix=toolchain_dir, |
| cc=os.path.join(clang_dir, 'bin', 'clang'), |
| cxx=os.path.join(clang_dir, 'bin', 'clang++'), |
| ar=os.path.join(clang_dir, 'bin', 'llvm-ar'), |
| )) |
| |
| cargo_dir = ensure_dir(os.path.join(staging_dir, '.cargo')) |
| with open(os.path.join(cargo_dir, 'config'), 'w') as file: |
| file.write(CARGO_CONFIG.format( |
| target=target, |
| linker=os.path.join(clang_dir, 'bin', 'clang'), |
| ar=os.path.join(clang_dir, 'bin', 'llvm-ar'), |
| sysroot=sysroot, |
| shared_libs_root=shared_libs_root, |
| )) |
| |
| cflags_key = 'CFLAGS_%s-fuchsia' % target |
| cflags_val = '--target=%s-fuchsia --sysroot=%s' % (target, sysroot) |
| |
| env = { |
| 'CARGO_HOME': cargo_dir, |
| cflags_key: cflags_val, |
| 'PATH': os.environ['PATH'], |
| 'RUST_BACKTRACE': '1', |
| } |
| |
| def run_build_command(command): |
| command_args = [ |
| os.path.join(rust_root, 'x.py'), |
| ] |
| command_args += command |
| command_args += [ |
| '--config', |
| config_file, |
| '--src', |
| rust_root, |
| ] |
| if debug: |
| command_args.append('--verbose') |
| print('Running: %s' % ' '.join(command_args)) |
| # The builds need to run from a subdirectory of the staging dir |
| # otherwise the cargo config set up above will get clobbered by x.py. |
| out_dir = ensure_dir(os.path.join(staging_dir, 'out')) |
| subprocess.check_call(command_args, env=env, cwd=out_dir) |
| |
| run_build_command(['install']) |
| |
| print('The toolchain is ready at: %s' % toolchain_dir) |
| |
| |
| if __name__ == '__main__': |
| main() |