| #!/usr/bin/env fuchsia-vendored-python |
| # 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(os.path.abspath(__file__)) # rust |
| ) |
| ) |
| |
| 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() |