compiletest: add aux-crate directive
This commit is contained in:
parent
590dd7dfef
commit
60d4e20ff0
11 changed files with 129 additions and 116 deletions
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
dep::somefun();
|
||||
}
|
|
@ -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.
|
||||
|
|
11
src/test/ui/extern-flag/noprelude-resolves.rs
Normal file
11
src/test/ui/extern-flag/noprelude-resolves.rs
Normal 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();
|
||||
}
|
7
src/test/ui/extern-flag/noprelude.rs
Normal file
7
src/test/ui/extern-flag/noprelude.rs
Normal 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
|
||||
}
|
9
src/test/ui/extern-flag/noprelude.stderr
Normal file
9
src/test/ui/extern-flag/noprelude.stderr
Normal 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`.
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue