Auto merge of #125031 - Oneirical:dynamic-libs, r=jieyouxu

Migrate `run-make/issue-11908` to new `rmake.rs` format

Part of #121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html).

Set as draft, because I have a few concerns:

- [x] I am not sure if `target().contains("darwin")` is a good way of checking that the target is on OSX.
- [x] I find it strange that the `dylib` part of the test adapts to different target platforms, but not the `rlib` part. Is `rlib` named the same on all platforms?
This commit is contained in:
bors 2024-05-15 02:10:09 +00:00
commit 9e7aff7945
8 changed files with 79 additions and 37 deletions

View File

@ -40,12 +40,17 @@ pub fn target() -> String {
/// Check if target is windows-like.
pub fn is_windows() -> bool {
env::var_os("IS_WINDOWS").is_some()
target().contains("windows")
}
/// Check if target uses msvc.
pub fn is_msvc() -> bool {
env::var_os("IS_MSVC").is_some()
target().contains("msvc")
}
/// Check if target uses macOS.
pub fn is_darwin() -> bool {
target().contains("darwin")
}
/// Construct a path to a static library under `$TMPDIR` given the library name. This will return a
@ -82,9 +87,47 @@ pub fn static_lib_name(name: &str) -> String {
// endif
// endif
// ```
assert!(!name.contains(char::is_whitespace), "name cannot contain whitespace");
assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
if target().contains("msvc") { format!("{name}.lib") } else { format!("lib{name}.a") }
if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
}
/// Construct a path to a dynamic library under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
pub fn dynamic_lib(name: &str) -> PathBuf {
tmp_dir().join(dynamic_lib_name(name))
}
/// Construct the dynamic library name based on the platform.
pub fn dynamic_lib_name(name: &str) -> String {
// See tools.mk (irrelevant lines omitted):
//
// ```makefile
// ifeq ($(UNAME),Darwin)
// DYLIB = $(TMPDIR)/lib$(1).dylib
// else
// ifdef IS_WINDOWS
// DYLIB = $(TMPDIR)/$(1).dll
// else
// DYLIB = $(TMPDIR)/lib$(1).so
// endif
// endif
// ```
assert!(!name.contains(char::is_whitespace), "dynamic library name cannot contain whitespace");
if is_darwin() {
format!("lib{name}.dylib")
} else if is_windows() {
format!("{name}.dll")
} else {
format!("lib{name}.so")
}
}
/// Construct a path to a rust library (rlib) under `$TMPDIR` given the library name. This will return a
/// path with `$TMPDIR` joined with the library name.
pub fn rust_lib(name: &str) -> PathBuf {
tmp_dir().join(format!("lib{name}.rlib"))
}
/// Construct the binary name based on platform.

View File

@ -91,7 +91,7 @@ pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self
}
/// Specify path to the output file.
/// Specify path to the output file. Equivalent to `-o`` in rustc.
pub fn output<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("-o");
self.cmd.arg(path.as_ref());
@ -150,13 +150,7 @@ pub fn crate_type(&mut self, crate_type: &str) -> &mut Self {
self
}
/// Enables link time optimizations in rustc. Equivalent to `-Clto``.
pub fn lto(&mut self) -> &mut Self {
self.cmd.arg("-Clto");
self
}
/// Add a directory to the library search path.
/// Add a directory to the library search path. Equivalent to `-L`` in rustc.
pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg("-L");
self.cmd.arg(path.as_ref());

View File

@ -94,7 +94,6 @@ run-make/invalid-staticlib/Makefile
run-make/issue-107094/Makefile
run-make/issue-10971-temps-dir/Makefile
run-make/issue-109934-lto-debuginfo/Makefile
run-make/issue-11908/Makefile
run-make/issue-14698/Makefile
run-make/issue-15460/Makefile
run-make/issue-18943/Makefile

View File

@ -1,22 +0,0 @@
# ignore-cross-compile
# This test ensures that if you have the same rlib or dylib at two locations
# in the same path that you don't hit an assertion in the compiler.
#
# Note that this relies on `liburl` to be in the path somewhere else,
# and then our aux-built libraries will collide with liburl (they have
# the same version listed)
include ../tools.mk
all:
mkdir $(TMPDIR)/other
$(RUSTC) foo.rs --crate-type=dylib -C prefer-dynamic
mv $(call DYLIB,foo) $(TMPDIR)/other
$(RUSTC) foo.rs --crate-type=dylib -C prefer-dynamic
$(RUSTC) bar.rs -L $(TMPDIR)/other
rm -rf $(TMPDIR)
mkdir -p $(TMPDIR)/other
$(RUSTC) foo.rs --crate-type=rlib
mv $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
$(RUSTC) foo.rs --crate-type=rlib
$(RUSTC) bar.rs -L $(TMPDIR)/other

View File

@ -9,7 +9,7 @@
//@ ignore-cross-compile
use run_make_support::{cc, extra_c_flags, run, rustc, static_lib, tmp_dir};
use run_make_support::{cc, extra_c_flags, run, rustc, static_lib};
fn main() {
let libbar_path = static_lib("bar");
@ -17,7 +17,7 @@ fn main() {
rustc()
.input("bar.rs")
.crate_type("staticlib")
.lto()
.arg("-Clto")
.library_search_path(".")
.output(&libbar_path)
.run();

View File

@ -0,0 +1,28 @@
// A path which contains the same rlib or dylib in two locations
// should not cause an assertion panic in the compiler.
// This test tries to replicate the linked issue and checks
// if the bugged error makes a resurgence.
// See https://github.com/rust-lang/rust/issues/11908
//@ ignore-cross-compile
use run_make_support::{dynamic_lib, rust_lib, rustc, tmp_dir};
use std::fs;
fn main() {
let tmp_dir_other = tmp_dir().join("other");
fs::create_dir(&tmp_dir_other);
rustc().input("foo.rs").crate_type("dylib").arg("-Cprefer-dynamic").run();
fs::rename(dynamic_lib("foo"), &tmp_dir_other);
rustc().input("foo.rs").crate_type("dylib").arg("-Cprefer-dynamic").run();
rustc().input("bar.rs").library_search_path(&tmp_dir_other).run();
fs::remove_dir_all(tmp_dir());
fs::create_dir_all(&tmp_dir_other);
rustc().input("foo.rs").crate_type("rlib").run();
fs::rename(rust_lib("foo"), &tmp_dir_other);
rustc().input("foo.rs").crate_type("rlib").run();
rustc().input("bar.rs").library_search_path(tmp_dir_other).run();
}