|
1 | 1 | //! A helper class for dealing with static archives
|
2 | 2 |
|
3 |
| -use std::ffi::{c_char, c_void, CStr, CString, OsString}; |
| 3 | +use std::ffi::{c_char, c_void, CStr, CString}; |
4 | 4 | use std::path::{Path, PathBuf};
|
5 |
| -use std::{env, io, mem, ptr, str}; |
| 5 | +use std::{io, mem, ptr, str}; |
6 | 6 |
|
7 | 7 | use rustc_codegen_ssa::back::archive::{
|
8 |
| - try_extract_macho_fat_archive, ArArchiveBuilder, ArchiveBuildFailure, ArchiveBuilder, |
9 |
| - ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, DEFAULT_OBJECT_READER, |
| 8 | + create_mingw_dll_import_lib, try_extract_macho_fat_archive, ArArchiveBuilder, |
| 9 | + ArchiveBuildFailure, ArchiveBuilder, ArchiveBuilderBuilder, ObjectReader, UnknownArchiveKind, |
| 10 | + DEFAULT_OBJECT_READER, |
10 | 11 | };
|
11 | 12 | use rustc_codegen_ssa::common;
|
12 | 13 | use rustc_session::Session;
|
13 | 14 | use tracing::trace;
|
14 | 15 |
|
15 |
| -use crate::errors::{ |
16 |
| - DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, |
17 |
| -}; |
| 16 | +use crate::errors::ErrorCreatingImportLibrary; |
18 | 17 | use crate::llvm::archive_ro::{ArchiveRO, Child};
|
19 | 18 | use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
20 | 19 |
|
@@ -121,95 +120,18 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
|
121 | 120 | import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
|
122 | 121 | output_path: &Path,
|
123 | 122 | ) {
|
124 |
| - let target = &sess.target; |
125 |
| - let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target); |
126 |
| - |
127 |
| - if mingw_gnu_toolchain { |
| 123 | + if common::is_mingw_gnu_toolchain(&sess.target) { |
128 | 124 | // The binutils linker used on -windows-gnu targets cannot read the import
|
129 | 125 | // libraries generated by LLVM: in our attempts, the linker produced an .EXE
|
130 | 126 | // that loaded but crashed with an AV upon calling one of the imported
|
131 | 127 | // functions. Therefore, use binutils to create the import library instead,
|
132 | 128 | // by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
133 |
| - let def_file_path = output_path.with_extension("def"); |
134 |
| - |
135 |
| - let def_file_content = format!( |
136 |
| - "EXPORTS\n{}", |
137 |
| - import_name_and_ordinal_vector |
138 |
| - .into_iter() |
139 |
| - .map(|(name, ordinal)| { |
140 |
| - match ordinal { |
141 |
| - Some(n) => format!("{name} @{n} NONAME"), |
142 |
| - None => name, |
143 |
| - } |
144 |
| - }) |
145 |
| - .collect::<Vec<String>>() |
146 |
| - .join("\n") |
| 129 | + create_mingw_dll_import_lib( |
| 130 | + sess, |
| 131 | + lib_name, |
| 132 | + import_name_and_ordinal_vector, |
| 133 | + output_path, |
147 | 134 | );
|
148 |
| - |
149 |
| - match std::fs::write(&def_file_path, def_file_content) { |
150 |
| - Ok(_) => {} |
151 |
| - Err(e) => { |
152 |
| - sess.dcx().emit_fatal(ErrorWritingDEFFile { error: e }); |
153 |
| - } |
154 |
| - }; |
155 |
| - |
156 |
| - // --no-leading-underscore: For the `import_name_type` feature to work, we need to be |
157 |
| - // able to control the *exact* spelling of each of the symbols that are being imported: |
158 |
| - // hence we don't want `dlltool` adding leading underscores automatically. |
159 |
| - let dlltool = find_binutils_dlltool(sess); |
160 |
| - let temp_prefix = { |
161 |
| - let mut path = PathBuf::from(&output_path); |
162 |
| - path.pop(); |
163 |
| - path.push(lib_name); |
164 |
| - path |
165 |
| - }; |
166 |
| - // dlltool target architecture args from: |
167 |
| - // https://github.com/llvm/llvm-project-release-prs/blob/llvmorg-15.0.6/llvm/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp#L69 |
168 |
| - let (dlltool_target_arch, dlltool_target_bitness) = match sess.target.arch.as_ref() { |
169 |
| - "x86_64" => ("i386:x86-64", "--64"), |
170 |
| - "x86" => ("i386", "--32"), |
171 |
| - "aarch64" => ("arm64", "--64"), |
172 |
| - "arm" => ("arm", "--32"), |
173 |
| - _ => panic!("unsupported arch {}", sess.target.arch), |
174 |
| - }; |
175 |
| - let mut dlltool_cmd = std::process::Command::new(&dlltool); |
176 |
| - dlltool_cmd |
177 |
| - .arg("-d") |
178 |
| - .arg(def_file_path) |
179 |
| - .arg("-D") |
180 |
| - .arg(lib_name) |
181 |
| - .arg("-l") |
182 |
| - .arg(&output_path) |
183 |
| - .arg("-m") |
184 |
| - .arg(dlltool_target_arch) |
185 |
| - .arg("-f") |
186 |
| - .arg(dlltool_target_bitness) |
187 |
| - .arg("--no-leading-underscore") |
188 |
| - .arg("--temp-prefix") |
189 |
| - .arg(temp_prefix); |
190 |
| - |
191 |
| - match dlltool_cmd.output() { |
192 |
| - Err(e) => { |
193 |
| - sess.dcx().emit_fatal(ErrorCallingDllTool { |
194 |
| - dlltool_path: dlltool.to_string_lossy(), |
195 |
| - error: e, |
196 |
| - }); |
197 |
| - } |
198 |
| - // dlltool returns '0' on failure, so check for error output instead. |
199 |
| - Ok(output) if !output.stderr.is_empty() => { |
200 |
| - sess.dcx().emit_fatal(DlltoolFailImportLibrary { |
201 |
| - dlltool_path: dlltool.to_string_lossy(), |
202 |
| - dlltool_args: dlltool_cmd |
203 |
| - .get_args() |
204 |
| - .map(|arg| arg.to_string_lossy()) |
205 |
| - .collect::<Vec<_>>() |
206 |
| - .join(" "), |
207 |
| - stdout: String::from_utf8_lossy(&output.stdout), |
208 |
| - stderr: String::from_utf8_lossy(&output.stderr), |
209 |
| - }) |
210 |
| - } |
211 |
| - _ => {} |
212 |
| - } |
213 | 135 | } else {
|
214 | 136 | // we've checked for \0 characters in the library name already
|
215 | 137 | let dll_name_z = CString::new(lib_name).unwrap();
|
@@ -434,39 +356,3 @@ impl<'a> LlvmArchiveBuilder<'a> {
|
434 | 356 | fn string_to_io_error(s: String) -> io::Error {
|
435 | 357 | io::Error::new(io::ErrorKind::Other, format!("bad archive: {s}"))
|
436 | 358 | }
|
437 |
| - |
438 |
| -fn find_binutils_dlltool(sess: &Session) -> OsString { |
439 |
| - assert!(sess.target.options.is_like_windows && !sess.target.options.is_like_msvc); |
440 |
| - if let Some(dlltool_path) = &sess.opts.cg.dlltool { |
441 |
| - return dlltool_path.clone().into_os_string(); |
442 |
| - } |
443 |
| - |
444 |
| - let tool_name: OsString = if sess.host.options.is_like_windows { |
445 |
| - // If we're compiling on Windows, always use "dlltool.exe". |
446 |
| - "dlltool.exe" |
447 |
| - } else { |
448 |
| - // On other platforms, use the architecture-specific name. |
449 |
| - match sess.target.arch.as_ref() { |
450 |
| - "x86_64" => "x86_64-w64-mingw32-dlltool", |
451 |
| - "x86" => "i686-w64-mingw32-dlltool", |
452 |
| - "aarch64" => "aarch64-w64-mingw32-dlltool", |
453 |
| - |
454 |
| - // For non-standard architectures (e.g., aarch32) fallback to "dlltool". |
455 |
| - _ => "dlltool", |
456 |
| - } |
457 |
| - } |
458 |
| - .into(); |
459 |
| - |
460 |
| - // NOTE: it's not clear how useful it is to explicitly search PATH. |
461 |
| - for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) { |
462 |
| - let full_path = dir.join(&tool_name); |
463 |
| - if full_path.is_file() { |
464 |
| - return full_path.into_os_string(); |
465 |
| - } |
466 |
| - } |
467 |
| - |
468 |
| - // The user didn't specify the location of the dlltool binary, and we weren't able |
469 |
| - // to find the appropriate one on the PATH. Just return the name of the tool |
470 |
| - // and let the invocation fail with a hopefully useful error message. |
471 |
| - tool_name |
472 |
| -} |
0 commit comments