Skip to content

Commit a40a010

Browse files
committed
cc works for non-absolute-path toolchains
Bring along the files, and make sure to absolut-ise the CC path. Also, add in the env vars required by the linker, because these are required for proper toolchain detection on the default OSX cc_toolchain.
1 parent 7d39dce commit a40a010

File tree

3 files changed

+45
-15
lines changed

3 files changed

+45
-15
lines changed

cargo/cargo_build_script.bzl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@io_bazel_rules_rust//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts")
1+
load("@io_bazel_rules_rust//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts", "get_linker_and_args")
22
load("@io_bazel_rules_rust//rust:private/utils.bzl", "find_toolchain")
33
load("@io_bazel_rules_rust//rust:rust.bzl", "rust_binary")
44
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
@@ -20,6 +20,14 @@ def _cargo_build_script_run(ctx, script):
2020
crate_name = crate_name.replace("_build_script", "")
2121
crate_name = crate_name.replace("_", "-")
2222

23+
toolchain_tools = [
24+
# Needed for rustc to function.
25+
toolchain.rustc_lib.files,
26+
toolchain.rust_lib.files,
27+
]
28+
29+
cc_toolchain = find_cpp_toolchain(ctx)
30+
2331
env = {
2432
"CARGO_CFG_TARGET_ARCH": toolchain.target_arch,
2533
"CARGO_MANIFEST_DIR": manifest_dir,
@@ -31,10 +39,15 @@ def _cargo_build_script_run(ctx, script):
3139
"TARGET": toolchain.target_triple,
3240
}
3341

34-
cc_toolchain = find_cpp_toolchain(ctx)
42+
# Pull in env vars which may be required for the cc_toolchain to work (e.g. on OSX, the SDK version).
43+
# We hope that the linker env is sufficient for the whole cc_toolchain.
44+
_, _, linker_env = get_linker_and_args(ctx, None)
45+
env.update(**linker_env)
46+
3547
cc_executable = cc_toolchain and cc_toolchain.compiler_executable
3648
if cc_executable:
3749
env["CC"] = cc_executable
50+
toolchain_tools.append(cc_toolchain.all_files)
3851

3952
for f in ctx.attr.crate_features:
4053
env["CARGO_FEATURE_" + f.upper().replace("-", "_")] = "1"
@@ -45,11 +58,7 @@ def _cargo_build_script_run(ctx, script):
4558
ctx.executable._cargo_build_script_runner,
4659
toolchain.rustc,
4760
],
48-
transitive = [
49-
# Needed for rustc to function.
50-
toolchain.rustc_lib.files,
51-
toolchain.rust_lib.files,
52-
],
61+
transitive = toolchain_tools,
5362
)
5463

5564
# dep_env_file contains additional environment variables coming from
@@ -109,6 +118,7 @@ _build_script_run = rule(
109118
),
110119
"deps": attr.label_list(),
111120
},
121+
fragments = ["cpp"],
112122
toolchains = [
113123
"@io_bazel_rules_rust//rust:toolchain",
114124
"@bazel_tools//tools/cpp:toolchain_type",

cargo/cargo_build_script_runner/bin.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ extern crate cargo_build_script_output_parser;
1818

1919
use cargo_build_script_output_parser::BuildScriptOutput;
2020
use std::env;
21-
use std::fs::{File, canonicalize, create_dir_all};
21+
use std::fs::{canonicalize, create_dir_all, File};
2222
use std::io::Write;
23+
use std::path::Path;
2324
use std::process::{exit, Command};
2425

2526
fn main() {
27+
let exec_root = env::current_dir().expect("Failed to get current directory");
28+
2629
let mut args = env::args().skip(1);
2730
let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR was not set");
2831
let out_dir_env = env::var("OUT_DIR").expect("OUT_DIR was not set");
@@ -31,18 +34,35 @@ fn main() {
3134
let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
3235
// Because of the Bazel's sandbox, bazel cannot provide full path, convert all relative path to correct path.
3336
let manifest_dir = canonicalize(&manifest_dir_env).expect(&format!("Failed to canonicalize '{}'", manifest_dir_env));
34-
let out_dir = canonicalize(&out_dir_env).expect(&format!("Failed to canonicalize '{}'", out_dir_env));
37+
let out_dir =
38+
canonicalize(&out_dir_env).expect(&format!("Failed to canonicalize '{}'", out_dir_env));
3539
let rustc = canonicalize(&rustc_env).expect(&format!("Failed to canonicalize '{}'", rustc_env));
40+
41+
let cc = env::var_os("CC").map(|env_var| {
42+
let cc_path = Path::new(&env_var);
43+
if cc_path.is_relative() {
44+
exec_root.join(cc_path).into_os_string()
45+
} else {
46+
env_var
47+
}
48+
});
49+
3650
match (args.next(), args.next(), args.next(), args.next(), args.next()) {
3751
(Some(progname), Some(crate_name), Some(envfile), Some(flagfile), Some(depenvfile)) => {
38-
let output = BuildScriptOutput::from_command(
39-
Command::new(
40-
canonicalize(&progname).expect(&format!("Failed to canonicalize '{}'", progname)))
52+
let mut command = Command::new(
53+
canonicalize(&progname).expect(&format!("Failed to canonicalize '{}'", progname)),
54+
);
55+
command
4156
.args(args)
4257
.current_dir(manifest_dir.clone())
4358
.env("OUT_DIR", out_dir)
4459
.env("CARGO_MANIFEST_DIR", manifest_dir)
45-
.env("RUSTC", rustc));
60+
.env("RUSTC", rustc);
61+
62+
if let Some(cc) = cc {
63+
command.env("CC", cc);
64+
}
65+
let output = BuildScriptOutput::from_command(&mut command);
4666
let mut f =
4767
File::create(&envfile).expect(&format!("Unable to create file {}", envfile));
4868
f.write_all(BuildScriptOutput::to_env(&output).as_bytes())

rust/private/rustc.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def collect_deps(label, deps, proc_macro_deps, aliases, toolchain):
192192
build_info,
193193
)
194194

195-
def _get_linker_and_args(ctx, rpaths):
195+
def get_linker_and_args(ctx, rpaths):
196196
if (len(BAZEL_VERSION) == 0 or
197197
versions.is_at_least("0.18.0", BAZEL_VERSION)):
198198
user_link_flags = ctx.fragments.cpp.linkopts
@@ -327,7 +327,7 @@ def _construct_arguments(
327327
# linker since it won't understand.
328328
if toolchain.target_arch != "wasm32":
329329
rpaths = _compute_rpaths(toolchain, output_dir, dep_info)
330-
ld, link_args, link_env = _get_linker_and_args(ctx, rpaths)
330+
ld, link_args, link_env = get_linker_and_args(ctx, rpaths)
331331
env.update(link_env)
332332
args.add("--codegen=linker=" + ld)
333333
args.add_joined("--codegen", link_args, join_with = " ", format_joined = "link-args=%s")

0 commit comments

Comments
 (0)