about summary refs log tree commit diff
path: root/src/tools
diff options
context:
space:
mode:
authorEric Huss <eric@huss.org>2019-12-05 16:26:21 -0800
committerEric Huss <eric@huss.org>2019-12-09 08:08:27 -0800
commit60d4e20ff07ac4546f47f09094c7c04b577f0966 (patch)
tree968239eaa2584fd2ba3c1362f291ce064cc2e9fa /src/tools
parent590dd7dfef3e835756edb5f920bf31cd19eef4d0 (diff)
downloadrust-60d4e20ff07ac4546f47f09094c7c04b577f0966.tar.gz
rust-60d4e20ff07ac4546f47f09094c7c04b577f0966.zip
compiletest: add aux-crate directive
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/compiletest/src/header.rs29
-rw-r--r--src/tools/compiletest/src/runtest.rs159
2 files changed, 95 insertions, 93 deletions
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index ca30e782c50..46cce6394e6 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -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> {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index ca68fe3e39b..480868440b8 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -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,