|
1 | 1 | //! Commands for building zrc toolchains |
2 | 2 |
|
| 3 | +use std::{error::Error, process::Command}; |
| 4 | + |
3 | 5 | use clap::Parser; |
4 | | -use std::error::Error; |
5 | 6 |
|
6 | | -use crate::cli::DispatchCommand; |
7 | | -use crate::{build, deps, git_utils, installer, paths}; |
| 7 | +use crate::{cli::DispatchCommand, deps, git_utils, paths}; |
8 | 8 |
|
9 | 9 | /// Build a specific version of zrc |
10 | 10 | #[derive(Parser)] |
@@ -54,56 +54,104 @@ impl DispatchCommand for BuildCmd { |
54 | 54 |
|
55 | 55 | println!("Building version: {}", version); |
56 | 56 |
|
57 | | - // Check if cargo is available |
58 | | - build::check_cargo()?; |
59 | | - |
60 | | - // Build zrc |
61 | | - build::build_zrc(&source_dir)?; |
62 | | - |
63 | 57 | // Create toolchain directory |
64 | 58 | let toolchain_dir = paths::toolchain_dir(&version); |
65 | | - let toolchain_bin_dir = paths::toolchain_bin_dir(&version); |
66 | | - let toolchain_include_dir = paths::toolchain_include_dir(&version); |
67 | | - |
68 | | - std::fs::create_dir_all(&toolchain_bin_dir)?; |
69 | | - std::fs::create_dir_all(&toolchain_include_dir)?; |
70 | | - |
71 | | - // Install binary |
72 | | - installer::install_zrc_binary(&source_dir, &toolchain_bin_dir)?; |
73 | | - |
74 | | - // Install zircop binary if it exists |
75 | | - let has_zircop = installer::install_zircop_binary(&source_dir, &toolchain_bin_dir)?; |
| 59 | + std::fs::create_dir_all(&toolchain_dir)?; |
76 | 60 |
|
77 | | - // Install include files |
78 | | - installer::install_include_files(&source_dir, &toolchain_include_dir)?; |
| 61 | + // Execute the hook script from the zrc repo |
| 62 | + // The hook handles building and installing to the toolchain directory |
| 63 | + run_build_hook(&source_dir, &toolchain_dir)?; |
79 | 64 |
|
80 | 65 | // Update current symlink |
81 | 66 | let current_link = paths::current_toolchain_link(); |
82 | 67 | paths::create_link(&toolchain_dir, ¤t_link)?; |
83 | 68 |
|
84 | | - // Create/update bin links |
85 | | - let zrc_link = paths::zrc_binary_link(); |
86 | | - let zrc_binary = paths::toolchain_zrc_binary(&version); |
87 | | - paths::create_link(&zrc_binary, &zrc_link)?; |
88 | | - |
89 | | - // Create/update zircop bin link if it exists |
90 | | - if has_zircop { |
91 | | - let zircop_link = paths::zircop_binary_link(); |
92 | | - let zircop_binary = paths::toolchain_zircop_binary(&version); |
93 | | - paths::create_link(&zircop_binary, &zircop_link)?; |
94 | | - } |
95 | | - |
96 | | - // Create/update include link |
97 | | - let include_link = paths::include_dir_link(); |
98 | | - paths::create_link(&toolchain_include_dir, &include_link)?; |
99 | | - |
100 | 69 | println!("\n✓ Successfully built and installed zrc {}", version); |
101 | 70 | println!(" Toolchain location: {}", toolchain_dir.display()); |
102 | | - println!("\nTo use zrc, add to your PATH:"); |
103 | | - println!(" export PATH=\"{}:$PATH\"", paths::bin_dir().display()); |
104 | | - println!("\nOr run:"); |
| 71 | + println!("\nTo use zrc, run:"); |
105 | 72 | println!(" source <(zircon env)"); |
106 | 73 |
|
107 | 74 | Ok(()) |
108 | 75 | } |
109 | 76 | } |
| 77 | + |
| 78 | +/// Run the build hook script from the zrc repository |
| 79 | +#[cfg(unix)] |
| 80 | +fn run_build_hook( |
| 81 | + source_dir: &std::path::Path, |
| 82 | + toolchain_dir: &std::path::Path, |
| 83 | +) -> Result<(), Box<dyn Error>> { |
| 84 | + let hook_script = source_dir.join("hooks").join("zircon.sh"); |
| 85 | + if !hook_script.exists() { |
| 86 | + return Err(format!( |
| 87 | + "Hook script not found at {}. This version of zrc may not support zircon hooks.", |
| 88 | + hook_script.display() |
| 89 | + ) |
| 90 | + .into()); |
| 91 | + } |
| 92 | + |
| 93 | + println!("Running zrc build hook..."); |
| 94 | + let status = Command::new("bash") |
| 95 | + .arg(&hook_script) |
| 96 | + .env("ZIRCON_TOOLCHAIN_DIR", toolchain_dir) |
| 97 | + .current_dir(source_dir) |
| 98 | + .status()?; |
| 99 | + |
| 100 | + if !status.success() { |
| 101 | + let exit_code = status.code().unwrap_or(-1); |
| 102 | + return Err(format!("Hook script failed (exit code: {})", exit_code).into()); |
| 103 | + } |
| 104 | + |
| 105 | + Ok(()) |
| 106 | +} |
| 107 | + |
| 108 | +/// Run the build hook script from the zrc repository (Windows) |
| 109 | +#[cfg(windows)] |
| 110 | +fn run_build_hook( |
| 111 | + source_dir: &std::path::Path, |
| 112 | + toolchain_dir: &std::path::Path, |
| 113 | +) -> Result<(), Box<dyn Error>> { |
| 114 | + // Check for PowerShell script first, then batch file |
| 115 | + let ps_hook = source_dir.join("hooks").join("zircon.ps1"); |
| 116 | + let bat_hook = source_dir.join("hooks").join("zircon.bat"); |
| 117 | + |
| 118 | + if ps_hook.exists() { |
| 119 | + println!("Running zrc build hook (PowerShell)..."); |
| 120 | + // Use Bypass to run local scripts regardless of system execution policy. |
| 121 | + // This is safe because the script is part of the zrc repo the user cloned. |
| 122 | + let status = Command::new("powershell") |
| 123 | + .args(["-ExecutionPolicy", "Bypass", "-File"]) |
| 124 | + .arg(&ps_hook) |
| 125 | + .env("ZIRCON_TOOLCHAIN_DIR", toolchain_dir) |
| 126 | + .current_dir(source_dir) |
| 127 | + .status()?; |
| 128 | + |
| 129 | + if !status.success() { |
| 130 | + let exit_code = status.code().unwrap_or(-1); |
| 131 | + return Err(format!("Hook script failed (exit code: {})", exit_code).into()); |
| 132 | + } |
| 133 | + } else if bat_hook.exists() { |
| 134 | + println!("Running zrc build hook (batch)..."); |
| 135 | + let status = Command::new("cmd") |
| 136 | + .args(["/C"]) |
| 137 | + .arg(&bat_hook) |
| 138 | + .env("ZIRCON_TOOLCHAIN_DIR", toolchain_dir) |
| 139 | + .current_dir(source_dir) |
| 140 | + .status()?; |
| 141 | + |
| 142 | + if !status.success() { |
| 143 | + let exit_code = status.code().unwrap_or(-1); |
| 144 | + return Err(format!("Hook script failed (exit code: {})", exit_code).into()); |
| 145 | + } |
| 146 | + } else { |
| 147 | + return Err(format!( |
| 148 | + "No Windows hook script found at {} or {}. \ |
| 149 | + This version of zrc may not support Windows builds via zircon hooks.", |
| 150 | + ps_hook.display(), |
| 151 | + bat_hook.display() |
| 152 | + ) |
| 153 | + .into()); |
| 154 | + } |
| 155 | + |
| 156 | + Ok(()) |
| 157 | +} |
0 commit comments