Skip to content

Commit 9092298

Browse files
committed
Auto merge of #5394 - henriklaxhuber:master, r=alexcrichton
Pass linker path to build script This change adds the environment variable LINKER to pass the path of the linker used by cargo to the build script. This complements the variable RUSTC (the rustc binary used) to give the build script full knowledge of its environment. A specific usage example would be automatically generating bindings to system headers in cross compilation, e.g. by locating jni.h for android targets.
2 parents 7debd81 + 3ebdc72 commit 9092298

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/cargo/core/compiler/custom_build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
146146
.env("RUSTDOC", &*cx.config.rustdoc()?)
147147
.inherit_jobserver(&cx.jobserver);
148148

149+
if let Some(ref linker) = cx.build_config.target.linker {
150+
cmd.env("RUSTC_LINKER", linker);
151+
}
152+
149153
if let Some(links) = unit.pkg.manifest().links() {
150154
cmd.env("CARGO_MANIFEST_LINKS", links);
151155
}

src/doc/src/reference/environment-variables.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,18 @@ let out_dir = env::var("OUT_DIR").unwrap();
123123
* `RUSTC`, `RUSTDOC` - the compiler and documentation generator that Cargo has
124124
resolved to use, passed to the build script so it might
125125
use it as well.
126+
* `RUSTC_LINKER` - The path to the linker binary that Cargo has resolved to use
127+
for the current target, if specified. The linker can be
128+
changed by editing `.cargo/config`; see the documentation
129+
about [cargo configuration][cargo-config] for more
130+
information.
126131

127132
[links]: reference/build-scripts.html#the-links-manifest-key
128133
[profile]: reference/manifest.html#the-profile-sections
129134
[configuration]: https://doc.rust-lang.org/reference/attributes.html#conditional-compilation
130135
[clang]: http://clang.llvm.org/docs/CrossCompilation.html#target-triple
131136
[jobserver]: https://www.gnu.org/software/make/manual/html_node/Job-Slots.html
137+
[cargo-config]: reference/config.html
132138

133139
### Environment variables Cargo sets for 3rd party subcommands
134140

tests/testsuite/build_script.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::io::prelude::*;
44
use std::path::PathBuf;
55

66
use cargotest::{rustc_host, sleep_ms};
7-
use cargotest::support::{execs, project};
7+
use cargotest::support::{cross_compile, execs, project};
88
use cargotest::support::paths::CargoPathExt;
99
use cargotest::support::registry::Package;
1010
use hamcrest::{assert_that, existing_dir, existing_file};
@@ -134,6 +134,8 @@ fn custom_build_env_vars() {
134134
135135
let rustdoc = env::var("RUSTDOC").unwrap();
136136
assert_eq!(rustdoc, "rustdoc");
137+
138+
assert!(env::var("RUSTC_LINKER").is_err());
137139
}}
138140
"#,
139141
p.root()
@@ -151,6 +153,50 @@ fn custom_build_env_vars() {
151153
);
152154
}
153155

156+
157+
#[test]
158+
fn custom_build_env_var_rustc_linker() {
159+
if cross_compile::disabled() { return; }
160+
let target = cross_compile::alternate();
161+
let p = project("foo")
162+
.file("Cargo.toml",
163+
r#"
164+
[project]
165+
name = "foo"
166+
version = "0.0.1"
167+
"#
168+
)
169+
.file(
170+
".cargo/config",
171+
&format!(
172+
r#"
173+
[target.{}]
174+
linker = "/path/to/linker"
175+
"#,
176+
target
177+
)
178+
)
179+
.file(
180+
"build.rs",
181+
r#"
182+
use std::env;
183+
184+
fn main() {
185+
assert!(env::var("RUSTC_LINKER").unwrap().ends_with("/path/to/linker"));
186+
}
187+
"#
188+
)
189+
.file("src/lib.rs", "")
190+
.build();
191+
192+
// no crate type set => linker never called => build succeeds if and
193+
// only if build.rs succeeds, despite linker binary not existing.
194+
assert_that(
195+
p.cargo("build").arg("--target").arg(&target),
196+
execs().with_status(0),
197+
);
198+
}
199+
154200
#[test]
155201
fn custom_build_script_wrong_rustc_flags() {
156202
let p = project("foo")

0 commit comments

Comments
 (0)