Auto merge of #98989 - dpaoliello:rawdylibbin, r=michaelwoerister
Enable raw-dylib for bin crates Fixes #93842 When `raw-dylib` is used in a `bin` crate, we need to collect all of the `raw-dylib` functions, generate the import library and add that to the linker command line. I also changed the tests so that 1) the C++ dlls are created after the Rust dlls, thus there is no chance of accidentally using them in the Rust linking process and 2) disabled generating import libraries when building with MSVC.
This commit is contained in:
commit
daaae25022
11 changed files with 108 additions and 53 deletions
|
@ -204,12 +204,16 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||||
any_members
|
any_members
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dll_import_lib(
|
fn sess(&self) -> &Session {
|
||||||
&mut self,
|
self.sess
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_dll_import_lib(
|
||||||
|
_sess: &Session,
|
||||||
_lib_name: &str,
|
_lib_name: &str,
|
||||||
_dll_imports: &[rustc_session::cstore::DllImport],
|
_dll_imports: &[rustc_session::cstore::DllImport],
|
||||||
_tmpdir: &rustc_data_structures::temp_dir::MaybeTempDir,
|
_tmpdir: &Path,
|
||||||
) {
|
) -> PathBuf {
|
||||||
bug!("injecting dll imports is not supported");
|
bug!("creating dll imports is not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
|
||||||
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
|
||||||
use rustc_session::cstore::DllImport;
|
use rustc_session::cstore::DllImport;
|
||||||
|
|
||||||
struct ArchiveConfig<'a> {
|
struct ArchiveConfig<'a> {
|
||||||
|
@ -177,7 +176,16 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||||
any_members
|
any_members
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dll_import_lib(&mut self, _lib_name: &str, _dll_imports: &[DllImport], _tmpdir: &MaybeTempDir) {
|
fn sess(&self) -> &Session {
|
||||||
|
self.config.sess
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_dll_import_lib(
|
||||||
|
_sess: &Session,
|
||||||
|
_lib_name: &str,
|
||||||
|
_dll_imports: &[DllImport],
|
||||||
|
_tmpdir: &Path,
|
||||||
|
) -> PathBuf {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ use std::str;
|
||||||
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
use crate::llvm::archive_ro::{ArchiveRO, Child};
|
||||||
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
|
||||||
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
|
||||||
use rustc_session::cstore::{DllCallingConvention, DllImport};
|
use rustc_session::cstore::{DllCallingConvention, DllImport};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
|
||||||
|
@ -96,19 +95,23 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject_dll_import_lib(
|
fn sess(&self) -> &Session {
|
||||||
&mut self,
|
self.sess
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_dll_import_lib(
|
||||||
|
sess: &Session,
|
||||||
lib_name: &str,
|
lib_name: &str,
|
||||||
dll_imports: &[DllImport],
|
dll_imports: &[DllImport],
|
||||||
tmpdir: &MaybeTempDir,
|
tmpdir: &Path,
|
||||||
) {
|
) -> PathBuf {
|
||||||
let output_path = {
|
let output_path = {
|
||||||
let mut output_path: PathBuf = tmpdir.as_ref().to_path_buf();
|
let mut output_path: PathBuf = tmpdir.to_path_buf();
|
||||||
output_path.push(format!("{}_imports", lib_name));
|
output_path.push(format!("{}_imports", lib_name));
|
||||||
output_path.with_extension("lib")
|
output_path.with_extension("lib")
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = &self.sess.target;
|
let target = &sess.target;
|
||||||
let mingw_gnu_toolchain = target.vendor == "pc"
|
let mingw_gnu_toolchain = target.vendor == "pc"
|
||||||
&& target.os == "windows"
|
&& target.os == "windows"
|
||||||
&& target.env == "gnu"
|
&& target.env == "gnu"
|
||||||
|
@ -117,7 +120,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
|
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
|
||||||
.iter()
|
.iter()
|
||||||
.map(|import: &DllImport| {
|
.map(|import: &DllImport| {
|
||||||
if self.sess.target.arch == "x86" {
|
if sess.target.arch == "x86" {
|
||||||
(
|
(
|
||||||
LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
|
LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
|
||||||
import.ordinal,
|
import.ordinal,
|
||||||
|
@ -134,8 +137,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
// that loaded but crashed with an AV upon calling one of the imported
|
// that loaded but crashed with an AV upon calling one of the imported
|
||||||
// functions. Therefore, use binutils to create the import library instead,
|
// functions. Therefore, use binutils to create the import library instead,
|
||||||
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
|
||||||
let def_file_path =
|
let def_file_path = tmpdir.join(format!("{}_imports", lib_name)).with_extension("def");
|
||||||
tmpdir.as_ref().join(format!("{}_imports", lib_name)).with_extension("def");
|
|
||||||
|
|
||||||
let def_file_content = format!(
|
let def_file_content = format!(
|
||||||
"EXPORTS\n{}",
|
"EXPORTS\n{}",
|
||||||
|
@ -154,11 +156,11 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
match std::fs::write(&def_file_path, def_file_content) {
|
match std::fs::write(&def_file_path, def_file_content) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.sess.fatal(&format!("Error writing .DEF file: {}", e));
|
sess.fatal(&format!("Error writing .DEF file: {}", e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let dlltool = find_binutils_dlltool(self.sess);
|
let dlltool = find_binutils_dlltool(sess);
|
||||||
let result = std::process::Command::new(dlltool)
|
let result = std::process::Command::new(dlltool)
|
||||||
.args([
|
.args([
|
||||||
"-d",
|
"-d",
|
||||||
|
@ -172,9 +174,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.sess.fatal(&format!("Error calling dlltool: {}", e));
|
sess.fatal(&format!("Error calling dlltool: {}", e));
|
||||||
}
|
}
|
||||||
Ok(output) if !output.status.success() => self.sess.fatal(&format!(
|
Ok(output) if !output.status.success() => sess.fatal(&format!(
|
||||||
"Dlltool could not create import library: {}\n{}",
|
"Dlltool could not create import library: {}\n{}",
|
||||||
String::from_utf8_lossy(&output.stdout),
|
String::from_utf8_lossy(&output.stdout),
|
||||||
String::from_utf8_lossy(&output.stderr)
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
@ -220,13 +222,13 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
output_path_z.as_ptr(),
|
output_path_z.as_ptr(),
|
||||||
ffi_exports.as_ptr(),
|
ffi_exports.as_ptr(),
|
||||||
ffi_exports.len(),
|
ffi_exports.len(),
|
||||||
llvm_machine_type(&self.sess.target.arch) as u16,
|
llvm_machine_type(&sess.target.arch) as u16,
|
||||||
!self.sess.target.is_like_msvc,
|
!sess.target.is_like_msvc,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if result == crate::llvm::LLVMRustResult::Failure {
|
if result == crate::llvm::LLVMRustResult::Failure {
|
||||||
self.sess.fatal(&format!(
|
sess.fatal(&format!(
|
||||||
"Error creating import library for {}: {}",
|
"Error creating import library for {}: {}",
|
||||||
lib_name,
|
lib_name,
|
||||||
llvm::last_error().unwrap_or("unknown LLVM error".to_string())
|
llvm::last_error().unwrap_or("unknown LLVM error".to_string())
|
||||||
|
@ -234,13 +236,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
|
output_path
|
||||||
self.sess.fatal(&format!(
|
|
||||||
"failed to add native library {}: {}",
|
|
||||||
output_path.display(),
|
|
||||||
e
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,37 @@ pub trait ArchiveBuilder<'a> {
|
||||||
|
|
||||||
fn build(self) -> bool;
|
fn build(self) -> bool;
|
||||||
|
|
||||||
|
fn sess(&self) -> &Session;
|
||||||
|
|
||||||
|
/// Creates a DLL Import Library <https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-creation#creating-an-import-library>.
|
||||||
|
/// and returns the path on disk to that import library.
|
||||||
|
/// This functions doesn't take `self` so that it can be called from
|
||||||
|
/// `linker_with_args`, which is specialized on `ArchiveBuilder` but
|
||||||
|
/// doesn't take or create an instance of that type.
|
||||||
|
fn create_dll_import_lib(
|
||||||
|
sess: &Session,
|
||||||
|
lib_name: &str,
|
||||||
|
dll_imports: &[DllImport],
|
||||||
|
tmpdir: &Path,
|
||||||
|
) -> PathBuf;
|
||||||
|
|
||||||
|
/// Creates a DLL Import Library <https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-creation#creating-an-import-library>
|
||||||
|
/// and adds it to the current compilation's set of archives.
|
||||||
fn inject_dll_import_lib(
|
fn inject_dll_import_lib(
|
||||||
&mut self,
|
&mut self,
|
||||||
lib_name: &str,
|
lib_name: &str,
|
||||||
dll_imports: &[DllImport],
|
dll_imports: &[DllImport],
|
||||||
tmpdir: &MaybeTempDir,
|
tmpdir: &MaybeTempDir,
|
||||||
);
|
) {
|
||||||
|
let output_path =
|
||||||
|
Self::create_dll_import_lib(self.sess(), lib_name, dll_imports, tmpdir.as_ref());
|
||||||
|
|
||||||
|
self.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
|
||||||
|
self.sess().fatal(&format!(
|
||||||
|
"failed to add native library {}: {}",
|
||||||
|
output_path.display(),
|
||||||
|
e
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
||||||
&out_filename,
|
&out_filename,
|
||||||
codegen_results,
|
codegen_results,
|
||||||
path.as_ref(),
|
path.as_ref(),
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sess.opts.json_artifact_notifications {
|
if sess.opts.json_artifact_notifications {
|
||||||
|
@ -650,7 +650,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
||||||
out_filename: &Path,
|
out_filename: &Path,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
tmpdir: &Path,
|
tmpdir: &Path,
|
||||||
) {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
info!("preparing {:?} to {:?}", crate_type, out_filename);
|
info!("preparing {:?} to {:?}", crate_type, out_filename);
|
||||||
let (linker_path, flavor) = linker_and_flavor(sess);
|
let (linker_path, flavor) = linker_and_flavor(sess);
|
||||||
let mut cmd = linker_with_args::<B>(
|
let mut cmd = linker_with_args::<B>(
|
||||||
|
@ -661,7 +661,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
||||||
tmpdir,
|
tmpdir,
|
||||||
out_filename,
|
out_filename,
|
||||||
codegen_results,
|
codegen_results,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
linker::disable_localization(&mut cmd);
|
linker::disable_localization(&mut cmd);
|
||||||
|
|
||||||
|
@ -1000,6 +1000,8 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
||||||
(Strip::None, _) => {}
|
(Strip::None, _) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporarily support both -Z strip and -C strip
|
// Temporarily support both -Z strip and -C strip
|
||||||
|
@ -1848,7 +1850,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
||||||
tmpdir: &Path,
|
tmpdir: &Path,
|
||||||
out_filename: &Path,
|
out_filename: &Path,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
) -> Command {
|
) -> Result<Command, ErrorGuaranteed> {
|
||||||
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
|
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
|
||||||
let cmd = &mut *super::linker::get_linker(
|
let cmd = &mut *super::linker::get_linker(
|
||||||
sess,
|
sess,
|
||||||
|
@ -1955,6 +1957,18 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
||||||
add_upstream_native_libraries(cmd, sess, codegen_results);
|
add_upstream_native_libraries(cmd, sess, codegen_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link with the import library generated for any raw-dylib functions.
|
||||||
|
for (raw_dylib_name, raw_dylib_imports) in
|
||||||
|
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
|
||||||
|
{
|
||||||
|
cmd.add_object(&B::create_dll_import_lib(
|
||||||
|
sess,
|
||||||
|
&raw_dylib_name,
|
||||||
|
&raw_dylib_imports,
|
||||||
|
tmpdir,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
|
// Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
|
||||||
// command line shorter, reset it to default here before adding more libraries.
|
// command line shorter, reset it to default here before adding more libraries.
|
||||||
cmd.reset_per_library_state();
|
cmd.reset_per_library_state();
|
||||||
|
@ -1998,7 +2012,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
||||||
// to it and remove the option.
|
// to it and remove the option.
|
||||||
add_post_link_args(cmd, sess, flavor);
|
add_post_link_args(cmd, sess, flavor);
|
||||||
|
|
||||||
cmd.take_cmd()
|
Ok(cmd.take_cmd())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_order_independent_options(
|
fn add_order_independent_options(
|
||||||
|
@ -2227,8 +2241,7 @@ fn add_local_native_libraries(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NativeLibKind::RawDylib => {
|
NativeLibKind::RawDylib => {
|
||||||
// FIXME(#58713): Proper handling for raw dylibs.
|
// Ignore RawDylib here, they are handled separately in linker_with_args().
|
||||||
bug!("raw_dylib feature not yet implemented");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
|
||||||
OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
|
OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
|
||||||
-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
|
-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
|
||||||
else
|
else
|
||||||
COMPILE_OBJ = $(CC) -c -o $(1) $(2)
|
COMPILE_OBJ = $(CC) -v -c -o $(1) $(2)
|
||||||
COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
|
COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
|
||||||
NATIVE_STATICLIB_FILE = lib$(1).a
|
NATIVE_STATICLIB_FILE = lib$(1).a
|
||||||
NATIVE_STATICLIB = $(call STATICLIB,$(1))
|
NATIVE_STATICLIB = $(call STATICLIB,$(1))
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
-include ../../run-make-fulldeps/tools.mk
|
-include ../../run-make-fulldeps/tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
$(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs
|
||||||
|
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
||||||
$(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
|
$(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
|
||||||
ifdef IS_MSVC
|
ifdef IS_MSVC
|
||||||
$(CC) "$(TMPDIR)"/extern.obj -link -dll -out:"$(TMPDIR)"/extern.dll
|
$(CC) "$(TMPDIR)"/extern.obj -link -dll -out:"$(TMPDIR)"/extern.dll -noimplib
|
||||||
else
|
else
|
||||||
$(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
|
$(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
|
||||||
endif
|
endif
|
||||||
$(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs
|
|
||||||
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
|
||||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
||||||
|
|
||||||
ifdef RUSTC_BLESS_TEST
|
ifdef RUSTC_BLESS_TEST
|
||||||
|
|
|
@ -5,21 +5,24 @@
|
||||||
-include ../../run-make-fulldeps/tools.mk
|
-include ../../run-make-fulldeps/tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
||||||
|
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
||||||
|
$(RUSTC) --crate-type bin --crate-name raw_dylib_test_bin lib.rs
|
||||||
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
|
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_1.obj,extern_1.c)
|
||||||
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
|
$(call COMPILE_OBJ,"$(TMPDIR)"/extern_2.obj,extern_2.c)
|
||||||
ifdef IS_MSVC
|
ifdef IS_MSVC
|
||||||
$(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll
|
$(CC) "$(TMPDIR)"/extern_1.obj -link -dll -out:"$(TMPDIR)"/extern_1.dll -noimplib
|
||||||
$(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll
|
$(CC) "$(TMPDIR)"/extern_2.obj -link -dll -out:"$(TMPDIR)"/extern_2.dll -noimplib
|
||||||
else
|
else
|
||||||
$(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
|
$(CC) "$(TMPDIR)"/extern_1.obj -shared -o "$(TMPDIR)"/extern_1.dll
|
||||||
$(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
|
$(CC) "$(TMPDIR)"/extern_2.obj -shared -o "$(TMPDIR)"/extern_2.dll
|
||||||
endif
|
endif
|
||||||
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
|
||||||
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
|
||||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
||||||
|
"$(TMPDIR)"/raw_dylib_test_bin > "$(TMPDIR)"/output_bin.txt
|
||||||
|
|
||||||
ifdef RUSTC_BLESS_TEST
|
ifdef RUSTC_BLESS_TEST
|
||||||
cp "$(TMPDIR)"/output.txt output.txt
|
cp "$(TMPDIR)"/output.txt output.txt
|
||||||
else
|
else
|
||||||
$(DIFF) output.txt "$(TMPDIR)"/output.txt
|
$(DIFF) output.txt "$(TMPDIR)"/output.txt
|
||||||
|
$(DIFF) output.txt "$(TMPDIR)"/output_bin.txt
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -20,3 +20,7 @@ pub fn library_function() {
|
||||||
extern_fn_3();
|
extern_fn_3();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
library_function();
|
||||||
|
}
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
-include ../../run-make-fulldeps/tools.mk
|
-include ../../run-make-fulldeps/tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
||||||
|
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
||||||
$(call COMPILE_OBJ,"$(TMPDIR)"/exporter.obj,exporter.c)
|
$(call COMPILE_OBJ,"$(TMPDIR)"/exporter.obj,exporter.c)
|
||||||
ifdef IS_MSVC
|
ifdef IS_MSVC
|
||||||
$(CC) "$(TMPDIR)"/exporter.obj exporter.def -link -dll -out:"$(TMPDIR)"/exporter.dll
|
$(CC) "$(TMPDIR)"/exporter.obj exporter.def -link -dll -out:"$(TMPDIR)"/exporter.dll -noimplib
|
||||||
else
|
else
|
||||||
$(CC) "$(TMPDIR)"/exporter.obj exporter.def -shared -o "$(TMPDIR)"/exporter.dll
|
$(CC) "$(TMPDIR)"/exporter.obj exporter.def -shared -o "$(TMPDIR)"/exporter.dll
|
||||||
endif
|
endif
|
||||||
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
|
||||||
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
|
||||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
|
||||||
|
|
||||||
ifdef RUSTC_BLESS_TEST
|
ifdef RUSTC_BLESS_TEST
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
-include ../../run-make-fulldeps/tools.mk
|
-include ../../run-make-fulldeps/tools.mk
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
||||||
|
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
||||||
$(call COMPILE_OBJ,"$(TMPDIR)"/exporter.obj,exporter.c)
|
$(call COMPILE_OBJ,"$(TMPDIR)"/exporter.obj,exporter.c)
|
||||||
ifdef IS_MSVC
|
ifdef IS_MSVC
|
||||||
$(CC) "$(TMPDIR)"/exporter.obj exporter-msvc.def -link -dll -out:"$(TMPDIR)"/exporter.dll
|
$(CC) "$(TMPDIR)"/exporter.obj exporter-msvc.def -link -dll -out:"$(TMPDIR)"/exporter.dll -noimplib
|
||||||
else
|
else
|
||||||
$(CC) "$(TMPDIR)"/exporter.obj exporter-gnu.def -shared -o "$(TMPDIR)"/exporter.dll
|
$(CC) "$(TMPDIR)"/exporter.obj exporter-gnu.def -shared -o "$(TMPDIR)"/exporter.dll
|
||||||
endif
|
endif
|
||||||
$(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs
|
|
||||||
$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
|
|
||||||
"$(TMPDIR)"/driver > "$(TMPDIR)"/actual_output.txt
|
"$(TMPDIR)"/driver > "$(TMPDIR)"/actual_output.txt
|
||||||
|
|
||||||
ifdef RUSTC_BLESS_TEST
|
ifdef RUSTC_BLESS_TEST
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue