Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable windows-gnu target to link to libgcc dynamically. #90020

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1625,26 +1625,7 @@ fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) {

/// Add arbitrary "late link" args defined by the target spec.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_late_link_args(
cmd: &mut dyn Linker,
sess: &Session,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
) {
let any_dynamic_crate = crate_type == CrateType::Dylib
|| codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| {
*ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic)
});
if any_dynamic_crate {
if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) {
cmd.args(args);
}
} else {
if let Some(args) = sess.target.late_link_args_static.get(&flavor) {
cmd.args(args);
}
}
fn add_late_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.late_link_args.get(&flavor) {
cmd.args(args);
}
Expand Down Expand Up @@ -1870,7 +1851,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
// FIXME: Built-in target specs occasionally use this for linking system libraries,
// eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)`
// and remove the option.
add_late_link_args(cmd, sess, flavor, crate_type, codegen_results);
add_late_link_args(cmd, sess, flavor);

// ------------ Arbitrary order-independent options ------------

Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,12 +1077,6 @@ pub struct TargetOptions {
/// user-defined but before post-link objects. Standard platform
/// libraries that should be always be linked to, usually go here.
pub late_link_args: LinkArgs,
/// Linker arguments used in addition to `late_link_args` if at least one
/// Rust dependency is dynamically linked.
pub late_link_args_dynamic: LinkArgs,
/// Linker arguments used in addition to `late_link_args` if aall Rust
/// dependencies are statically linked.
pub late_link_args_static: LinkArgs,
/// Linker arguments that are unconditionally passed *after* any
/// user-defined libraries.
pub post_link_args: LinkArgs,
Expand Down Expand Up @@ -1416,8 +1410,6 @@ impl Default for TargetOptions {
post_link_objects_fallback: Default::default(),
crt_objects_fallback: None,
late_link_args: LinkArgs::new(),
late_link_args_dynamic: LinkArgs::new(),
late_link_args_static: LinkArgs::new(),
link_env: Vec::new(),
link_env_remove: Vec::new(),
archive_format: "gnu".to_string(),
Expand Down Expand Up @@ -1965,8 +1957,6 @@ impl Target {
key!(crt_objects_fallback, crt_objects_fallback)?;
key!(pre_link_args, link_args);
key!(late_link_args, link_args);
key!(late_link_args_dynamic, link_args);
key!(late_link_args_static, link_args);
key!(post_link_args, link_args);
key!(link_script, optional);
key!(link_env, env);
Expand Down Expand Up @@ -2204,8 +2194,6 @@ impl ToJson for Target {
target_option_val!(crt_objects_fallback);
target_option_val!(link_args - pre_link_args);
target_option_val!(link_args - late_link_args);
target_option_val!(link_args - late_link_args_dynamic);
target_option_val!(link_args - late_link_args_static);
target_option_val!(link_args - post_link_args);
target_option_val!(link_script);
target_option_val!(env - link_env);
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_target/src/spec/tests/tests_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ impl Target {
self.lld_flavor == LldFlavor::Link,
);
assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link);
for args in &[
&self.pre_link_args,
&self.late_link_args,
&self.late_link_args_dynamic,
&self.late_link_args_static,
&self.post_link_args,
] {
for args in &[&self.pre_link_args, &self.late_link_args, &self.post_link_args] {
assert_eq!(
args.get(&LinkerFlavor::Msvc),
args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
Expand Down
25 changes: 2 additions & 23 deletions compiler/rustc_target/src/spec/windows_gnu_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ pub fn opts() -> TargetOptions {
);

let mut late_link_args = LinkArgs::new();
let mut late_link_args_dynamic = LinkArgs::new();
let mut late_link_args_static = LinkArgs::new();
// Order of `late_link_args*` was found through trial and error to work with various
// mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
let mingw_libs = vec![
Expand All @@ -39,25 +37,6 @@ pub fn opts() -> TargetOptions {
];
late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone());
late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
let dynamic_unwind_libs = vec![
// If any of our crates are dynamically linked then we need to use
// the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries.
"-lgcc_s".to_string(),
];
late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone());
Berrysoft marked this conversation as resolved.
Show resolved Hide resolved
late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs);
let static_unwind_libs = vec![
// If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries.
"-lgcc_eh".to_string(),
"-l:libpthread.a".to_string(),
];
late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone());
late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs);

TargetOptions {
os: "windows".to_string(),
Expand All @@ -81,8 +60,8 @@ pub fn opts() -> TargetOptions {
post_link_objects_fallback: crt_objects::post_mingw_fallback(),
crt_objects_fallback: Some(CrtObjectsFallback::Mingw),
late_link_args,
late_link_args_dynamic,
late_link_args_static,
crt_static_allows_dylibs: true,
crt_static_respected: true,
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
requires_uwtable: true,
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ pub fn opts() -> TargetOptions {
// FIXME: This should be updated for the exception machinery changes from #67502
// and inherit from `windows_gnu_base`, at least partially.
let mut late_link_args = LinkArgs::new();
let late_link_args_dynamic = LinkArgs::new();
let late_link_args_static = LinkArgs::new();
let mingw_libs = vec![
//"-lwinstorecompat".to_string(),
//"-lmingwex".to_string(),
Expand All @@ -30,8 +28,6 @@ pub fn opts() -> TargetOptions {
executables: false,
limit_rdylib_exports: false,
late_link_args,
late_link_args_dynamic,
late_link_args_static,

..base
}
Expand Down
4 changes: 2 additions & 2 deletions library/unwind/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ cc = "1.0.69"

[features]

# Only applies for Linux and Fuchsia targets
# Only applies for MinGW, Linux and Fuchsia targets
# Static link to the in-tree build of llvm libunwind
llvm-libunwind = []

# Only applies for Linux and Fuchsia targets
# Only applies for MinGW, Linux and Fuchsia targets
# If crt-static is enabled, static link to `libunwind.a` provided by system
# If crt-static is disabled, dynamic link to `libunwind.so` provided by system
system-llvm-libunwind = []
26 changes: 26 additions & 0 deletions library/unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,32 @@ extern "C" {}
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern "C" {}

#[cfg(all(
windows,
target_env = "gnu",
not(feature = "llvm-libunwind"),
not(feature = "system-llvm-libunwind")
))]
#[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(
name = "pthread",
kind = "static",
modifiers = "-bundle",
cfg(target_feature = "crt-static")
)]
#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))]
extern "C" {}

#[cfg(all(
windows,
target_env = "gnu",
not(feature = "llvm-libunwind"),
feature = "system-llvm-libunwind"
))]
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
extern "C" {}

#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
extern "C" {}
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/foreign-exceptions/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ all: foo
$(call RUN,foo)

foo: foo.rs $(call NATIVE_STATICLIB,foo)
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS)
$(RUSTC) $< -lfoo $(EXTRACXXFLAGS)

$(TMPDIR)/libfoo.o: foo.cpp
$(call COMPILE_OBJ_CXX,$@,$<)
18 changes: 0 additions & 18 deletions src/test/run-make-fulldeps/tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,11 @@ ifdef IS_MSVC
else
EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt
EXTRACXXFLAGS := -lstdc++
# So this is a bit hacky: we can't use the DLL version of libstdc++ because
# it pulls in the DLL version of libgcc, which means that we end up with 2
# instances of the DW2 unwinding implementation. This is a problem on
# i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
# unwind information with the unwinding implementation, and libstdc++'s
# __cxa_throw won't see the unwinding info we registered with our statically
# linked libgcc.
#
# Now, simply statically linking libstdc++ would fix this problem, except
# that it is compiled with the expectation that pthreads is dynamically
# linked as a DLL and will fail to link with a statically linked libpthread.
#
# So we end up with the following hack: we link use static:-bundle to only
# link the parts of libstdc++ that we actually use, which doesn't include
# the dependency on the pthreads DLL.
EXTRARSCXXFLAGS := -l static:-bundle=stdc++ -Z unstable-options
endif
else
ifeq ($(UNAME),Darwin)
EXTRACFLAGS := -lresolv
EXTRACXXFLAGS := -lc++
EXTRARSCXXFLAGS := -lc++
else
ifeq ($(UNAME),FreeBSD)
EXTRACFLAGS := -lm -lpthread -lgcc_s
Expand All @@ -140,7 +123,6 @@ ifeq ($(UNAME),OpenBSD)
else
EXTRACFLAGS := -lm -lrt -ldl -lpthread
EXTRACXXFLAGS := -lstdc++
EXTRARSCXXFLAGS := -lstdc++
endif
endif
endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
PATH=$(SYSTEMROOT)/system32

all:
$(RUSTC) hello.rs
$(RUSTC) hello.rs -C target-feature=+crt-static
$(TMPDIR)/hello.exe
2 changes: 1 addition & 1 deletion src/test/run-make/issue-36710/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ all: foo
$(call RUN,foo)

foo: foo.rs $(call NATIVE_STATICLIB,foo)
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) --target $(TARGET)
$(RUSTC) $< -lfoo $(EXTRACXXFLAGS) --target $(TARGET)

$(TMPDIR)/libfoo.o: foo.cpp
$(call COMPILE_OBJ_CXX,$@,$<)