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