Skip to content

Commit 94f8359

Browse files
committed
Handle --extern-private properly on musl
On musl (and some other platforms), compiletest ends up creating a static rlib (instead of a dylib) when building 'aux-build' crates. This commit changes the '--extern-private' path computed by compiletest to properly take this into account
1 parent eb15d2f commit 94f8359

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/tools/compiletest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![crate_name = "compiletest"]
22
#![feature(test)]
3+
#![feature(vec_remove_item)]
34
#![deny(warnings, rust_2018_idioms)]
45

56
#[cfg(unix)]

src/tools/compiletest/src/runtest.rs

+34-8
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,15 @@ pub fn dylib_env_var() -> &'static str {
7575
}
7676

7777
/// The platform-specific library file extension
78-
pub fn lib_extension() -> &'static str {
78+
pub fn lib_extension(dylib: bool) -> &'static str {
79+
// In some casess (e.g. MUSL), we build a static
80+
// library, rather than a dynamic library.
81+
// In this case, the only path we can pass
82+
// with '--extern-meta' is the '.lib' file
83+
if !dylib {
84+
return ".rlib"
85+
}
86+
7987
if cfg!(windows) {
8088
".dll"
8189
} else if cfg!(target_os = "macos") {
@@ -1596,12 +1604,15 @@ impl<'test> TestCx<'test> {
15961604
create_dir_all(&aux_dir).unwrap();
15971605
}
15981606

1599-
for priv_dep in &self.props.extern_private {
1600-
let lib_name = format!("lib{}{}", priv_dep, lib_extension());
1607+
// Use a Vec instead of a HashMap to preserve original order
1608+
let mut extern_priv = self.props.extern_private.clone();
1609+
1610+
let mut add_extern_priv = |priv_dep: &str, dylib: bool| {
1611+
let lib_name = format!("lib{}{}", priv_dep, lib_extension(dylib));
16011612
rustc
16021613
.arg("--extern-private")
16031614
.arg(format!("{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap()));
1604-
}
1615+
};
16051616

16061617
for rel_ab in &self.props.aux_builds {
16071618
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
@@ -1619,8 +1630,8 @@ impl<'test> TestCx<'test> {
16191630
create_dir_all(aux_cx.output_base_dir()).unwrap();
16201631
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
16211632

1622-
let crate_type = if aux_props.no_prefer_dynamic {
1623-
None
1633+
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
1634+
(true, None)
16241635
} else if self.config.target.contains("cloudabi")
16251636
|| self.config.target.contains("emscripten")
16261637
|| (self.config.target.contains("musl") && !aux_props.force_host)
@@ -1636,11 +1647,20 @@ impl<'test> TestCx<'test> {
16361647
// dynamic libraries so we just go back to building a normal library. Note,
16371648
// however, that for MUSL if the library is built with `force_host` then
16381649
// it's ok to be a dylib as the host should always support dylibs.
1639-
Some("lib")
1650+
(false, Some("lib"))
16401651
} else {
1641-
Some("dylib")
1652+
(true, Some("dylib"))
16421653
};
16431654

1655+
let trimmed = rel_ab.trim_end_matches(".rs").to_string();
1656+
1657+
// Normally, every 'extern-private' has a correspodning 'aux-build'
1658+
// entry. If so, we remove it from our list of private crates,
1659+
// and add an '--extern-private' flag to rustc
1660+
if extern_priv.remove_item(&trimmed).is_some() {
1661+
add_extern_priv(&trimmed, dylib);
1662+
}
1663+
16441664
if let Some(crate_type) = crate_type {
16451665
aux_rustc.args(&["--crate-type", crate_type]);
16461666
}
@@ -1664,6 +1684,12 @@ impl<'test> TestCx<'test> {
16641684
}
16651685
}
16661686

1687+
// Add any '--extenr-private' entries without a matching
1688+
// 'aux-build'
1689+
for private_lib in extern_priv {
1690+
add_extern_priv(&private_lib, true);
1691+
}
1692+
16671693
rustc.envs(self.props.rustc_env.clone());
16681694
self.compose_and_run(
16691695
rustc,

0 commit comments

Comments
 (0)