mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #108355 - dpaoliello:dlltoolm, r=michaelwoerister
Fix cross-compiling with dlltool for raw-dylib Fix for #103939 Issue Details: When attempting to cross-compile using the `raw-dylib` feature and the GNU toolchain, rustc would attempt to find a cross-compiling version of dlltool (e.g., `i686-w64-mingw32-dlltool`). The has two issues 1) on Windows dlltool is always `dlltool` (no cross-compiling named versions exist) and 2) it only supported compiling to i686 and x86_64 resulting in ARM 32 and 64 compiling as x86_64. Fix Details: * On Windows always use the normal `dlltool` binary. * Add the ARM64 cross-compiling dlltool name (support for this is coming: https://sourceware.org/bugzilla/show_bug.cgi?id=29964) * Provide the `-m` argument to dlltool to indicate the target machine type. (This is the first of two PRs to fix the remaining issues for the `raw-dylib` feature (#58713) that is blocking stabilization (#104218))
This commit is contained in:
commit
9a6b0c3326
@ -189,6 +189,15 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
||||
path.push(lib_name);
|
||||
path
|
||||
};
|
||||
// dlltool target architecture args from:
|
||||
// https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69
|
||||
let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch.as_ref() {
|
||||
"x86_64" => ("i386:x86-64", "--64"),
|
||||
"x86" => ("i386", "--32"),
|
||||
"aarch64" => ("arm64", "--64"),
|
||||
"arm" => ("arm", "--32"),
|
||||
_ => panic!("unsupported arch {}", sess.target.arch),
|
||||
};
|
||||
let result = std::process::Command::new(dlltool)
|
||||
.args([
|
||||
"-d",
|
||||
@ -197,6 +206,10 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
||||
lib_name,
|
||||
"-l",
|
||||
output_path.to_str().unwrap(),
|
||||
"-m",
|
||||
dlltool_target_arch,
|
||||
"-f",
|
||||
dlltool_target_bitness,
|
||||
"--no-leading-underscore",
|
||||
"--temp-prefix",
|
||||
temp_prefix.to_str().unwrap(),
|
||||
@ -422,24 +435,22 @@ fn find_binutils_dlltool(sess: &Session) -> OsString {
|
||||
return dlltool_path.clone().into_os_string();
|
||||
}
|
||||
|
||||
let mut tool_name: OsString = if sess.host.arch != sess.target.arch {
|
||||
// We are cross-compiling, so we need the tool with the prefix matching our target
|
||||
if sess.target.arch == "x86" {
|
||||
"i686-w64-mingw32-dlltool"
|
||||
} else {
|
||||
"x86_64-w64-mingw32-dlltool"
|
||||
}
|
||||
let tool_name: OsString = if sess.host.options.is_like_windows {
|
||||
// If we're compiling on Windows, always use "dlltool.exe".
|
||||
"dlltool.exe"
|
||||
} else {
|
||||
// We are not cross-compiling, so we just want `dlltool`
|
||||
"dlltool"
|
||||
// On other platforms, use the architecture-specific name.
|
||||
match sess.target.arch.as_ref() {
|
||||
"x86_64" => "x86_64-w64-mingw32-dlltool",
|
||||
"x86" => "i686-w64-mingw32-dlltool",
|
||||
"aarch64" => "aarch64-w64-mingw32-dlltool",
|
||||
|
||||
// For non-standard architectures (e.g., aarch32) fallback to "dlltool".
|
||||
_ => "dlltool",
|
||||
}
|
||||
}
|
||||
.into();
|
||||
|
||||
if sess.host.options.is_like_windows {
|
||||
// If we're compiling on Windows, add the .exe suffix
|
||||
tool_name.push(".exe");
|
||||
}
|
||||
|
||||
// NOTE: it's not clear how useful it is to explicitly search PATH.
|
||||
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
|
||||
let full_path = dir.join(&tool_name);
|
||||
|
@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
zlib1g-dev \
|
||||
lib32z1-dev \
|
||||
xz-utils \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
|
@ -23,6 +23,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
|
@ -25,6 +25,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
nodejs \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install powershell (universal package) so we can test x.ps1 on Linux
|
||||
|
@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
xz-utils \
|
||||
mingw-w64 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
|
@ -964,6 +964,19 @@ pub fn make_test_description<R: Read>(
|
||||
.join(if config.host.contains("windows") { "rust-lld.exe" } else { "rust-lld" })
|
||||
.exists();
|
||||
|
||||
fn is_on_path(file: &'static str) -> impl Fn() -> bool {
|
||||
move || env::split_paths(&env::var_os("PATH").unwrap()).any(|dir| dir.join(file).is_file())
|
||||
}
|
||||
|
||||
// On Windows, dlltool.exe is used for all architectures.
|
||||
#[cfg(windows)]
|
||||
let (has_i686_dlltool, has_x86_64_dlltool) =
|
||||
(is_on_path("dlltool.exe"), is_on_path("dlltool.exe"));
|
||||
// For non-Windows, there are architecture specific dlltool binaries.
|
||||
#[cfg(not(windows))]
|
||||
let (has_i686_dlltool, has_x86_64_dlltool) =
|
||||
(is_on_path("i686-w64-mingw32-dlltool"), is_on_path("x86_64-w64-mingw32-dlltool"));
|
||||
|
||||
iter_header(path, src, &mut |revision, ln| {
|
||||
if revision.is_some() && revision != cfg {
|
||||
return;
|
||||
@ -1031,6 +1044,8 @@ pub fn make_test_description<R: Read>(
|
||||
reason!(config.debugger == Some(Debugger::Gdb) && ignore_gdb(config, ln));
|
||||
reason!(config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln));
|
||||
reason!(!has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld"));
|
||||
reason!(config.parse_name_directive(ln, "needs-i686-dlltool") && !has_i686_dlltool());
|
||||
reason!(config.parse_name_directive(ln, "needs-x86_64-dlltool") && !has_x86_64_dlltool());
|
||||
should_fail |= config.parse_name_directive(ln, "should-fail");
|
||||
});
|
||||
|
||||
|
22
tests/run-make/raw-dylib-cross-compilation/Makefile
Normal file
22
tests/run-make/raw-dylib-cross-compilation/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
# Tests that raw-dylib cross compilation works correctly
|
||||
|
||||
# only-gnu
|
||||
# needs-i686-dlltool
|
||||
# needs-x86_64-dlltool
|
||||
|
||||
# i686 dlltool.exe can't product x64 binaries.
|
||||
# ignore-i686-pc-windows-gnu
|
||||
|
||||
include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
all:
|
||||
# Build as x86 and make sure that we have x86 objects only.
|
||||
$(RUSTC) --crate-type lib --crate-name i686_raw_dylib_test --target i686-pc-windows-gnu lib.rs
|
||||
"$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libi686_raw_dylib_test.rlib > $(TMPDIR)/i686.objdump.txt
|
||||
$(CGREP) "file format coff-i386" < $(TMPDIR)/i686.objdump.txt
|
||||
$(CGREP) -v "file format coff-x86-64" < $(TMPDIR)/i686.objdump.txt
|
||||
# Build as x64 and make sure that we have x64 objects only.
|
||||
$(RUSTC) --crate-type lib --crate-name x64_raw_dylib_test --target x86_64-pc-windows-gnu lib.rs
|
||||
"$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libx64_raw_dylib_test.rlib > $(TMPDIR)/x64.objdump.txt
|
||||
$(CGREP) "file format coff-x86-64" < $(TMPDIR)/x64.objdump.txt
|
||||
$(CGREP) -v "file format coff-i386" < $(TMPDIR)/x64.objdump.txt
|
20
tests/run-make/raw-dylib-cross-compilation/lib.rs
Normal file
20
tests/run-make/raw-dylib-cross-compilation/lib.rs
Normal file
@ -0,0 +1,20 @@
|
||||
#![feature(raw_dylib)]
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// This is needed because of #![no_core]:
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[link(name = "extern_1", kind = "raw-dylib")]
|
||||
extern {
|
||||
fn extern_fn();
|
||||
}
|
||||
|
||||
pub fn extern_fn_caller() {
|
||||
unsafe {
|
||||
extern_fn();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user