Skip to content

Commit 0a1b437

Browse files
authored
Rollup merge of #151353 - Enselic:aux-crate-opts, r=Zalathar
compiletest: Make `aux-crate` directive explicitly handle `--extern` modifiers With `-Zunstable-options` it is possible to pass options to `--extern`. See here for an exhaustive list of possible options: https://github.com/rust-lang/rust/blob/b5dd72d2921500c9d9e15f074e1d831adcaa3dee/compiler/rustc_session/src/config.rs#L2356-L2367 Using these options works with the `aux-crate` directive, but only because the options pretend to be part of the name. Make it clearer what `aux-crate` supports by explicitly handling `--extern` options. This PR is step one of splitting up #151258 into smaller pieces. r? @Zalathar
2 parents 3a69035 + 6f767b6 commit 0a1b437

5 files changed

Lines changed: 87 additions & 26 deletions

File tree

src/doc/rustc-dev-guide/src/tests/compiletest.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,9 @@ to link to the extern crate to make the crate be available as an extern prelude.
665665
That allows you to specify the additional syntax of the `--extern` flag, such as
666666
renaming a dependency. For example, `//@ aux-crate:foo=bar.rs` will compile
667667
`auxiliary/bar.rs` and make it available under then name `foo` within the test.
668-
This is similar to how Cargo does dependency renaming.
668+
This is similar to how Cargo does dependency renaming. It is also possible to
669+
specify [`--extern` modifiers](https://github.com/rust-lang/rust/issues/98405).
670+
For example, `//@ aux-crate:noprelude:foo=bar.rs`.
669671

670672
`aux-bin` is similar to `aux-build` but will build a binary instead of a
671673
library. The binary will be available in `auxiliary/bin` relative to the working

src/doc/rustc-dev-guide/src/tests/directives.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ Directives can generally be found by browsing the
5353

5454
See [Building auxiliary crates](compiletest.html#building-auxiliary-crates)
5555

56-
| Directive | Explanation | Supported test suites | Possible values |
57-
|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|-----------------------------------------------|
58-
| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
59-
| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
60-
| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `<extern_prelude_name>=<path/to/aux/file.rs>` |
61-
| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file |
62-
| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file |
63-
| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A |
56+
| Directive | Explanation | Supported test suites | Possible values |
57+
|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|--------------------------------------------------------------------|
58+
| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
59+
| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
60+
| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `[<extern_modifiers>:]<extern_prelude_name>=<path/to/aux/file.rs>` |
61+
| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file |
62+
| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file |
63+
| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A |
6464

6565
[^pm]: please see the [Auxiliary proc-macro section](compiletest.html#auxiliary-proc-macro) in the compiletest chapter for specifics.
6666

src/tools/compiletest/src/directives/auxiliary.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ use std::iter;
66
use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO};
77
use crate::common::Config;
88
use crate::directives::DirectiveLine;
9+
use crate::util::static_regex;
10+
11+
#[cfg(test)]
12+
mod tests;
913

1014
/// The value of an `aux-crate` directive.
11-
#[derive(Clone, Debug, Default)]
15+
#[derive(Clone, Debug, Default, PartialEq, Eq)]
1216
pub struct AuxCrate {
17+
/// Contains `--extern` modifiers, if any. See the tracking issue for more
18+
/// info: <https://github.com/rust-lang/rust/issues/98405>
19+
/// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude`.
20+
pub extern_modifiers: Option<String>,
1321
/// With `aux-crate: foo=bar.rs` this will be `foo`.
14-
/// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude:foo`.
22+
/// With `aux-crate: noprelude:foo=bar.rs` this will be `foo`.
1523
pub name: String,
1624
/// With `aux-crate: foo=bar.rs` this will be `bar.rs`.
1725
pub path: String,
@@ -74,9 +82,20 @@ pub(super) fn parse_and_update_aux(
7482
}
7583

7684
fn parse_aux_crate(r: String) -> AuxCrate {
77-
let mut parts = r.trim().splitn(2, '=');
78-
AuxCrate {
79-
name: parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(),
80-
path: parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(),
81-
}
85+
let r = r.trim();
86+
87+
// Matches:
88+
// name=path
89+
// modifiers:name=path
90+
let caps = static_regex!(r"^(?:(?<modifiers>[^=]*?):)?(?<name>[^=]*)=(?<path>.*)$")
91+
.captures(r)
92+
.unwrap_or_else(|| {
93+
panic!("couldn't parse aux-crate value `{r}` (should be e.g. `log=log.rs`)")
94+
});
95+
96+
let modifiers = caps.name("modifiers").map(|m| m.as_str().to_string());
97+
let name = caps["name"].to_string();
98+
let path = caps["path"].to_string();
99+
100+
AuxCrate { extern_modifiers: modifiers, name, path }
82101
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use super::*;
2+
3+
#[test]
4+
fn test_aux_crate_value_no_modifiers() {
5+
assert_eq!(
6+
AuxCrate { extern_modifiers: None, name: "foo".to_string(), path: "foo.rs".to_string() },
7+
parse_aux_crate("foo=foo.rs".to_string())
8+
);
9+
}
10+
11+
#[test]
12+
fn test_aux_crate_value_with_modifiers() {
13+
assert_eq!(
14+
AuxCrate {
15+
extern_modifiers: Some("noprelude".to_string()),
16+
name: "foo".to_string(),
17+
path: "foo.rs".to_string()
18+
},
19+
parse_aux_crate("noprelude:foo=foo.rs".to_string())
20+
);
21+
}
22+
23+
#[test]
24+
#[should_panic(expected = "couldn't parse aux-crate value `foo.rs` (should be e.g. `log=log.rs`)")]
25+
fn test_aux_crate_value_invalid() {
26+
parse_aux_crate("foo.rs".to_string());
27+
}

src/tools/compiletest/src/runtest.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,23 +1277,36 @@ impl<'test> TestCx<'test> {
12771277
.replace('-', "_")
12781278
};
12791279

1280-
let add_extern =
1281-
|rustc: &mut Command, aux_name: &str, aux_path: &str, aux_type: AuxType| {
1282-
let lib_name = get_lib_name(&path_to_crate_name(aux_path), aux_type);
1283-
if let Some(lib_name) = lib_name {
1284-
rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir, lib_name));
1285-
}
1286-
};
1280+
let add_extern = |rustc: &mut Command,
1281+
extern_modifiers: Option<&str>,
1282+
aux_name: &str,
1283+
aux_path: &str,
1284+
aux_type: AuxType| {
1285+
let lib_name = get_lib_name(&path_to_crate_name(aux_path), aux_type);
1286+
if let Some(lib_name) = lib_name {
1287+
let modifiers_and_name = match extern_modifiers {
1288+
Some(modifiers) => format!("{modifiers}:{aux_name}"),
1289+
None => aux_name.to_string(),
1290+
};
1291+
rustc.arg("--extern").arg(format!("{modifiers_and_name}={aux_dir}/{lib_name}"));
1292+
}
1293+
};
12871294

1288-
for AuxCrate { name, path } in &self.props.aux.crates {
1295+
for AuxCrate { extern_modifiers, name, path } in &self.props.aux.crates {
12891296
let aux_type = self.build_auxiliary(&path, &aux_dir, None);
1290-
add_extern(rustc, name, path, aux_type);
1297+
add_extern(rustc, extern_modifiers.as_deref(), name, path, aux_type);
12911298
}
12921299

12931300
for proc_macro in &self.props.aux.proc_macros {
12941301
self.build_auxiliary(proc_macro, &aux_dir, Some(AuxType::ProcMacro));
12951302
let crate_name = path_to_crate_name(proc_macro);
1296-
add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro);
1303+
add_extern(
1304+
rustc,
1305+
None, // `extern_modifiers`
1306+
&crate_name,
1307+
proc_macro,
1308+
AuxType::ProcMacro,
1309+
);
12971310
}
12981311

12991312
// Build any `//@ aux-codegen-backend`, and pass the resulting library

0 commit comments

Comments
 (0)