|
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