Auto merge of #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 #108878 Fixes #102993
This commit is contained in:
commit
f383703e32
3 changed files with 47 additions and 6 deletions
|
@ -2097,7 +2097,14 @@ fn linker_with_args<'a>(
|
||||||
cmd.add_as_needed();
|
cmd.add_as_needed();
|
||||||
|
|
||||||
// Local native libraries of all kinds.
|
// 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.
|
// Upstream rust crates and their non-dynamic native libraries.
|
||||||
add_upstream_rust_crates(
|
add_upstream_rust_crates(
|
||||||
|
@ -2107,10 +2114,18 @@ fn linker_with_args<'a>(
|
||||||
codegen_results,
|
codegen_results,
|
||||||
crate_type,
|
crate_type,
|
||||||
tmpdir,
|
tmpdir,
|
||||||
|
link_output_kind,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Dynamic native libraries from upstream crates.
|
// 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.
|
// Link with the import library generated for any raw-dylib functions.
|
||||||
for (raw_dylib_name, raw_dylib_imports) in
|
for (raw_dylib_name, raw_dylib_imports) in
|
||||||
|
@ -2365,6 +2380,7 @@ fn add_native_libs_from_crate(
|
||||||
cnum: CrateNum,
|
cnum: CrateNum,
|
||||||
link_static: bool,
|
link_static: bool,
|
||||||
link_dynamic: bool,
|
link_dynamic: bool,
|
||||||
|
link_output_kind: LinkOutputKind,
|
||||||
) {
|
) {
|
||||||
if !sess.opts.unstable_opts.link_native_libraries {
|
if !sess.opts.unstable_opts.link_native_libraries {
|
||||||
// If `-Zlink-native-libraries=false` is set, then the assumption is that an
|
// If `-Zlink-native-libraries=false` is set, then the assumption is that an
|
||||||
|
@ -2444,10 +2460,18 @@ fn add_native_libs_from_crate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NativeLibKind::Unspecified => {
|
NativeLibKind::Unspecified => {
|
||||||
|
// 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 {
|
if link_dynamic {
|
||||||
cmd.link_dylib(name, verbatim, true);
|
cmd.link_dylib(name, verbatim, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
NativeLibKind::Framework { as_needed } => {
|
NativeLibKind::Framework { as_needed } => {
|
||||||
if link_dynamic {
|
if link_dynamic {
|
||||||
cmd.link_framework(name, as_needed.unwrap_or(true))
|
cmd.link_framework(name, as_needed.unwrap_or(true))
|
||||||
|
@ -2472,6 +2496,7 @@ fn add_local_native_libraries(
|
||||||
archive_builder_builder: &dyn ArchiveBuilderBuilder,
|
archive_builder_builder: &dyn ArchiveBuilderBuilder,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
tmpdir: &Path,
|
tmpdir: &Path,
|
||||||
|
link_output_kind: LinkOutputKind,
|
||||||
) {
|
) {
|
||||||
if sess.opts.unstable_opts.link_native_libraries {
|
if sess.opts.unstable_opts.link_native_libraries {
|
||||||
// User-supplied library search paths (-L on the command line). These are the same paths
|
// User-supplied library search paths (-L on the command line). These are the same paths
|
||||||
|
@ -2501,6 +2526,7 @@ fn add_local_native_libraries(
|
||||||
LOCAL_CRATE,
|
LOCAL_CRATE,
|
||||||
link_static,
|
link_static,
|
||||||
link_dynamic,
|
link_dynamic,
|
||||||
|
link_output_kind,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2511,6 +2537,7 @@ fn add_upstream_rust_crates<'a>(
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
crate_type: CrateType,
|
crate_type: CrateType,
|
||||||
tmpdir: &Path,
|
tmpdir: &Path,
|
||||||
|
link_output_kind: LinkOutputKind,
|
||||||
) {
|
) {
|
||||||
// All of the heavy lifting has previously been accomplished by the
|
// All of the heavy lifting has previously been accomplished by the
|
||||||
// dependency_format module of the compiler. This is just crawling the
|
// dependency_format module of the compiler. This is just crawling the
|
||||||
|
@ -2588,6 +2615,7 @@ fn add_upstream_rust_crates<'a>(
|
||||||
cnum,
|
cnum,
|
||||||
link_static,
|
link_static,
|
||||||
link_dynamic,
|
link_dynamic,
|
||||||
|
link_output_kind,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2598,6 +2626,7 @@ fn add_upstream_native_libraries(
|
||||||
archive_builder_builder: &dyn ArchiveBuilderBuilder,
|
archive_builder_builder: &dyn ArchiveBuilderBuilder,
|
||||||
codegen_results: &CodegenResults,
|
codegen_results: &CodegenResults,
|
||||||
tmpdir: &Path,
|
tmpdir: &Path,
|
||||||
|
link_output_kind: LinkOutputKind,
|
||||||
) {
|
) {
|
||||||
let search_path = OnceCell::new();
|
let search_path = OnceCell::new();
|
||||||
for &cnum in &codegen_results.crate_info.used_crates {
|
for &cnum in &codegen_results.crate_info.used_crates {
|
||||||
|
@ -2626,6 +2655,7 @@ fn add_upstream_native_libraries(
|
||||||
cnum,
|
cnum,
|
||||||
link_static,
|
link_static,
|
||||||
link_dynamic,
|
link_dynamic,
|
||||||
|
link_output_kind,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -675,6 +675,17 @@ impl LinkOutputKind {
|
||||||
_ => return None,
|
_ => 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 {
|
impl fmt::Display for LinkOutputKind {
|
||||||
|
|
|
@ -58,8 +58,8 @@ Example: `-l static:+whole-archive=mylib`.
|
||||||
|
|
||||||
The kind of library and the modifiers can also be specified in a [`#[link]`
|
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][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,
|
attribute or on the command-line, it will link a dynamic library by default,
|
||||||
otherwise it will use a static library. If the kind is specified on the
|
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.
|
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
|
The name used in a `link` attribute may be overridden using the form `-l
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue