rewrite foreign-double-unwind to rmake
This commit is contained in:
parent
5367673014
commit
8f641b1b95
7 changed files with 130 additions and 14 deletions
|
@ -1,8 +1,13 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
<<<<<<< HEAD
|
||||
use super::cygpath::get_windows_path;
|
||||
use crate::artifact_names::{dynamic_lib_name, static_lib_name};
|
||||
use crate::external_deps::cc::cc;
|
||||
=======
|
||||
use crate::artifact_names::static_lib_name;
|
||||
use crate::external_deps::cc::{cc, cxx};
|
||||
>>>>>>> e3cf7e53339 (rewrite foreign-double-unwind to rmake)
|
||||
use crate::external_deps::llvm::llvm_ar;
|
||||
use crate::path_helpers::path;
|
||||
use crate::targets::{is_darwin, is_msvc, is_windows};
|
||||
|
@ -10,6 +15,7 @@ use crate::targets::{is_darwin, is_msvc, is_windows};
|
|||
// FIXME(Oneirical): These native build functions should take a Path-based generic.
|
||||
|
||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||
/// Built from a C file.
|
||||
#[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") };
|
||||
|
@ -58,3 +64,24 @@ pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
|
|||
}
|
||||
path(lib_path)
|
||||
}
|
||||
|
||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||
/// Built from a C++ file.
|
||||
#[track_caller]
|
||||
pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
|
||||
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
|
||||
let src = format!("{lib_name}.cpp");
|
||||
let lib_path = static_lib_name(lib_name);
|
||||
if is_msvc() {
|
||||
cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
|
||||
} else {
|
||||
cxx().arg("-c").out_exe(&obj_file).input(src).run();
|
||||
};
|
||||
let obj_file = if is_msvc() {
|
||||
PathBuf::from(format!("{lib_name}.obj"))
|
||||
} else {
|
||||
PathBuf::from(format!("{lib_name}.o"))
|
||||
};
|
||||
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
|
||||
path(lib_path)
|
||||
}
|
||||
|
|
|
@ -214,3 +214,41 @@ pub fn extra_cxx_flags() -> Vec<&'static str> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `EXTRARSCXXFLAGS`
|
||||
pub fn extra_rs_cxx_flags() -> Vec<&'static str> {
|
||||
// Adapted from tools.mk (trimmed):
|
||||
//
|
||||
// ```makefile
|
||||
// ifdef IS_WINDOWS
|
||||
// ifdef IS_MSVC
|
||||
// else
|
||||
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
|
||||
// endif
|
||||
// else
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// EXTRARSCXXFLAGS := -lc++
|
||||
// else
|
||||
// ifeq ($(UNAME),FreeBSD)
|
||||
// else
|
||||
// ifeq ($(UNAME),SunOS)
|
||||
// else
|
||||
// ifeq ($(UNAME),OpenBSD)
|
||||
// else
|
||||
// EXTRARSCXXFLAGS := -lstdc++
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
if is_windows() {
|
||||
if is_msvc() { vec![] } else { vec!["-lstatic:-bundle=stdc++"] }
|
||||
} else {
|
||||
match &uname()[..] {
|
||||
"Darwin" => vec!["-lc++"],
|
||||
"FreeBSD" | "SunOS" | "OpenBSD" => vec![],
|
||||
_ => vec!["-lstdc++"],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::command::Command;
|
|||
use crate::env::env_var;
|
||||
use crate::path_helpers::cwd;
|
||||
use crate::util::set_host_rpath;
|
||||
use crate::{is_msvc, is_windows, uname};
|
||||
|
||||
/// Construct a new `rustc` invocation. This will automatically set the library
|
||||
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
||||
|
@ -314,4 +315,46 @@ impl Rustc {
|
|||
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
|
||||
self
|
||||
}
|
||||
|
||||
/// `EXTRARSCXXFLAGS`
|
||||
pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
|
||||
// Adapted from tools.mk (trimmed):
|
||||
//
|
||||
// ```makefile
|
||||
// ifdef IS_WINDOWS
|
||||
// ifdef IS_MSVC
|
||||
// else
|
||||
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
|
||||
// endif
|
||||
// else
|
||||
// ifeq ($(UNAME),Darwin)
|
||||
// EXTRARSCXXFLAGS := -lc++
|
||||
// else
|
||||
// ifeq ($(UNAME),FreeBSD)
|
||||
// else
|
||||
// ifeq ($(UNAME),SunOS)
|
||||
// else
|
||||
// ifeq ($(UNAME),OpenBSD)
|
||||
// else
|
||||
// EXTRARSCXXFLAGS := -lstdc++
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// endif
|
||||
// ```
|
||||
let flag = if is_windows() {
|
||||
if is_msvc() { None } else { Some("-lstatic:-bundle=stdc++") }
|
||||
} else {
|
||||
match &uname()[..] {
|
||||
"Darwin" => Some("-lc++"),
|
||||
"FreeBSD" | "SunOS" | "OpenBSD" => None,
|
||||
_ => Some("-lstdc++"),
|
||||
}
|
||||
};
|
||||
if let Some(flag) = flag {
|
||||
self.cmd.arg(flag);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ pub use wasmparser;
|
|||
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
||||
|
||||
// These rely on external dependencies.
|
||||
pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
|
||||
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
|
||||
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx};
|
||||
pub use clang::{clang, Clang};
|
||||
pub use htmldocck::htmldocck;
|
||||
pub use llvm::{
|
||||
|
|
|
@ -9,7 +9,6 @@ run-make/dep-info-spaces/Makefile
|
|||
run-make/dep-info/Makefile
|
||||
run-make/emit-to-stdout/Makefile
|
||||
run-make/extern-fn-reachable/Makefile
|
||||
run-make/foreign-double-unwind/Makefile
|
||||
run-make/foreign-exceptions/Makefile
|
||||
run-make/incr-add-rust-src-component/Makefile
|
||||
run-make/issue-36710/Makefile
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# ignore-cross-compile
|
||||
# needs-unwind
|
||||
include ../tools.mk
|
||||
|
||||
all: foo
|
||||
$(call RUN,foo) | $(CGREP) -v unreachable
|
||||
|
||||
foo: foo.rs $(call NATIVE_STATICLIB,foo)
|
||||
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS)
|
||||
|
||||
$(TMPDIR)/libfoo.o: foo.cpp
|
||||
$(call COMPILE_OBJ_CXX,$@,$<)
|
21
tests/run-make/foreign-double-unwind/rmake.rs
Normal file
21
tests/run-make/foreign-double-unwind/rmake.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// When using foreign function interface (FFI) with C++, it is possible
|
||||
// to run into a "double unwind" if either both Rust and C++ run into a panic
|
||||
// and exception at the same time, or C++ encounters two exceptions. In this case,
|
||||
// one of the panic unwinds would be leaked and the other would be kept, leading
|
||||
// to undefined behaviour. After this was fixed in #92911, this test checks that
|
||||
// the keyword "unreachable" indicative of this bug triggering in this specific context
|
||||
// does not appear after successfully compiling and executing the program.
|
||||
// See https://github.com/rust-lang/rust/pull/92911
|
||||
|
||||
//@ needs-unwind
|
||||
// Reason: this test exercises panic unwinding
|
||||
//@ ignore-cross-compile
|
||||
// Reason: the compiled binary is executed
|
||||
|
||||
use run_make_support::{build_native_static_lib_cxx, run, rustc};
|
||||
|
||||
fn main() {
|
||||
build_native_static_lib_cxx("foo");
|
||||
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
|
||||
run("foo").assert_stdout_not_contains("unreachable");
|
||||
}
|
Loading…
Add table
Reference in a new issue