Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@io_bazel_rules_rust//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts")
load("@io_bazel_rules_rust//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts", "get_linker_and_args")
load("@io_bazel_rules_rust//rust:private/utils.bzl", "find_toolchain")
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
Expand All @@ -20,6 +20,14 @@ def _cargo_build_script_run(ctx, script):
crate_name = crate_name.replace("_build_script", "")
crate_name = crate_name.replace("_", "-")

toolchain_tools = [
# Needed for rustc to function.
toolchain.rustc_lib.files,
toolchain.rust_lib.files,
]

cc_toolchain = find_cpp_toolchain(ctx)

env = {
"CARGO_CFG_TARGET_ARCH": toolchain.target_arch,
"CARGO_MANIFEST_DIR": manifest_dir,
Expand All @@ -31,10 +39,15 @@ def _cargo_build_script_run(ctx, script):
"TARGET": toolchain.target_triple,
}

cc_toolchain = find_cpp_toolchain(ctx)
# Pull in env vars which may be required for the cc_toolchain to work (e.g. on OSX, the SDK version).
# We hope that the linker env is sufficient for the whole cc_toolchain.
_, _, linker_env = get_linker_and_args(ctx, None)
env.update(**linker_env)

cc_executable = cc_toolchain and cc_toolchain.compiler_executable
if cc_executable:
env["CC"] = cc_executable
toolchain_tools.append(cc_toolchain.all_files)

for f in ctx.attr.crate_features:
env["CARGO_FEATURE_" + f.upper().replace("-", "_")] = "1"
Expand All @@ -45,11 +58,7 @@ def _cargo_build_script_run(ctx, script):
ctx.executable._cargo_build_script_runner,
toolchain.rustc,
],
transitive = [
# Needed for rustc to function.
toolchain.rustc_lib.files,
toolchain.rust_lib.files,
],
transitive = toolchain_tools,
)

# dep_env_file contains additional environment variables coming from
Expand Down Expand Up @@ -109,6 +118,7 @@ _build_script_run = rule(
),
"deps": attr.label_list(),
},
fragments = ["cpp"],
toolchains = [
"@io_bazel_rules_rust//rust:toolchain",
"@bazel_tools//tools/cpp:toolchain_type",
Expand Down
23 changes: 20 additions & 3 deletions cargo/cargo_build_script_runner/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use cargo_build_script_output_parser::BuildScriptOutput;
use std::env;
use std::fs::{File, create_dir_all};
use std::io::Write;
use std::path::Path;
use std::process::{exit, Command};

fn main() {
Expand All @@ -40,15 +41,31 @@ fn main() {
let manifest_dir = exec_root.join(&manifest_dir_env);
let out_dir = exec_root.join(&out_dir_env);
let rustc = exec_root.join(&rustc_env);

let cc = env::var_os("CC").map(|env_var| {
let cc_path = Path::new(&env_var);
if cc_path.is_relative() {
exec_root.join(cc_path).into_os_string()
} else {
env_var
}
});

match (args.next(), args.next(), args.next(), args.next(), args.next()) {
(Some(progname), Some(crate_name), Some(envfile), Some(flagfile), Some(depenvfile)) => {
let output = BuildScriptOutput::from_command(
Command::new(exec_root.join(&progname))
let mut command = Command::new(exec_root.join(&progname));
command
.args(args)
.current_dir(manifest_dir.clone())
.env("OUT_DIR", out_dir)
.env("CARGO_MANIFEST_DIR", manifest_dir)
.env("RUSTC", rustc));
.env("RUSTC", rustc);

if let Some(cc) = cc {
command.env("CC", cc);
}

let output = BuildScriptOutput::from_command(&mut command);
let mut f =
File::create(&envfile).expect(&format!("Unable to create file {}", envfile));
f.write_all(BuildScriptOutput::to_env(&output).as_bytes())
Expand Down
4 changes: 2 additions & 2 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def collect_deps(label, deps, proc_macro_deps, aliases, toolchain):
build_info,
)

def _get_linker_and_args(ctx, rpaths):
def get_linker_and_args(ctx, rpaths):
if (len(BAZEL_VERSION) == 0 or
versions.is_at_least("0.18.0", BAZEL_VERSION)):
user_link_flags = ctx.fragments.cpp.linkopts
Expand Down Expand Up @@ -331,7 +331,7 @@ def construct_arguments(
# linker since it won't understand.
if toolchain.target_arch != "wasm32":
rpaths = _compute_rpaths(toolchain, output_dir, dep_info)
ld, link_args, link_env = _get_linker_and_args(ctx, rpaths)
ld, link_args, link_env = get_linker_and_args(ctx, rpaths)
env.update(link_env)
args.add("--codegen=linker=" + ld)
args.add_joined("--codegen", link_args, join_with = " ", format_joined = "link-args=%s")
Expand Down