compiletest: support auxiliaries with auxiliaries
To test behaviour that depends on the extern options of intermediate crates, compiletest auxiliaries must have their own auxiliaries. Auxiliary compilation previously did not trigger compilation of any auxiliaries in the auxiliary's headers. In addition, those auxiliaries would need to be in an `auxiliary/auxiliary` directory, which is unnecessary and makes some crate graphs harder to write tests for, such as when A depends on B and C, and B depends on C. For a test `tests/ui/$path/root.rs`, with the following crate graph: ``` root |-- grandparent `-- parent `-- grandparent ``` then the intermediate outputs from compiletest will be: ``` build/$target/test/ui/$path/ |-- auxiliary | |-- libgrandparent.dylib | |-- libparent.dylib | |-- grandparent | | |-- grandparent.err | | `-- grandparent.out | `-- parent | |-- parent.err | `-- parent.out |-- libroot.rmeta |-- root.err `-- root.out ``` Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
29f87ade9d
commit
a2aa9672f6
@ -1936,7 +1936,7 @@ fn compile_test_general(
|
|||||||
fn document(&self, out_dir: &Path) -> ProcRes {
|
fn document(&self, out_dir: &Path) -> ProcRes {
|
||||||
if self.props.build_aux_docs {
|
if self.props.build_aux_docs {
|
||||||
for rel_ab in &self.props.aux_builds {
|
for rel_ab in &self.props.aux_builds {
|
||||||
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
|
let aux_testpaths = self.compute_aux_test_paths(&self.testpaths, rel_ab);
|
||||||
let aux_props =
|
let aux_props =
|
||||||
self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
||||||
let aux_cx = TestCx {
|
let aux_cx = TestCx {
|
||||||
@ -2092,24 +2092,18 @@ fn exec_compiled_test_general(
|
|||||||
proc_res
|
proc_res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For each `aux-build: foo/bar` annotation, we check to find the
|
/// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary`
|
||||||
/// file in an `auxiliary` directory relative to the test itself.
|
/// directory relative to the test itself (not any intermediate auxiliaries).
|
||||||
fn compute_aux_test_paths(&self, rel_ab: &str) -> TestPaths {
|
fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> TestPaths {
|
||||||
let test_ab = self
|
let test_ab =
|
||||||
.testpaths
|
of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab);
|
||||||
.file
|
|
||||||
.parent()
|
|
||||||
.expect("test file path has no parent")
|
|
||||||
.join("auxiliary")
|
|
||||||
.join(rel_ab);
|
|
||||||
if !test_ab.exists() {
|
if !test_ab.exists() {
|
||||||
self.fatal(&format!("aux-build `{}` source not found", test_ab.display()))
|
self.fatal(&format!("aux-build `{}` source not found", test_ab.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
TestPaths {
|
TestPaths {
|
||||||
file: test_ab,
|
file: test_ab,
|
||||||
relative_dir: self
|
relative_dir: of
|
||||||
.testpaths
|
|
||||||
.relative_dir
|
.relative_dir
|
||||||
.join(self.output_testname_unique())
|
.join(self.output_testname_unique())
|
||||||
.join("auxiliary")
|
.join("auxiliary")
|
||||||
@ -2135,7 +2129,7 @@ fn is_vxworks_pure_dynamic(&self) -> bool {
|
|||||||
self.config.target.contains("vxworks") && !self.is_vxworks_pure_static()
|
self.config.target.contains("vxworks") && !self.is_vxworks_pure_static()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_all_auxiliary(&self, rustc: &mut Command) -> PathBuf {
|
fn aux_output_dir(&self) -> PathBuf {
|
||||||
let aux_dir = self.aux_output_dir_name();
|
let aux_dir = self.aux_output_dir_name();
|
||||||
|
|
||||||
if !self.props.aux_builds.is_empty() {
|
if !self.props.aux_builds.is_empty() {
|
||||||
@ -2143,22 +2137,26 @@ fn build_all_auxiliary(&self, rustc: &mut Command) -> PathBuf {
|
|||||||
create_dir_all(&aux_dir).unwrap();
|
create_dir_all(&aux_dir).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aux_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Path, rustc: &mut Command) {
|
||||||
for rel_ab in &self.props.aux_builds {
|
for rel_ab in &self.props.aux_builds {
|
||||||
self.build_auxiliary(rel_ab, &aux_dir);
|
self.build_auxiliary(of, rel_ab, &aux_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (aux_name, aux_path) in &self.props.aux_crates {
|
for (aux_name, aux_path) in &self.props.aux_crates {
|
||||||
let is_dylib = self.build_auxiliary(&aux_path, &aux_dir);
|
let is_dylib = self.build_auxiliary(of, &aux_path, &aux_dir);
|
||||||
let lib_name =
|
let lib_name =
|
||||||
get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
|
get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
|
||||||
rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
|
rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
aux_dir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
|
fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
|
||||||
let aux_dir = self.build_all_auxiliary(&mut rustc);
|
let aux_dir = self.aux_output_dir();
|
||||||
|
self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc);
|
||||||
|
|
||||||
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
|
self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove);
|
||||||
rustc.envs(self.props.rustc_env.clone());
|
rustc.envs(self.props.rustc_env.clone());
|
||||||
self.compose_and_run(
|
self.compose_and_run(
|
||||||
@ -2172,10 +2170,10 @@ fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) ->
|
|||||||
/// Builds an aux dependency.
|
/// Builds an aux dependency.
|
||||||
///
|
///
|
||||||
/// Returns whether or not it is a dylib.
|
/// Returns whether or not it is a dylib.
|
||||||
fn build_auxiliary(&self, source_path: &str, aux_dir: &Path) -> bool {
|
fn build_auxiliary(&self, of: &TestPaths, source_path: &str, aux_dir: &Path) -> bool {
|
||||||
let aux_testpaths = self.compute_aux_test_paths(source_path);
|
let aux_testpaths = self.compute_aux_test_paths(of, source_path);
|
||||||
let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
||||||
let aux_output = TargetLocation::ThisDirectory(self.aux_output_dir_name());
|
let aux_output = TargetLocation::ThisDirectory(aux_dir.to_path_buf());
|
||||||
let aux_cx = TestCx {
|
let aux_cx = TestCx {
|
||||||
config: self.config,
|
config: self.config,
|
||||||
props: &aux_props,
|
props: &aux_props,
|
||||||
@ -2193,6 +2191,7 @@ fn build_auxiliary(&self, source_path: &str, aux_dir: &Path) -> bool {
|
|||||||
LinkToAux::No,
|
LinkToAux::No,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
);
|
);
|
||||||
|
aux_cx.build_all_auxiliary(of, aux_dir, &mut aux_rustc);
|
||||||
|
|
||||||
for key in &aux_props.unset_rustc_env {
|
for key in &aux_props.unset_rustc_env {
|
||||||
aux_rustc.env_remove(key);
|
aux_rustc.env_remove(key);
|
||||||
@ -3034,7 +3033,8 @@ fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
|
|||||||
LinkToAux::Yes,
|
LinkToAux::Yes,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
);
|
);
|
||||||
new_rustdoc.build_all_auxiliary(&mut rustc);
|
let aux_dir = new_rustdoc.aux_output_dir();
|
||||||
|
new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc);
|
||||||
|
|
||||||
let proc_res = new_rustdoc.document(&compare_dir);
|
let proc_res = new_rustdoc.document(&compare_dir);
|
||||||
if !proc_res.status.success() {
|
if !proc_res.status.success() {
|
||||||
|
14
tests/ui/compiletest-self-test/aux-aux.rs
Normal file
14
tests/ui/compiletest-self-test/aux-aux.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//@ aux-crate: aux_aux_foo=aux_aux_foo.rs
|
||||||
|
//@ aux-crate: aux_aux_bar=aux_aux_bar.rs
|
||||||
|
//@ edition: 2021
|
||||||
|
//@ compile-flags: --crate-type lib
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
use aux_aux_foo::Bar as IndirectBar;
|
||||||
|
use aux_aux_bar::Bar as DirectBar;
|
||||||
|
|
||||||
|
fn foo(x: IndirectBar) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(DirectBar);
|
||||||
|
}
|
3
tests/ui/compiletest-self-test/auxiliary/aux_aux_bar.rs
Normal file
3
tests/ui/compiletest-self-test/auxiliary/aux_aux_bar.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
pub struct Bar;
|
4
tests/ui/compiletest-self-test/auxiliary/aux_aux_foo.rs
Normal file
4
tests/ui/compiletest-self-test/auxiliary/aux_aux_foo.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
//@ aux-crate: aux_aux_bar=aux_aux_bar.rs
|
||||||
|
//@ edition: 2021
|
||||||
|
|
||||||
|
pub use aux_aux_bar::Bar;
|
Loading…
Reference in New Issue
Block a user