compiletest: add aux-crate directive

This commit is contained in:
Eric Huss 2019-12-05 16:26:21 -08:00
parent 590dd7dfef
commit 60d4e20ff0
11 changed files with 129 additions and 116 deletions

View File

@ -1,11 +0,0 @@
-include ../tools.mk
# Test --extern noprelude
all:
$(RUSTC) dep.rs --crate-name=dep --crate-type=rlib
$(RUSTC) foo.rs --edition=2018 -Zunstable-options \
--extern noprelude:dep=$(TMPDIR)/libdep.rlib 2>&1 | \
$(CGREP) -e 'failed to resolve.*`dep`'
$(RUSTC) foo.rs --edition=2018 -Zunstable-options \
--extern dep=$(TMPDIR)/libdep.rlib

View File

@ -1,3 +0,0 @@
fn main() {
dep::somefun();
}

View File

@ -1,6 +1,5 @@
// aux-build:issue-66159-1.rs
// aux-crate:priv:issue_66159_1=issue-66159-1.rs
// compile-flags:-Z unstable-options
// extern-private:issue_66159_1
// The issue was an ICE which meant that we never actually generated the docs
// so if we have generated the docs, we're okay.

View File

@ -0,0 +1,11 @@
// check-pass
// aux-crate:noprelude:somedep=somedep.rs
// compile-flags: -Zunstable-options
// edition:2018
// `extern crate` can be used to add to prelude.
extern crate somedep;
fn main() {
somedep::somefun();
}

View File

@ -0,0 +1,7 @@
// aux-crate:noprelude:somedep=somedep.rs
// compile-flags: -Zunstable-options
// edition:2018
fn main() {
somedep::somefun(); //~ ERROR failed to resolve
}

View File

@ -0,0 +1,9 @@
error[E0433]: failed to resolve: use of undeclared type or module `somedep`
--> $DIR/noprelude.rs:6:5
|
LL | somedep::somefun();
| ^^^^^^^ use of undeclared type or module `somedep`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0433`.

View File

@ -1,11 +1,10 @@
// aux-build:priv_dep.rs
// aux-crate:priv:priv_dep=priv_dep.rs
// aux-build:pub_dep.rs
// extern-private:priv_dep
#![deny(exported_private_dependencies)]
// This crate is a private dependency
extern crate priv_dep;
// This crate is a public dependenct
// This crate is a public dependency
extern crate pub_dep;
use priv_dep::{OtherType, OtherTrait};

View File

@ -1,23 +1,23 @@
error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:21:5
--> $DIR/pub-priv1.rs:20:5
|
LL | pub field: OtherType,
| ^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/pub-priv1.rs:4:9
--> $DIR/pub-priv1.rs:3:9
|
LL | #![deny(exported_private_dependencies)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:28:5
--> $DIR/pub-priv1.rs:27:5
|
LL | pub fn pub_fn(param: OtherType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface
--> $DIR/pub-priv1.rs:34:1
--> $DIR/pub-priv1.rs:33:1
|
LL | / pub trait MyPubTrait {
LL | | type Foo: OtherTrait;

View File

@ -71,6 +71,7 @@ pub struct EarlyProps {
pub ignore: Ignore,
pub should_fail: bool,
pub aux: Vec<String>,
pub aux_crate: Vec<(String, String)>,
pub revisions: Vec<String>,
}
@ -80,6 +81,7 @@ impl EarlyProps {
ignore: Ignore::Run,
should_fail: false,
aux: Vec::new(),
aux_crate: Vec::new(),
revisions: vec![],
};
@ -157,6 +159,10 @@ impl EarlyProps {
props.aux.push(s);
}
if let Some(ac) = config.parse_aux_crate(ln) {
props.aux_crate.push(ac);
}
if let Some(r) = config.parse_revisions(ln) {
props.revisions.extend(r);
}
@ -311,10 +317,9 @@ pub struct TestProps {
// directory as the test, but for backwards compatibility reasons
// we also check the auxiliary directory)
pub aux_builds: Vec<String>,
// A list of crates to pass '--extern priv:name=PATH' flags for
// This should be a subset of 'aux_build'
// FIXME: Replace this with a better solution: https://github.com/rust-lang/rust/pull/54020
pub extern_private: Vec<String>,
// Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
// to build and pass with the `--extern` flag.
pub aux_crates: Vec<(String, String)>,
// Environment settings to use for compiling
pub rustc_env: Vec<(String, String)>,
// Environment variables to unset prior to compiling.
@ -387,7 +392,7 @@ impl TestProps {
run_flags: None,
pp_exact: None,
aux_builds: vec![],
extern_private: vec![],
aux_crates: vec![],
revisions: vec![],
rustc_env: vec![],
unset_rustc_env: vec![],
@ -514,8 +519,8 @@ impl TestProps {
self.aux_builds.push(ab);
}
if let Some(ep) = config.parse_extern_private(ln) {
self.extern_private.push(ep);
if let Some(ac) = config.parse_aux_crate(ln) {
self.aux_crates.push(ac);
}
if let Some(ee) = config.parse_env(ln, "exec-env") {
@ -713,8 +718,14 @@ impl Config {
.map(|r| r.trim().to_string())
}
fn parse_extern_private(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "extern-private")
fn parse_aux_crate(&self, line: &str) -> Option<(String, String)> {
self.parse_name_value_directive(line, "aux-crate").map(|r| {
let mut parts = r.trim().splitn(2, '=');
(
parts.next().expect("aux-crate name").to_string(),
parts.next().expect("aux-crate value").to_string(),
)
})
}
fn parse_compile_flags(&self, line: &str) -> Option<String> {

View File

@ -1776,93 +1776,16 @@ impl<'test> TestCx<'test> {
create_dir_all(&aux_dir).unwrap();
}
// Use a Vec instead of a HashMap to preserve original order
let mut extern_priv = self.props.extern_private.clone();
let mut add_extern_priv = |priv_dep: &str, dylib: bool| {
let lib_name = get_lib_name(priv_dep, dylib);
rustc
.arg("--extern")
.arg(format!("priv:{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap()));
};
for rel_ab in &self.props.aux_builds {
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
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_cx = TestCx {
config: self.config,
props: &aux_props,
testpaths: &aux_testpaths,
revision: self.revision,
};
// Create the directory for the stdout/stderr files.
create_dir_all(aux_cx.output_base_dir()).unwrap();
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
(true, None)
} else if self.config.target.contains("cloudabi")
|| self.config.target.contains("emscripten")
|| (self.config.target.contains("musl")
&& !aux_props.force_host
&& !self.config.host.contains("musl"))
|| self.config.target.contains("wasm32")
|| self.config.target.contains("nvptx")
|| self.is_vxworks_pure_static()
{
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible
// for the test suite (otherwise including libstd statically in all
// executables takes up quite a bit of space).
//
// For targets like MUSL or Emscripten, however, there is no support for
// dynamic libraries so we just go back to building a normal library. Note,
// however, that for MUSL if the library is built with `force_host` then
// it's ok to be a dylib as the host should always support dylibs.
(false, Some("lib"))
} else {
(true, Some("dylib"))
};
let trimmed = rel_ab.trim_end_matches(".rs").to_string();
// Normally, every 'extern-private' has a corresponding 'aux-build'
// entry. If so, we remove it from our list of private crates,
// and add an '--extern priv:NAME=PATH' flag to rustc
if extern_priv.remove_item(&trimmed).is_some() {
add_extern_priv(&trimmed, dylib);
}
if let Some(crate_type) = crate_type {
aux_rustc.args(&["--crate-type", crate_type]);
}
aux_rustc.arg("-L").arg(&aux_dir);
let auxres = aux_cx.compose_and_run(
aux_rustc,
aux_cx.config.compile_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
None,
);
if !auxres.status.success() {
self.fatal_proc_rec(
&format!(
"auxiliary build of {:?} failed to compile: ",
aux_testpaths.file.display()
),
&auxres,
);
}
self.build_auxiliary(rel_ab, &aux_dir);
}
// Add any '--extern' private entries without a matching
// 'aux-build'
for private_lib in extern_priv {
add_extern_priv(&private_lib, true);
for (aux_name, aux_path) in &self.props.aux_crates {
let is_dylib = self.build_auxiliary(&aux_path, &aux_dir);
let lib_name = get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"),
is_dylib);
rustc.arg("--extern")
.arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
}
self.props.unset_rustc_env.clone()
@ -1877,6 +1800,74 @@ impl<'test> TestCx<'test> {
)
}
/// Builds an aux dependency.
///
/// Returns whether or not it is a dylib.
fn build_auxiliary(&self, source_path: &str, aux_dir: &Path) -> bool {
let aux_testpaths = self.compute_aux_test_paths(source_path);
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_cx = TestCx {
config: self.config,
props: &aux_props,
testpaths: &aux_testpaths,
revision: self.revision,
};
// Create the directory for the stdout/stderr files.
create_dir_all(aux_cx.output_base_dir()).unwrap();
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
(true, None)
} else if self.config.target.contains("cloudabi")
|| self.config.target.contains("emscripten")
|| (self.config.target.contains("musl")
&& !aux_props.force_host
&& !self.config.host.contains("musl"))
|| self.config.target.contains("wasm32")
|| self.config.target.contains("nvptx")
|| self.is_vxworks_pure_static()
{
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible
// for the test suite (otherwise including libstd statically in all
// executables takes up quite a bit of space).
//
// For targets like MUSL or Emscripten, however, there is no support for
// dynamic libraries so we just go back to building a normal library. Note,
// however, that for MUSL if the library is built with `force_host` then
// it's ok to be a dylib as the host should always support dylibs.
(false, Some("lib"))
} else {
(true, Some("dylib"))
};
if let Some(crate_type) = crate_type {
aux_rustc.args(&["--crate-type", crate_type]);
}
aux_rustc.arg("-L").arg(&aux_dir);
let auxres = aux_cx.compose_and_run(
aux_rustc,
aux_cx.config.compile_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
None,
);
if !auxres.status.success() {
self.fatal_proc_rec(
&format!(
"auxiliary build of {:?} failed to compile: ",
aux_testpaths.file.display()
),
&auxres,
);
}
dylib
}
fn compose_and_run(
&self,
mut command: Command,