diff --git a/src/bootstrap/src/core/session.rs b/src/bootstrap/src/core/session.rs index 3e6668258c641..6d0d29dcc1fc4 100644 --- a/src/bootstrap/src/core/session.rs +++ b/src/bootstrap/src/core/session.rs @@ -25,7 +25,8 @@ use crate::utils::build_stamp::BuildStamp; use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, ExecutionContext, command}; use crate::utils::helpers::{ - self, dir_is_empty, exe, libdir, set_file_times, split_debuginfo, symlink_dir, t, + self, dir_is_empty, exe, is_symlink_dir, libdir, set_file_times, split_debuginfo, symlink_dir, + t, }; use crate::{debug, trace}; @@ -1606,7 +1607,11 @@ impl Build { metadata = t!(fs::metadata(&src), format!("target = {}", src.display())); } else { let link = t!(fs::read_link(src)); - t!(self.symlink_file(link, dst)); + if is_symlink_dir(&metadata) { + t!(symlink_dir(&self.config, &link, dst)); + } else { + t!(self.symlink_file(link, dst)); + } return; } } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 8e881f1bf7734..d41ce974c5009 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -185,6 +185,17 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result< } } +/// Detects a symlink or a junction on Windows +pub fn is_symlink_dir(_metadata: &fs::Metadata) -> bool { + #[cfg(windows)] + { + use std::os::windows::fs::FileTypeExt; + _metadata.file_type().is_symlink_dir() + } + #[cfg(not(windows))] + false +} + /// Return the host target on which we are currently running. pub fn get_host_target() -> TargetSelection { TargetSelection::from_user(env!("BUILD_TRIPLE"))