blob: ac25d2d317d83c7ce7106bb35b8be2ee7ef30196 [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 json
import platform
import sys
EXTRA_TOOLS = ["cargo", "rls", "rustfmt", "cargo-fmt", "miri"]
DEFAULT_TOOLS = ["cargo", "clippy", "src"]
FUCHSIA_TRIPLE_TO_ARCH = {
"x86_64-fuchsia": "x64",
"aarch64-fuchsia": "arm64",
}
FUCHSIA_TRIPLES = FUCHSIA_TRIPLE_TO_ARCH.keys()
FUCHSIA_RUNTIME_ARCHES = ["aarch64", "x86_64"]
BUILD_CONFIG = """
[llvm]
optimize = true
thin-lto = {thinlto}
ccache = {gomacc_quote}
ninja = true
targets = "X86;AArch64;WebAssembly"
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
codegen-units-std = 1
channel = "nightly"
lld = true
llvm-libunwind = "in-tree"
# Enable full debuginfo for libstd.
#
# For now we only link libstd statically, so this won't affect any DSOs we
# ship.
debuginfo-level-std = 2
[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"),
"-C panic=abort",
"-C force-unwind-tables=yes",
]
)
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(","):
if "wasm32" in target:
# Skip setting sysroots for wasm32.
continue
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 generate_runtimes_spec(args):
runtimes = []
for arch in FUCHSIA_RUNTIME_ARCHES:
for dynlink_flags in [[], ["-Cprefer-dynamic"]]:
runtime = []
if dynlink_flags:
for lib in ["libstd", "libtest"]:
runtime.append(
{
# The runtimes module will expand this wildcard
# (it must match exactly one file.)
"dist": "rustlib/%s-fuchsia/lib/%s-*.so" % (arch, lib),
"name": lib,
}
)
runtimes.append(
{
"target": ["%s-unknown-fuchsia" % arch, "%s-fuchsia" % arch],
"rustflags": dynlink_flags,
"runtime": runtime,
}
)
print(json.dumps(runtimes))
def main():
is_mac = platform.system() == "Darwin"
default_targets = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"wasm32-unknown-unknown",
]
if is_mac:
default_targets.append("x86_64-apple-darwin")
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
parser_config = subparsers.add_parser("config_toml")
parser_env = subparsers.add_parser("environment")
parser_runtime = subparsers.add_parser("runtime")
for subcommand in [parser_config, parser_env]:
subcommand.add_argument(
"--targets",
default=",".join(default_targets),
help="comma-separated list of targets to build for, in addition to Fuchsia",
)
subcommand.add_argument(
"--clang-prefix", help="path to clang toolchain", required=True
)
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.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)
parser_runtime.set_defaults(func=generate_runtimes_spec)
args = parser.parse_args()
args.func(args)
return 0
if __name__ == "__main__":
sys.exit(main())