|
1 | 1 | use crate::TargetSelection; |
2 | 2 | use crate::{t, VERSION}; |
| 3 | +use std::env::consts::EXE_SUFFIX; |
3 | 4 | use std::fmt::Write as _; |
4 | | -use std::path::{Path, PathBuf}; |
| 5 | +use std::fs::File; |
| 6 | +use std::path::{Path, PathBuf, MAIN_SEPARATOR}; |
5 | 7 | use std::process::Command; |
6 | 8 | use std::str::FromStr; |
7 | 9 | use std::{ |
@@ -109,7 +111,8 @@ pub fn setup(src_path: &Path, profile: Profile) { |
109 | 111 | println!("`x.py` will now use the configuration at {}", include_path.display()); |
110 | 112 |
|
111 | 113 | let build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); |
112 | | - let stage_path = ["build", build.rustc_target_arg(), "stage1"].join("/"); |
| 114 | + let stage_path = |
| 115 | + ["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); |
113 | 116 |
|
114 | 117 | println!(); |
115 | 118 |
|
@@ -171,6 +174,13 @@ fn attempt_toolchain_link(stage_path: &str) { |
171 | 174 | return; |
172 | 175 | } |
173 | 176 |
|
| 177 | + if !ensure_stage1_toolchain_placeholder_exists(stage_path) { |
| 178 | + println!( |
| 179 | + "Failed to create a template for stage 1 toolchain or confirm that it already exists" |
| 180 | + ); |
| 181 | + return; |
| 182 | + } |
| 183 | + |
174 | 184 | if try_link_toolchain(&stage_path[..]) { |
175 | 185 | println!( |
176 | 186 | "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain" |
@@ -219,6 +229,33 @@ fn try_link_toolchain(stage_path: &str) -> bool { |
219 | 229 | .map_or(false, |output| output.status.success()) |
220 | 230 | } |
221 | 231 |
|
| 232 | +fn ensure_stage1_toolchain_placeholder_exists(stage_path: &str) -> bool { |
| 233 | + let pathbuf = PathBuf::from(stage_path); |
| 234 | + |
| 235 | + if fs::create_dir_all(pathbuf.join("lib")).is_err() { |
| 236 | + return false; |
| 237 | + }; |
| 238 | + |
| 239 | + let pathbuf = pathbuf.join("bin"); |
| 240 | + if fs::create_dir_all(&pathbuf).is_err() { |
| 241 | + return false; |
| 242 | + }; |
| 243 | + |
| 244 | + let pathbuf = pathbuf.join(format!("rustc{}", EXE_SUFFIX)); |
| 245 | + |
| 246 | + if pathbuf.exists() { |
| 247 | + return true; |
| 248 | + } |
| 249 | + |
| 250 | + // Take care not to overwrite the file |
| 251 | + let result = File::options().append(true).create(true).open(&pathbuf); |
| 252 | + if result.is_err() { |
| 253 | + return false; |
| 254 | + } |
| 255 | + |
| 256 | + return true; |
| 257 | +} |
| 258 | + |
222 | 259 | // Used to get the path for `Subcommand::Setup` |
223 | 260 | pub fn interactive_path() -> io::Result<Profile> { |
224 | 261 | fn abbrev_all() -> impl Iterator<Item = ((String, String), Profile)> { |
|
0 commit comments