From c4d61accf4d19515d55a1277dee47467d44a5bbf Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Sun, 8 Jul 2018 05:09:42 -0400 Subject: [PATCH] Fix rust depfile problem. Fixes #316. --- build_extra/rust/rust.gni | 46 ++++++++++++++++++++------------------- tools/run_rustc.py | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 tools/run_rustc.py diff --git a/build_extra/rust/rust.gni b/build_extra/rust/rust.gni index 20641fadcf..faa97205b9 100644 --- a/build_extra/rust/rust.gni +++ b/build_extra/rust/rust.gni @@ -25,10 +25,9 @@ template("run_rustc") { source_root, ] outputs = [] - script = "//third_party/v8/tools/run.py" + script = "//tools/run_rustc.py" args = [ - "rustc", rebase_path(source_root, root_build_dir), "--crate-name=$crate_name", "--crate-type=$crate_type", @@ -36,37 +35,40 @@ template("run_rustc") { if (defined(is_test) && is_test) { # Test outputs are executables which should be in root_out_dir. - output = "$root_out_dir/$crate_name" + output_file = "$root_out_dir/$crate_name" args += [ "--test", "-o", - rebase_path(output, root_build_dir), + rebase_path(output_file, root_build_dir), ] - outputs += [ output ] + outputs += [ output_file ] } else { # Non-test targets are handled differently. - # For unknown reasons emitting a depfile on tests doesn't work. - depfile = "$target_out_dir/$target_name.d" - args += [ "--emit=dep-info=" + rebase_path(depfile, root_build_dir) ] - if (crate_type == "staticlib") { - staticlib = "$target_out_dir/$crate_name.a" - outputs += [ staticlib ] - args += [ "--emit=link=" + rebase_path(staticlib, root_build_dir) ] + output_file = "$target_out_dir/$crate_name.a" + emit_type = "link" + } else if (crate_type == "bin") { + output_file = "$target_out_dir/$crate_name.o" + emit_type = "obj" + } else if (crate_type == "rlib") { + output_file = "$target_out_dir/lib$crate_name.rlib" + emit_type = "link" } + outputs += [ output_file ] + output_file_rel = rebase_path(output_file, root_build_dir) + args += [ "--emit=$emit_type=$output_file_rel" ] - if (crate_type == "rlib" || crate_type == "bin") { - obj = "$target_out_dir/$crate_name.o" - outputs += [ obj ] - args += [ "--emit=obj=" + rebase_path(obj, root_build_dir) ] - } + # TODO(ry) For unknown reasons emitting a depfile on tests doesn't work. + depfile = "$target_out_dir/$crate_name.d" + args += [ + "--emit=dep-info=" + rebase_path(depfile, root_build_dir), - if (crate_type == "rlib") { - rlib = "$target_out_dir/lib$crate_name.rlib" - outputs += [ rlib ] - args += [ "--emit=link=" + rebase_path(rlib, root_build_dir) ] - } + # The following two args are used by run_rustc.py to fix + # the depfile on the fly. They are not passed thru to rustc. + "--depfile=" + rebase_path(depfile, root_build_dir), + "--output_file=" + output_file_rel, + ] } if (is_debug) { diff --git a/tools/run_rustc.py b/tools/run_rustc.py new file mode 100644 index 0000000000..9e7284c260 --- /dev/null +++ b/tools/run_rustc.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# Inspired by +# https://fuchsia.googlesource.com/build/+/master/rust/build_rustc_target.py +# 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 sys +import os +import argparse +import subprocess + + +# Updates the path of the main target in the depfile to the relative path +# from base_path build_output_path +def fix_depfile(depfile_path, base_path, build_output_path): + with open(depfile_path, "r") as depfile: + content = depfile.read() + content_split = content.split(': ', 1) + target_path = os.path.relpath(build_output_path, start=base_path) + new_content = "%s: %s" % (target_path, content_split[1]) + with open(depfile_path, "w") as depfile: + depfile.write(new_content) + + +def main(): + parser = argparse.ArgumentParser("Compiles a Rust crate") + parser.add_argument( + "--depfile", + help="Path at which the output depfile should be stored", + required=False) + parser.add_argument( + "--output_file", + help="Path at which the output file should be stored", + required=False) + args, rest = parser.parse_known_args() + + env = os.environ.copy() + subprocess.check_call(["rustc"] + rest, env=env) + + if args.depfile and args.output_file: + fix_depfile(args.depfile, os.getcwd(), args.output_file) + + +if __name__ == '__main__': + sys.exit(main())