| #!/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 | |
| 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() |