Skip to content

Commit eeef857

Browse files
committed
Crude proof of concept
1 parent c9db3e0 commit eeef857

File tree

2 files changed

+31
-43
lines changed

2 files changed

+31
-43
lines changed

compiler/rustc_codegen_llvm/src/back/archive.rs

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::ptr;
88
use std::str;
99

1010
use crate::llvm::archive_ro::{ArchiveRO, Child};
11-
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
11+
use crate::llvm::{self, ArchiveKind, LLVMMachineType};
1212
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
1313
use rustc_data_structures::temp_dir::MaybeTempDir;
1414
use rustc_middle::middle::cstore::{DllCallingConvention, DllImport};
@@ -54,6 +54,7 @@ fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) ->
5454
ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) }
5555
}
5656

57+
#[allow(dead_code)]
5758
/// Map machine type strings to values of LLVM's MachineTypes enum.
5859
fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
5960
match cpu {
@@ -152,60 +153,47 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
152153
dll_imports: &[DllImport],
153154
tmpdir: &MaybeTempDir,
154155
) {
155-
let output_path = {
156-
let mut output_path: PathBuf = tmpdir.as_ref().to_path_buf();
157-
output_path.push(format!("{}_imports", lib_name));
158-
output_path.with_extension("lib")
159-
};
160-
161-
// we've checked for \0 characters in the library name already
162-
let dll_name_z = CString::new(lib_name).unwrap();
163-
// All import names are Rust identifiers and therefore cannot contain \0 characters.
164-
// FIXME: when support for #[link_name] implemented, ensure that import.name values don't
165-
// have any \0 characters
166-
let import_name_vector: Vec<CString> = dll_imports
156+
let mut def_file_path = tmpdir.as_ref().to_path_buf();
157+
def_file_path.push(format!("{}_imports", lib_name));
158+
def_file_path.with_extension("def");
159+
let mut output_path: PathBuf = tmpdir.as_ref().to_path_buf();
160+
output_path.push(format!("{}_imports", lib_name));
161+
output_path.with_extension("dll.a");
162+
163+
let import_name_vector: Vec<String> = dll_imports
167164
.iter()
168165
.map(|import: &DllImport| {
169166
if self.config.sess.target.arch == "x86" {
170-
LlvmArchiveBuilder::i686_decorated_name(import)
167+
LlvmArchiveBuilder::i686_decorated_name(import).into_string().unwrap()
171168
} else {
172-
CString::new(import.name.to_string()).unwrap()
169+
import.name.to_string()
173170
}
174171
})
175172
.collect();
176173

177-
let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
174+
let def_file_content = format!("EXPORTS\n{}", &import_name_vector.join("\n"));
175+
std::fs::write(&def_file_path, &def_file_content).unwrap();
176+
std::fs::copy(&def_file_path, "d:/imports.def").unwrap();
178177

179-
tracing::trace!("invoking LLVMRustWriteImportLibrary");
180-
tracing::trace!(" dll_name {:#?}", dll_name_z);
181-
tracing::trace!(" output_path {}", output_path.display());
182-
tracing::trace!(
183-
" import names: {}",
184-
dll_imports.iter().map(|import| import.name.to_string()).collect::<Vec<_>>().join(", "),
185-
);
186-
187-
let ffi_exports: Vec<LLVMRustCOFFShortExport> = import_name_vector
188-
.iter()
189-
.map(|name_z| LLVMRustCOFFShortExport::from_name(name_z.as_ptr()))
190-
.collect();
191-
let result = unsafe {
192-
crate::llvm::LLVMRustWriteImportLibrary(
193-
dll_name_z.as_ptr(),
194-
output_path_z.as_ptr(),
195-
ffi_exports.as_ptr(),
196-
ffi_exports.len(),
197-
llvm_machine_type(&self.config.sess.target.arch) as u16,
198-
!self.config.sess.target.is_like_msvc,
199-
)
200-
};
178+
let result = std::process::Command::new("dlltool")
179+
.args([
180+
"-d",
181+
def_file_path.to_str().unwrap(),
182+
"-D",
183+
lib_name,
184+
"-l",
185+
output_path.to_str().unwrap(),
186+
])
187+
.status();
201188

202-
if result == crate::llvm::LLVMRustResult::Failure {
189+
if let Err(e) = result {
203190
self.config.sess.fatal(&format!(
204191
"Error creating import library for {}: {}",
205192
lib_name,
206-
llvm::last_error().unwrap_or("unknown LLVM error".to_string())
193+
e.to_string()
207194
));
208195
}
196+
std::fs::copy(&output_path, "d:/imports.dll.a").unwrap();
209197

210198
self.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
211199
self.config.sess.fatal(&format!(

src/test/run-make/raw-dylib-c/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Test the behavior of #[link(.., kind = "raw-dylib")] on windows-msvc
22

3-
# only-windows-msvc
3+
# only-windows-gnu
44

55
-include ../../run-make-fulldeps/tools.mk
66

77
all:
88
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
99
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
10-
$(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll
11-
$(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll
10+
$(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
11+
$(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
1212
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
1313
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
1414
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt

0 commit comments

Comments
 (0)