rewrite prune-link-args to rmake format

This commit is contained in:
Oneirical 2024-06-09 16:37:31 -04:00
parent b55fa8f757
commit 3b495bb60b
8 changed files with 99 additions and 80 deletions

View File

@ -1,7 +1,7 @@
use std::path::Path;
use crate::command::Command;
use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname};
use crate::{cygpath_windows, env_var, is_msvc, is_windows, uname};
/// Construct a new platform-specific C compiler invocation.
///
@ -68,9 +68,14 @@ pub fn out_exe(&mut self, name: &str) -> &mut Self {
// endif
// ```
let mut path = std::path::PathBuf::from(name);
if is_msvc() {
let fe_path = cygpath_windows(bin_name(name));
let fo_path = cygpath_windows(format!("{name}.obj"));
path.set_extension("exe");
let fe_path = cygpath_windows(&path);
path.set_extension("");
path.set_extension("obj");
let fo_path = cygpath_windows(path);
self.cmd.arg(format!("-Fe:{fe_path}"));
self.cmd.arg(format!("-Fo:{fo_path}"));
} else {

View File

@ -294,6 +294,26 @@ pub fn not_contains<P: AsRef<Path>>(path: P, expected: &str) -> bool {
!path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected))
}
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
#[track_caller]
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
let src = format!("{lib_name}.c");
let lib_path = static_lib_name(lib_name);
if is_msvc() {
cc().arg("-c").out_exe(&obj_file).input(src).run();
} else {
cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run();
};
let mut obj_file = PathBuf::from(format!("{lib_name}.o"));
if is_msvc() {
obj_file.set_extension("");
obj_file.set_extension("obj");
}
ar(&[obj_file], &lib_path);
path(lib_path)
}
/// Returns true if the filename at `path` is not in `expected`.
pub fn filename_not_in_denylist<P: AsRef<Path>, V: AsRef<[String]>>(path: P, expected: V) -> bool {
let expected = expected.as_ref();

View File

@ -135,6 +135,9 @@ pub fn remap_path_prefix<P: AsRef<Path>, P2: AsRef<Path>>(
self.cmd.arg("--remap-path-prefix");
self.cmd.arg(format!("{from}={to}"));
self
}
/// Specify path to the input file.
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());
@ -239,7 +242,8 @@ pub fn library_search_path<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self
}
/// Add a directory to the library search path with a restriction. Equivalent to `-L KIND=PATH` in rustc.
/// Add a directory to the library search path with a restriction, where `kind` is a dependency
/// type. Equivalent to `-L KIND=PATH` in rustc.
pub fn specific_library_search_path<P: AsRef<Path>>(
&mut self,
kind: &str,

View File

@ -94,7 +94,6 @@ run-make/pgo-indirect-call-promotion/Makefile
run-make/pointer-auth-link-with-c/Makefile
run-make/print-calling-conventions/Makefile
run-make/print-target-list/Makefile
run-make/prune-link-args/Makefile
run-make/raw-dylib-alt-calling-convention/Makefile
run-make/raw-dylib-c/Makefile
run-make/raw-dylib-custom-dlltool/Makefile

View File

@ -5,99 +5,80 @@
// fail to be used by the compiler.
// See https://github.com/rust-lang/rust/pull/19941
use run_make_support::fs_wrapper;
use run_make_support::{rmake_out_path, rustc};
//@ ignore-wasm32
//@ ignore-wasm64
// Reason: a C compiler is required for build_native_static_lib
use run_make_support::{build_native_static_lib, fs_wrapper, rustc, static_lib_name};
fn main() {
assert!(rmake_out_path("libnative.a").exists());
fs_wrapper::create_dir_all(rmake_out_path("crate"));
fs_wrapper::create_dir_all(rmake_out_path("native"));
fs_wrapper::rename(rmake_out_path("libnative.a"), rmake_out_path("native"));
build_native_static_lib("native");
let lib_native = static_lib_name("native");
fs_wrapper::create_dir_all("crate");
fs_wrapper::create_dir_all("native");
fs_wrapper::rename(&lib_native, format!("native/{}", &lib_native));
rustc().input("a.rs").run();
fs_wrapper::rename(rmake_out_path("liba.a"), rmake_out_path("crate"));
rustc()
.input("b.rs")
.specific_library_search_path("native", rmake_out_path("crate"))
.run_fail();
rustc()
.input("b.rs")
.specific_library_search_path("dependency", rmake_out_path("crate"))
.run_fail();
rustc().input("b.rs").specific_library_search_path("crate", rmake_out_path("crate")).run();
rustc().input("b.rs").specific_library_search_path("all", rmake_out_path("crate")).run();
fs_wrapper::rename("liba.rlib", "crate/liba.rlib");
rustc().input("b.rs").specific_library_search_path("native", "crate").run_fail();
rustc().input("b.rs").specific_library_search_path("dependency", "crate").run_fail();
rustc().input("b.rs").specific_library_search_path("crate", "crate").run();
rustc().input("b.rs").specific_library_search_path("all", "crate").run();
rustc()
.input("c.rs")
.specific_library_search_path("native", rmake_out_path("crate"))
.run_fail();
rustc().input("c.rs").specific_library_search_path("crate", rmake_out_path("crate")).run_fail();
rustc().input("c.rs").specific_library_search_path("dependency", rmake_out_path("crate")).run();
rustc().input("c.rs").specific_library_search_path("all", rmake_out_path("crate")).run();
rustc().input("c.rs").specific_library_search_path("native", "crate").run_fail();
rustc().input("c.rs").specific_library_search_path("crate", "crate").run_fail();
rustc().input("c.rs").specific_library_search_path("dependency", "crate").run();
rustc().input("c.rs").specific_library_search_path("all", "crate").run();
rustc()
.input("d.rs")
.specific_library_search_path("dependency", rmake_out_path("native"))
.run_fail();
rustc()
.input("d.rs")
.specific_library_search_path("crate", rmake_out_path("native"))
.run_fail();
rustc().input("d.rs").specific_library_search_path("native", rmake_out_path("native")).run();
rustc().input("d.rs").specific_library_search_path("all", rmake_out_path("native")).run();
rustc().input("d.rs").specific_library_search_path("dependency", "native").run_fail();
rustc().input("d.rs").specific_library_search_path("crate", "native").run_fail();
rustc().input("d.rs").specific_library_search_path("native", "native").run();
rustc().input("d.rs").specific_library_search_path("all", "native").run();
// Deduplication tests.
fs_wrapper::create_dir_all(rmake_out_path("e1"));
fs_wrapper::create_dir_all(rmake_out_path("e2"));
fs_wrapper::create_dir_all("e1");
fs_wrapper::create_dir_all("e2");
rustc().input("e.rs").output(rmake_out_path("e1/libe.rlib")).run();
rustc().input("e.rs").output(rmake_out_path("e2/libe.rlib")).run();
rustc().input("e.rs").output("e1/libe.rlib").run();
rustc().input("e.rs").output("e2/libe.rlib").run();
// If the library hash is correct, compilation should succeed.
rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run();
rustc()
.input("f.rs")
.library_search_path(rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.specific_library_search_path("crate", "e1")
.library_search_path("e2")
.run();
rustc()
.input("f.rs")
.specific_library_search_path("crate", rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.run();
rustc()
.input("f.rs")
.specific_library_search_path("crate", rmake_out_path("e1"))
.specific_library_search_path("crate", rmake_out_path("e2"))
.specific_library_search_path("crate", "e1")
.specific_library_search_path("crate", "e2")
.run();
// If the library has a different hash, errors should occur.
rustc().input("e2.rs").output(rmake_out_path("e2/libe.rlib")).run();
rustc().input("e2.rs").output("e2/libe.rlib").run();
rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run_fail();
rustc()
.input("f.rs")
.library_search_path(rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.specific_library_search_path("crate", "e1")
.library_search_path("e2")
.run_fail();
rustc()
.input("f.rs")
.specific_library_search_path("crate", rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.run_fail();
rustc()
.input("f.rs")
.specific_library_search_path("crate", rmake_out_path("e1"))
.specific_library_search_path("crate", rmake_out_path("e2"))
.specific_library_search_path("crate", "e1")
.specific_library_search_path("crate", "e2")
.run_fail();
// Native and dependency paths do not cause errors.
rustc()
.input("f.rs")
.specific_library_search_path("native", rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.specific_library_search_path("native", "e1")
.library_search_path("e2")
.run();
rustc()
.input("f.rs")
.specific_library_search_path("dependency", rmake_out_path("e1"))
.library_search_path(rmake_out_path("e2"))
.specific_library_search_path("dependency", "e1")
.library_search_path("e2")
.run();
rustc()
.input("f.rs")
.specific_library_search_path("dependency", rmake_out_path("e1"))
.specific_library_search_path("crate", rmake_out_path("e2"))
.specific_library_search_path("dependency", "e1")
.specific_library_search_path("crate", "e2")
.run();
}

View File

@ -7,6 +7,11 @@
use run_make_support::{cwd, fs_wrapper, rustc};
fn main() {
rustc().crate_type("lib").input("foo.rs").dump_mono_stats(cwd()).arg("-Zdump-mono-stats-format=json").run();
assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains("\"name\":\"bar\"");
rustc()
.crate_type("lib")
.input("foo.rs")
.arg(format!("-Zdump-mono-stats={}", cwd().display()))
.arg("-Zdump-mono-stats-format=json")
.run();
assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#));
}

View File

@ -1,10 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# ignore-windows
# Notice the space in the end, this emulates the output of pkg-config
RUSTC_FLAGS = -C link-args="-lc "
all:
$(RUSTC) $(RUSTC_FLAGS) empty.rs

View File

@ -0,0 +1,15 @@
// Passing link-args with an unexpected space
// could result in the flag being parsed and receiving
// an unexpected, empty linker argument. This test
// ensures successful compilation even when a space is
// present.
// See https://github.com/rust-lang/rust/pull/10749
//@ ignore-cross-compile
use run_make_support::rustc;
fn main() {
// Notice the space at the end of -lc, which emulates the output of pkg-config.
rustc().arg("-Clink-args=-lc ").input("empty.rs").run();
}