Skip to content

Commit f383703

Browse files
committed
Auto merge of rust-lang#111698 - Amanieu:force-static-lib, r=petrochenkov
Force all native libraries to be statically linked when linking a static binary Previously, `#[link]` without an explicit `kind = "static"` would confuse the linker and end up producing a dynamically linked library because of the `-Bdynamic` flag. However this binary would not work correctly anyways since it was linked with startup code for a static binary. This PR solves this by forcing all native libraries to be statically linked when the output is a static binary that cannot link to dynamic libraries anyways. Fixes rust-lang#108878 Fixes rust-lang#102993
2 parents a97c36d + 0304e0a commit f383703

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,14 @@ fn linker_with_args<'a>(
20972097
cmd.add_as_needed();
20982098

20992099
// Local native libraries of all kinds.
2100-
add_local_native_libraries(cmd, sess, archive_builder_builder, codegen_results, tmpdir);
2100+
add_local_native_libraries(
2101+
cmd,
2102+
sess,
2103+
archive_builder_builder,
2104+
codegen_results,
2105+
tmpdir,
2106+
link_output_kind,
2107+
);
21012108

21022109
// Upstream rust crates and their non-dynamic native libraries.
21032110
add_upstream_rust_crates(
@@ -2107,10 +2114,18 @@ fn linker_with_args<'a>(
21072114
codegen_results,
21082115
crate_type,
21092116
tmpdir,
2117+
link_output_kind,
21102118
);
21112119

21122120
// Dynamic native libraries from upstream crates.
2113-
add_upstream_native_libraries(cmd, sess, archive_builder_builder, codegen_results, tmpdir);
2121+
add_upstream_native_libraries(
2122+
cmd,
2123+
sess,
2124+
archive_builder_builder,
2125+
codegen_results,
2126+
tmpdir,
2127+
link_output_kind,
2128+
);
21142129

21152130
// Link with the import library generated for any raw-dylib functions.
21162131
for (raw_dylib_name, raw_dylib_imports) in
@@ -2365,6 +2380,7 @@ fn add_native_libs_from_crate(
23652380
cnum: CrateNum,
23662381
link_static: bool,
23672382
link_dynamic: bool,
2383+
link_output_kind: LinkOutputKind,
23682384
) {
23692385
if !sess.opts.unstable_opts.link_native_libraries {
23702386
// If `-Zlink-native-libraries=false` is set, then the assumption is that an
@@ -2444,8 +2460,16 @@ fn add_native_libs_from_crate(
24442460
}
24452461
}
24462462
NativeLibKind::Unspecified => {
2447-
if link_dynamic {
2448-
cmd.link_dylib(name, verbatim, true);
2463+
// If we are generating a static binary, prefer static library when the
2464+
// link kind is unspecified.
2465+
if !link_output_kind.can_link_dylib() && !sess.target.crt_static_allows_dylibs {
2466+
if link_static {
2467+
cmd.link_staticlib(name, verbatim)
2468+
}
2469+
} else {
2470+
if link_dynamic {
2471+
cmd.link_dylib(name, verbatim, true);
2472+
}
24492473
}
24502474
}
24512475
NativeLibKind::Framework { as_needed } => {
@@ -2472,6 +2496,7 @@ fn add_local_native_libraries(
24722496
archive_builder_builder: &dyn ArchiveBuilderBuilder,
24732497
codegen_results: &CodegenResults,
24742498
tmpdir: &Path,
2499+
link_output_kind: LinkOutputKind,
24752500
) {
24762501
if sess.opts.unstable_opts.link_native_libraries {
24772502
// User-supplied library search paths (-L on the command line). These are the same paths
@@ -2501,6 +2526,7 @@ fn add_local_native_libraries(
25012526
LOCAL_CRATE,
25022527
link_static,
25032528
link_dynamic,
2529+
link_output_kind,
25042530
);
25052531
}
25062532

@@ -2511,6 +2537,7 @@ fn add_upstream_rust_crates<'a>(
25112537
codegen_results: &CodegenResults,
25122538
crate_type: CrateType,
25132539
tmpdir: &Path,
2540+
link_output_kind: LinkOutputKind,
25142541
) {
25152542
// All of the heavy lifting has previously been accomplished by the
25162543
// dependency_format module of the compiler. This is just crawling the
@@ -2588,6 +2615,7 @@ fn add_upstream_rust_crates<'a>(
25882615
cnum,
25892616
link_static,
25902617
link_dynamic,
2618+
link_output_kind,
25912619
);
25922620
}
25932621
}
@@ -2598,6 +2626,7 @@ fn add_upstream_native_libraries(
25982626
archive_builder_builder: &dyn ArchiveBuilderBuilder,
25992627
codegen_results: &CodegenResults,
26002628
tmpdir: &Path,
2629+
link_output_kind: LinkOutputKind,
26012630
) {
26022631
let search_path = OnceCell::new();
26032632
for &cnum in &codegen_results.crate_info.used_crates {
@@ -2626,6 +2655,7 @@ fn add_upstream_native_libraries(
26262655
cnum,
26272656
link_static,
26282657
link_dynamic,
2658+
link_output_kind,
26292659
);
26302660
}
26312661
}

compiler/rustc_target/src/spec/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,17 @@ impl LinkOutputKind {
675675
_ => return None,
676676
})
677677
}
678+
679+
pub fn can_link_dylib(self) -> bool {
680+
match self {
681+
LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false,
682+
LinkOutputKind::DynamicNoPicExe
683+
| LinkOutputKind::DynamicPicExe
684+
| LinkOutputKind::DynamicDylib
685+
| LinkOutputKind::StaticDylib
686+
| LinkOutputKind::WasiReactorExe => true,
687+
}
688+
}
678689
}
679690

680691
impl fmt::Display for LinkOutputKind {

src/doc/rustc/src/command-line-arguments.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ Example: `-l static:+whole-archive=mylib`.
5858

5959
The kind of library and the modifiers can also be specified in a [`#[link]`
6060
attribute][link-attribute]. If the kind is not specified in the `link`
61-
attribute or on the command-line, it will link a dynamic library if available,
62-
otherwise it will use a static library. If the kind is specified on the
61+
attribute or on the command-line, it will link a dynamic library by default,
62+
except when building a static executable. If the kind is specified on the
6363
command-line, it will override the kind specified in a `link` attribute.
6464

6565
The name used in a `link` attribute may be overridden using the form `-l

0 commit comments

Comments
 (0)