Add unstable rustc option to control self-contained linkage mode
This commit is contained in:
parent
1557fb031b
commit
2e3f51775a
3 changed files with 42 additions and 19 deletions
|
@ -140,7 +140,12 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
|
|||
// The third parameter is for env vars, used on windows to set up the
|
||||
// path for MSVC to find its DLLs, and gcc to find its bundled
|
||||
// toolchain
|
||||
fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command {
|
||||
fn get_linker(
|
||||
sess: &Session,
|
||||
linker: &Path,
|
||||
flavor: LinkerFlavor,
|
||||
self_contained: bool,
|
||||
) -> Command {
|
||||
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
|
||||
|
||||
// If our linker looks like a batch script on Windows then to execute this
|
||||
|
@ -199,7 +204,7 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command {
|
|||
|
||||
// The compiler's sysroot often has some bundled tools, so add it to the
|
||||
// PATH for the child.
|
||||
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
|
||||
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(self_contained);
|
||||
let mut msvc_changed_path = false;
|
||||
if sess.target.target.options.is_like_msvc {
|
||||
if let Some(ref tool) = msvc_tool {
|
||||
|
@ -563,7 +568,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
|
|||
.iter()
|
||||
.copied()
|
||||
.flatten()
|
||||
.map(|obj| get_object_file_path(sess, obj).into_os_string())
|
||||
.map(|obj| get_object_file_path(sess, obj, fallback).into_os_string())
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let pre_objects_static_pie = get_objects(pre_objects, LinkOutputKind::StaticPicExe);
|
||||
|
@ -1066,9 +1071,11 @@ fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_object_file_path(sess: &Session, name: &str) -> PathBuf {
|
||||
fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> PathBuf {
|
||||
// prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
|
||||
if sess.target.target.llvm_target.contains("windows-gnu") {
|
||||
if sess.opts.debugging_opts.link_self_contained.is_none()
|
||||
&& sess.target.target.llvm_target.contains("windows-gnu")
|
||||
{
|
||||
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
|
||||
let file_path = compiler_libs_path.join(name);
|
||||
if file_path.exists() {
|
||||
|
@ -1081,9 +1088,12 @@ fn get_object_file_path(sess: &Session, name: &str) -> PathBuf {
|
|||
if file_path.exists() {
|
||||
return file_path;
|
||||
}
|
||||
let file_path = fs.get_selfcontained_lib_path().join(name);
|
||||
if file_path.exists() {
|
||||
return file_path;
|
||||
// Special directory with objects used only in self-contained linkage mode
|
||||
if self_contained {
|
||||
let file_path = fs.get_selfcontained_lib_path().join(name);
|
||||
if file_path.exists() {
|
||||
return file_path;
|
||||
}
|
||||
}
|
||||
for search_path in fs.search_paths() {
|
||||
let file_path = search_path.dir.join(name);
|
||||
|
@ -1268,6 +1278,10 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
|
|||
/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
|
||||
/// We only provide such support for a very limited number of targets.
|
||||
fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
|
||||
if let Some(self_contained) = sess.opts.debugging_opts.link_self_contained {
|
||||
return self_contained;
|
||||
}
|
||||
|
||||
match sess.target.target.options.crt_objects_fallback {
|
||||
// FIXME: Find a better heuristic for "native musl toolchain is available",
|
||||
// based on host and linker path, for example.
|
||||
|
@ -1292,7 +1306,7 @@ fn add_pre_link_objects(
|
|||
let opts = &sess.target.target.options;
|
||||
let objects = if fallback { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects };
|
||||
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
|
||||
cmd.add_object(&get_object_file_path(sess, obj));
|
||||
cmd.add_object(&get_object_file_path(sess, obj, fallback));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1306,7 +1320,7 @@ fn add_post_link_objects(
|
|||
let opts = &sess.target.target.options;
|
||||
let objects = if fallback { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
|
||||
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
|
||||
cmd.add_object(&get_object_file_path(sess, obj));
|
||||
cmd.add_object(&get_object_file_path(sess, obj, fallback));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1468,9 +1482,12 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
|
|||
}
|
||||
|
||||
/// Add sysroot and other globally set directories to the directory search list.
|
||||
fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
|
||||
fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) {
|
||||
// Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details.
|
||||
if cfg!(windows) && sess.target.target.llvm_target.contains("windows-gnu") {
|
||||
if sess.opts.debugging_opts.link_self_contained.is_none()
|
||||
&& cfg!(windows)
|
||||
&& sess.target.target.llvm_target.contains("windows-gnu")
|
||||
{
|
||||
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
|
||||
cmd.include_path(&compiler_libs_path);
|
||||
}
|
||||
|
@ -1481,8 +1498,11 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
|
|||
let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
|
||||
|
||||
let lib_path = sess.target_filesearch(PathKind::All).get_selfcontained_lib_path();
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
|
||||
// Special directory with libraries used only in self-contained linkage mode
|
||||
if self_contained {
|
||||
let lib_path = sess.target_filesearch(PathKind::All).get_selfcontained_lib_path();
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
|
||||
}
|
||||
}
|
||||
|
||||
/// Add options making relocation sections in the produced ELF files read-only
|
||||
|
@ -1545,13 +1565,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
|||
codegen_results: &CodegenResults,
|
||||
target_cpu: &str,
|
||||
) -> Command {
|
||||
let base_cmd = get_linker(sess, path, flavor);
|
||||
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
|
||||
let base_cmd = get_linker(sess, path, flavor, crt_objects_fallback);
|
||||
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
|
||||
// to the linker args construction.
|
||||
assert!(base_cmd.get_args().is_empty() || sess.target.target.target_vendor == "uwp");
|
||||
let cmd = &mut *codegen_results.linker_info.to_linker(base_cmd, &sess, flavor, target_cpu);
|
||||
let link_output_kind = link_output_kind(sess, crate_type);
|
||||
let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
|
||||
|
||||
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
|
||||
add_pre_link_args(cmd, sess, flavor);
|
||||
|
@ -1597,7 +1617,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
|
|||
|
||||
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
|
||||
// FIXME: Order-dependent, at least relatively to other args adding searh directories.
|
||||
add_library_search_dirs(cmd, sess);
|
||||
add_library_search_dirs(cmd, sess, crt_objects_fallback);
|
||||
|
||||
// OBJECT-FILES-YES
|
||||
add_local_crate_regular_objects(cmd, codegen_results);
|
||||
|
|
|
@ -92,13 +92,13 @@ impl<'a> FileSearch<'a> {
|
|||
}
|
||||
|
||||
// Returns a list of directories where target-specific tool binaries are located.
|
||||
pub fn get_tools_search_paths(&self) -> Vec<PathBuf> {
|
||||
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
||||
let mut p = PathBuf::from(self.sysroot);
|
||||
p.push(find_libdir(self.sysroot).as_ref());
|
||||
p.push(RUST_LIB_DIR);
|
||||
p.push(&self.triple);
|
||||
p.push("bin");
|
||||
vec![p.clone(), p.join("self-contained")]
|
||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p.clone()] }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -888,6 +888,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
"keep hygiene data after analysis (default: no)"),
|
||||
link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
|
||||
"link native libraries in the linker invocation (default: yes)"),
|
||||
link_self_contained: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"control whether to link Rust provided C objects/libraries or rely
|
||||
on C toolchain installed in the system"),
|
||||
link_only: bool = (false, parse_bool, [TRACKED],
|
||||
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
|
||||
llvm_time_trace: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue