Skip to content

Commit b2496f0

Browse files
committed
Auto merge of #10274 - aviramha:extra-link-args, r=ehuss
extra-link-arg-etc: support all link types (credit @davidhewitt) This commit adds support for the remaining link types to `-Zextra-link-arg-etc`: ` rustc-link-arg-tests rustc-link-arg-benches rustc-link-arg-examples ` This would be useful in PyO3, where users writing Python extension modules (which do link against libpython) want to run cargo tests for extension module. As executables, these tests need to link against libpython. This is a follow up of #9416 by `@davidhewitt`
2 parents f639ea3 + 541c908 commit b2496f0

File tree

4 files changed

+152
-20
lines changed

4 files changed

+152
-20
lines changed

src/cargo/core/compiler/custom_build.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,22 @@ impl BuildOutput {
579579
script_out_dir.to_str().unwrap(),
580580
);
581581

582+
macro_rules! check_and_add_target {
583+
($target_kind: expr, $is_target_kind: expr, $link_type: expr) => {
584+
if !targets.iter().any(|target| $is_target_kind(target)) {
585+
bail!(
586+
"invalid instruction `cargo:{}` from {}\n\
587+
The package {} does not have a {} target.",
588+
key,
589+
whence,
590+
pkg_descr,
591+
$target_kind
592+
);
593+
}
594+
linker_args.push(($link_type, value));
595+
};
596+
}
597+
582598
// Keep in sync with TargetConfig::parse_links_overrides.
583599
match key {
584600
"rustc-flags" => {
@@ -604,16 +620,7 @@ impl BuildOutput {
604620
linker_args.push((LinkType::Cdylib, value))
605621
}
606622
"rustc-link-arg-bins" => {
607-
if !targets.iter().any(|target| target.is_bin()) {
608-
bail!(
609-
"invalid instruction `cargo:{}` from {}\n\
610-
The package {} does not have a bin target.",
611-
key,
612-
whence,
613-
pkg_descr
614-
);
615-
}
616-
linker_args.push((LinkType::Bin, value));
623+
check_and_add_target!("bin", Target::is_bin, LinkType::Bin);
617624
}
618625
"rustc-link-arg-bin" => {
619626
let mut parts = value.splitn(2, '=');
@@ -643,6 +650,15 @@ impl BuildOutput {
643650
}
644651
linker_args.push((LinkType::SingleBin(bin_name), arg.to_string()));
645652
}
653+
"rustc-link-arg-tests" => {
654+
check_and_add_target!("test", Target::is_test, LinkType::Test);
655+
}
656+
"rustc-link-arg-benches" => {
657+
check_and_add_target!("benchmark", Target::is_bench, LinkType::Bench);
658+
}
659+
"rustc-link-arg-examples" => {
660+
check_and_add_target!("example", Target::is_example, LinkType::Example);
661+
}
646662
"rustc-link-arg" => {
647663
linker_args.push((LinkType::All, value));
648664
}

src/cargo/util/config/target.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,27 @@ fn parse_links_overrides(
173173
.extend(list.iter().map(|v| PathBuf::from(&v.0)));
174174
}
175175
"rustc-link-arg-cdylib" | "rustc-cdylib-link-arg" => {
176-
let args = value.list(key)?;
177-
let args = args.iter().map(|v| (LinkType::Cdylib, v.0.clone()));
176+
let args = extra_link_args(LinkType::Cdylib, key, value)?;
178177
output.linker_args.extend(args);
179178
}
180179
"rustc-link-arg-bins" => {
181-
let args = value.list(key)?;
182-
let args = args.iter().map(|v| (LinkType::Bin, v.0.clone()));
180+
let args = extra_link_args(LinkType::Bin, key, value)?;
183181
output.linker_args.extend(args);
184182
}
185183
"rustc-link-arg" => {
186-
let args = value.list(key)?;
187-
let args = args.iter().map(|v| (LinkType::All, v.0.clone()));
184+
let args = extra_link_args(LinkType::All, key, value)?;
185+
output.linker_args.extend(args);
186+
}
187+
"rustc-link-arg-tests" => {
188+
let args = extra_link_args(LinkType::Test, key, value)?;
189+
output.linker_args.extend(args);
190+
}
191+
"rustc-link-arg-benches" => {
192+
let args = extra_link_args(LinkType::Bench, key, value)?;
193+
output.linker_args.extend(args);
194+
}
195+
"rustc-link-arg-examples" => {
196+
let args = extra_link_args(LinkType::Example, key, value)?;
188197
output.linker_args.extend(args);
189198
}
190199
"rustc-cfg" => {
@@ -210,3 +219,12 @@ fn parse_links_overrides(
210219
}
211220
Ok(links_overrides)
212221
}
222+
223+
fn extra_link_args<'a>(
224+
link_type: LinkType,
225+
key: &str,
226+
value: &'a CV,
227+
) -> CargoResult<impl Iterator<Item = (LinkType, String)> + 'a> {
228+
let args = value.list(key)?;
229+
Ok(args.iter().map(move |v| (link_type.clone(), v.0.clone())))
230+
}

src/doc/src/reference/build-scripts.md

+29-3
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ one detailed below.
100100
flags to a linker for the binary `BIN`.
101101
* [`cargo:rustc-link-arg-bins=FLAG`](#rustc-link-arg-bins) – Passes custom
102102
flags to a linker for binaries.
103+
* [`cargo:rustc-link-arg-tests=FLAG`](#rustc-link-arg-tests) – Passes custom
104+
flags to a linker for tests.
105+
* [`cargo:rustc-link-arg-examples=FLAG`](#rustc-link-arg-examples) – Passes custom
106+
flags to a linker for examples.
107+
* [`cargo:rustc-link-arg-benches=FLAG`](#rustc-link-arg-benches) – Passes custom
108+
flags to a linker for benchmarks.
103109
* [`cargo:rustc-link-lib=[KIND=]NAME`](#rustc-link-lib) — Adds a library to
104110
link.
105111
* [`cargo:rustc-link-search=[KIND=]PATH`](#rustc-link-search) — Adds to the
@@ -136,7 +142,6 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building
136142
the binary target with name `BIN`. Its usage is highly platform specific. It is useful
137143
to set a linker script or other linker options.
138144

139-
[link-arg]: ../../rustc/codegen-options/index.md#link-arg
140145

141146
<a id="rustc-link-arg-bins"></a>
142147
#### `cargo:rustc-link-arg-bins=FLAG`
@@ -146,7 +151,6 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building a
146151
binary target. Its usage is highly platform specific. It is useful
147152
to set a linker script or other linker options.
148153

149-
[link-arg]: ../../rustc/codegen-options/index.md#link-arg
150154

151155
<a id="rustc-link-lib"></a>
152156
#### `cargo:rustc-link-lib=[KIND=]NAME`
@@ -169,6 +173,29 @@ The optional `KIND` may be one of `dylib`, `static`, or `framework`. See the
169173
[option-link]: ../../rustc/command-line-arguments.md#option-l-link-lib
170174
[FFI]: ../../nomicon/ffi.md
171175

176+
177+
<a id="rustc-link-arg-tests"></a>
178+
#### `cargo:rustc-link-arg-tests=FLAG`
179+
180+
The `rustc-link-arg-tests` instruction tells Cargo to pass the [`-C
181+
link-arg=FLAG` option][link-arg] to the compiler, but only when building a
182+
tests target.
183+
184+
185+
<a id="rustc-link-arg-examples"></a>
186+
#### `cargo:rustc-link-arg-examples=FLAG`
187+
188+
The `rustc-link-arg-examples` instruction tells Cargo to pass the [`-C
189+
link-arg=FLAG` option][link-arg] to the compiler, but only when building an examples
190+
target.
191+
192+
<a id="rustc-link-arg-benches"></a>
193+
#### `cargo:rustc-link-arg-benches=FLAG`
194+
195+
The `rustc-link-arg-benches` instruction tells Cargo to pass the [`-C
196+
link-arg=FLAG` option][link-arg] to the compiler, but only when building an benchmark
197+
target.
198+
172199
<a id="rustc-link-search"></a>
173200
#### `cargo:rustc-link-search=[KIND=]PATH`
174201

@@ -247,7 +274,6 @@ link-arg=FLAG` option][link-arg] to the compiler, but only when building a
247274
`cdylib` library target. Its usage is highly platform specific. It is useful
248275
to set the shared library version or the runtime-path.
249276

250-
[link-arg]: ../../rustc/codegen-options/index.md#link-arg
251277

252278
<a id="cargo-warning"></a>
253279
#### `cargo:warning=MESSAGE`

tests/testsuite/build_script_extra_link_arg.rs

+73-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// and other linkers will return an error.
66

77
use cargo_test_support::registry::Package;
8-
use cargo_test_support::{basic_bin_manifest, basic_manifest, project};
8+
use cargo_test_support::{basic_bin_manifest, basic_lib_manifest, basic_manifest, project};
99

1010
#[cargo_test]
1111
fn build_script_extra_link_arg_bin() {
@@ -310,3 +310,75 @@ fn link_arg_with_doctest() {
310310
)
311311
.run();
312312
}
313+
314+
#[cargo_test]
315+
fn build_script_extra_link_arg_tests() {
316+
let p = project()
317+
.file("Cargo.toml", &basic_lib_manifest("foo"))
318+
.file("src/lib.rs", "")
319+
.file("tests/test_foo.rs", "")
320+
.file(
321+
"build.rs",
322+
r#"
323+
fn main() {
324+
println!("cargo:rustc-link-arg-tests=--this-is-a-bogus-flag");
325+
}
326+
"#,
327+
)
328+
.build();
329+
330+
p.cargo("test -v")
331+
.without_status()
332+
.with_stderr_contains(
333+
"[RUNNING] `rustc --crate-name test_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
334+
)
335+
.run();
336+
}
337+
338+
#[cargo_test]
339+
fn build_script_extra_link_arg_benches() {
340+
let p = project()
341+
.file("Cargo.toml", &basic_lib_manifest("foo"))
342+
.file("src/lib.rs", "")
343+
.file("benches/bench_foo.rs", "")
344+
.file(
345+
"build.rs",
346+
r#"
347+
fn main() {
348+
println!("cargo:rustc-link-arg-benches=--this-is-a-bogus-flag");
349+
}
350+
"#,
351+
)
352+
.build();
353+
354+
p.cargo("bench -v")
355+
.without_status()
356+
.with_stderr_contains(
357+
"[RUNNING] `rustc --crate-name bench_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
358+
)
359+
.run();
360+
}
361+
362+
#[cargo_test]
363+
fn build_script_extra_link_arg_examples() {
364+
let p = project()
365+
.file("Cargo.toml", &basic_lib_manifest("foo"))
366+
.file("src/lib.rs", "")
367+
.file("examples/example_foo.rs", "fn main() {}")
368+
.file(
369+
"build.rs",
370+
r#"
371+
fn main() {
372+
println!("cargo:rustc-link-arg-examples=--this-is-a-bogus-flag");
373+
}
374+
"#,
375+
)
376+
.build();
377+
378+
p.cargo("build -v --examples")
379+
.without_status()
380+
.with_stderr_contains(
381+
"[RUNNING] `rustc --crate-name example_foo [..]-C link-arg=--this-is-a-bogus-flag[..]",
382+
)
383+
.run();
384+
}

0 commit comments

Comments
 (0)