1use std::path::PathBuf;
2
3use crate::compiler::clang::Clang;
4use crate::compiler::clang_cl::ClangCl;
5use crate::options::XWinOptions;
6use anyhow::Result;
7use clap::{Parser, Subcommand};
8use fs_err as fs;
9
10#[derive(Debug, Parser)]
12pub struct Cache {
13 #[command(subcommand)]
14 pub subcommand: CacheSubcommand,
15}
16
17#[derive(Debug, Subcommand)]
18pub enum CacheSubcommand {
19 Xwin(CacheXwin),
21 WindowsMsvcSysroot(CacheWindowsMsvcSysroot),
23}
24
25#[derive(Debug, Parser)]
27pub struct CacheXwin {
28 #[command(flatten)]
29 pub xwin_options: XWinOptions,
30
31 #[arg(long)]
33 pub update: bool,
34}
35
36#[derive(Debug, Parser)]
38pub struct CacheWindowsMsvcSysroot {
39 #[arg(long, env = "XWIN_CACHE_DIR")]
41 pub cache_dir: Option<PathBuf>,
42}
43
44fn get_default_cache_dir() -> PathBuf {
46 dirs::cache_dir()
47 .unwrap_or_else(|| std::env::current_dir().expect("Failed to get current dir"))
48 .join(env!("CARGO_PKG_NAME"))
49}
50
51fn prepare_cache_dir(cache_dir: Option<PathBuf>) -> Result<PathBuf> {
53 let cache_dir = cache_dir.unwrap_or_else(get_default_cache_dir);
54 fs::create_dir_all(&cache_dir)?;
55 cache_dir.canonicalize().map_err(Into::into)
56}
57
58pub fn prepare_xwin_cache_dir(base_cache_dir: PathBuf) -> Result<PathBuf> {
60 let xwin_cache_dir = base_cache_dir.join("xwin");
61 fs::create_dir_all(&xwin_cache_dir)?;
62 xwin_cache_dir.canonicalize().map_err(Into::into)
63}
64
65impl Cache {
66 pub fn execute(self) -> Result<()> {
67 match self.subcommand {
68 CacheSubcommand::Xwin(xwin) => xwin.execute(),
69 CacheSubcommand::WindowsMsvcSysroot(sysroot) => sysroot.execute(),
70 }
71 }
72}
73
74impl CacheXwin {
75 pub fn execute(self) -> Result<()> {
76 let cache_dir = prepare_cache_dir(self.xwin_options.xwin_cache_dir.clone())?;
77 let xwin_cache_dir = prepare_xwin_cache_dir(cache_dir)?;
78
79 println!("📦 Pre-caching Microsoft CRT and Windows SDK...");
80 println!("📁 Cache directory: {}", xwin_cache_dir.display());
81
82 let clang_cl = ClangCl::new(&self.xwin_options);
83 clang_cl.setup_msvc_crt(xwin_cache_dir, self.update)?;
84
85 println!("✅ xwin cache setup completed successfully!");
86 Ok(())
87 }
88}
89
90impl CacheWindowsMsvcSysroot {
91 pub fn execute(self) -> Result<()> {
92 let cache_dir = prepare_cache_dir(self.cache_dir.clone())?;
93
94 println!("📦 Pre-caching windows-msvc-sysroot...");
95 println!("📁 Cache directory: {}", cache_dir.display());
96
97 let clang = Clang::new();
98 let sysroot_dir = clang.setup_msvc_sysroot(cache_dir)?;
99
100 println!("✅ windows-msvc-sysroot cache setup completed successfully!");
101 println!("📁 Sysroot location: {}", sysroot_dir.display());
102 Ok(())
103 }
104}