Skip to content

Commit

Permalink
Force all native libraries to be statically linked when linking a sta…
Browse files Browse the repository at this point in the history
…tic binary
  • Loading branch information
Amanieu committed Jun 7, 2023
1 parent c2ccc85 commit 0304e0a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
38 changes: 34 additions & 4 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2129,7 +2129,14 @@ fn linker_with_args<'a>(
cmd.add_as_needed();

// Local native libraries of all kinds.
add_local_native_libraries(cmd, sess, archive_builder_builder, codegen_results, tmpdir);
add_local_native_libraries(
cmd,
sess,
archive_builder_builder,
codegen_results,
tmpdir,
link_output_kind,
);

// Upstream rust crates and their non-dynamic native libraries.
add_upstream_rust_crates(
Expand All @@ -2139,10 +2146,18 @@ fn linker_with_args<'a>(
codegen_results,
crate_type,
tmpdir,
link_output_kind,
);

// Dynamic native libraries from upstream crates.
add_upstream_native_libraries(cmd, sess, archive_builder_builder, codegen_results, tmpdir);
add_upstream_native_libraries(
cmd,
sess,
archive_builder_builder,
codegen_results,
tmpdir,
link_output_kind,
);

// Link with the import library generated for any raw-dylib functions.
for (raw_dylib_name, raw_dylib_imports) in
Expand Down Expand Up @@ -2397,6 +2412,7 @@ fn add_native_libs_from_crate(
cnum: CrateNum,
link_static: bool,
link_dynamic: bool,
link_output_kind: LinkOutputKind,
) {
if !sess.opts.unstable_opts.link_native_libraries {
// If `-Zlink-native-libraries=false` is set, then the assumption is that an
Expand Down Expand Up @@ -2476,8 +2492,16 @@ fn add_native_libs_from_crate(
}
}
NativeLibKind::Unspecified => {
if link_dynamic {
cmd.link_dylib(name, verbatim, true);
// If we are generating a static binary, prefer static library when the
// link kind is unspecified.
if !link_output_kind.can_link_dylib() && !sess.target.crt_static_allows_dylibs {
if link_static {
cmd.link_staticlib(name, verbatim)
}
} else {
if link_dynamic {
cmd.link_dylib(name, verbatim, true);
}
}
}
NativeLibKind::Framework { as_needed } => {
Expand All @@ -2504,6 +2528,7 @@ fn add_local_native_libraries(
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
) {
if sess.opts.unstable_opts.link_native_libraries {
// User-supplied library search paths (-L on the command line). These are the same paths
Expand Down Expand Up @@ -2533,6 +2558,7 @@ fn add_local_native_libraries(
LOCAL_CRATE,
link_static,
link_dynamic,
link_output_kind,
);
}

Expand All @@ -2543,6 +2569,7 @@ fn add_upstream_rust_crates<'a>(
codegen_results: &CodegenResults,
crate_type: CrateType,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
) {
// All of the heavy lifting has previously been accomplished by the
// dependency_format module of the compiler. This is just crawling the
Expand Down Expand Up @@ -2620,6 +2647,7 @@ fn add_upstream_rust_crates<'a>(
cnum,
link_static,
link_dynamic,
link_output_kind,
);
}
}
Expand All @@ -2630,6 +2658,7 @@ fn add_upstream_native_libraries(
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
tmpdir: &Path,
link_output_kind: LinkOutputKind,
) {
let search_path = OnceCell::new();
for &cnum in &codegen_results.crate_info.used_crates {
Expand Down Expand Up @@ -2658,6 +2687,7 @@ fn add_upstream_native_libraries(
cnum,
link_static,
link_dynamic,
link_output_kind,
);
}
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,17 @@ impl LinkOutputKind {
_ => return None,
})
}

pub fn can_link_dylib(self) -> bool {
match self {
LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false,
LinkOutputKind::DynamicNoPicExe
| LinkOutputKind::DynamicPicExe
| LinkOutputKind::DynamicDylib
| LinkOutputKind::StaticDylib
| LinkOutputKind::WasiReactorExe => true,
}
}
}

impl fmt::Display for LinkOutputKind {
Expand Down
4 changes: 2 additions & 2 deletions src/doc/rustc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ Example: `-l static:+whole-archive=mylib`.

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

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

0 comments on commit 0304e0a

Please sign in to comment.