diff --git a/cargo/cargo_build_script.bzl b/cargo/cargo_build_script.bzl index 348901bc83..00b738adbd 100644 --- a/cargo/cargo_build_script.bzl +++ b/cargo/cargo_build_script.bzl @@ -71,18 +71,18 @@ def _cargo_build_script_run(ctx, script): # available to the current crate build script. # See https://doc.rust-lang.org/cargo/reference/build-scripts.html#-sys-packages # for details. - cmd = "" + args = ctx.actions.args() + args.add_all([script.path, crate_name, out_dir.path, env_out.path, flags_out.path, link_flags.path, dep_env_out.path]) dep_env_files = [] for dep in ctx.attr.deps: if DepInfo in dep and dep[DepInfo].dep_env: dep_env_file = dep[DepInfo].dep_env - cmd += "export $(cat %s); " % dep_env_file.path + args.add(dep_env_file.path) dep_env_files.append(dep_env_file) - cmd += "$@" - ctx.actions.run_shell( - command = cmd, - arguments = [ctx.executable._cargo_build_script_runner.path, script.path, crate_name, out_dir.path, env_out.path, flags_out.path, link_flags.path, dep_env_out.path], + ctx.actions.run( + executable = ctx.executable._cargo_build_script_runner, + arguments = [args], outputs = [out_dir, env_out, flags_out, link_flags, dep_env_out], tools = tools, inputs = dep_env_files, @@ -131,7 +131,7 @@ _build_script_run = rule( ], ) -def cargo_build_script(name, crate_name="", crate_features=[], deps=[], **kwargs): +def cargo_build_script(name, crate_name = "", crate_features = [], deps = [], **kwargs): """ Compile and execute a rust build script to generate build attributes @@ -184,7 +184,7 @@ def cargo_build_script(name, crate_name="", crate_features=[], deps=[], **kwargs name = name + "_script_", crate_features = crate_features, deps = deps, - **kwargs, + **kwargs ) _build_script_run( name = name, diff --git a/cargo/cargo_build_script_runner/bin.rs b/cargo/cargo_build_script_runner/bin.rs index 1a26c5fbda..56e407bdd6 100644 --- a/cargo/cargo_build_script_runner/bin.rs +++ b/cargo/cargo_build_script_runner/bin.rs @@ -19,7 +19,7 @@ extern crate cargo_build_script_output_parser; use cargo_build_script_output_parser::{BuildScriptOutput, CompileAndLinkFlags}; use std::env; use std::ffi::OsString; -use std::fs::{create_dir_all, write}; +use std::fs::{create_dir_all, read_to_string, write}; use std::path::Path; use std::process::Command; @@ -45,16 +45,34 @@ fn main() -> Result<(), String> { let mut command = Command::new(exec_root.join(&progname)); command - .args(args) .current_dir(manifest_dir.clone()) .env("OUT_DIR", out_dir_abs) .env("CARGO_MANIFEST_DIR", manifest_dir) .env("RUSTC", rustc) .env("RUST_BACKTRACE", "full"); + while let Some(dep_env_path) = args.next() { + if let Ok(contents) = read_to_string(dep_env_path) { + for line in contents.split('\n') { + let mut key_val = line.splitn(2, '='); + match (key_val.next(), key_val.next()) { + (Some(key), Some(value)) => { + command.env(key, value); + } + _ => { + return Err("error: Wrong environment file format, should not happen".to_owned()) + } + } + } + } else { + return Err("error: Dependency environment file unreadable".to_owned()) + } + } + if let Some(cc_path) = env::var_os("CC") { command.env("CC", absolutify(&exec_root, cc_path)); } + if let Some(ar_path) = env::var_os("AR") { // The default OSX toolchain uses libtool as ar_executable not ar. // This doesn't work when used as $AR, so simply don't set it - tools will probably fall back to