Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:53:39.707Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

build.rs

243 lines · 7.7 KB · rust
1#![allow(clippy::disallowed_methods, reason = "build scripts are exempt")]
2
3fn main() {
4    #[cfg(target_os = "windows")]
5    {
6        // Compile HLSL shaders
7        #[cfg(not(debug_assertions))]
8        compile_shaders();
9    }
10}
11
12#[cfg(all(target_os = "windows", not(debug_assertions)))]
13mod shader_compilation {
14    use std::{
15        fs,
16        io::Write,
17        path::{Path, PathBuf},
18        process::{self, Command},
19    };
20
21    pub fn compile_shaders() {
22        let shader_path =
23            PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("src/shaders.hlsl");
24        let out_dir = std::env::var("OUT_DIR").unwrap();
25
26        println!("cargo:rerun-if-changed={}", shader_path.display());
27
28        // Check if fxc.exe is available
29        let fxc_path = find_fxc_compiler();
30
31        // Define all modules
32        let modules = [
33            "quad",
34            "shadow",
35            "path_rasterization",
36            "path_sprite",
37            "underline",
38            "monochrome_sprite",
39            "subpixel_sprite",
40            "polychrome_sprite",
41        ];
42
43        let rust_binding_path = format!("{}/shaders_bytes.rs", out_dir);
44        if Path::new(&rust_binding_path).exists() {
45            fs::remove_file(&rust_binding_path)
46                .expect("Failed to remove existing Rust binding file");
47        }
48        for module in modules {
49            compile_shader_for_module(
50                module,
51                &out_dir,
52                &fxc_path,
53                shader_path.to_str().unwrap(),
54                &rust_binding_path,
55            );
56        }
57
58        {
59            let shader_path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap())
60                .join("src/color_text_raster.hlsl");
61            compile_shader_for_module(
62                "emoji_rasterization",
63                &out_dir,
64                &fxc_path,
65                shader_path.to_str().unwrap(),
66                &rust_binding_path,
67            );
68        }
69    }
70
71    /// Locate `binary` in the newest installed Windows SDK.
72    pub fn find_latest_windows_sdk_binary(
73        binary: &str,
74    ) -> Result<Option<PathBuf>, Box<dyn std::error::Error>> {
75        let key = windows_registry::LOCAL_MACHINE
76            .open("SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0")?;
77
78        let install_folder: String = key.get_string("InstallationFolder")?; // "C:\Program Files (x86)\Windows Kits\10\"
79        let install_folder_bin = Path::new(&install_folder).join("bin");
80
81        let mut versions: Vec<_> = std::fs::read_dir(&install_folder_bin)?
82            .flatten()
83            .filter(|entry| entry.path().is_dir())
84            .filter_map(|entry| entry.file_name().into_string().ok())
85            .collect();
86
87        versions.sort_by_key(|s| {
88            s.split('.')
89                .filter_map(|p| p.parse().ok())
90                .collect::<Vec<u32>>()
91        });
92
93        let arch = match std::env::consts::ARCH {
94            "x86_64" => "x64",
95            "aarch64" => "arm64",
96            _ => Err(format!(
97                "Unsupported architecture: {}",
98                std::env::consts::ARCH
99            ))?,
100        };
101
102        if let Some(highest_version) = versions.last() {
103            return Ok(Some(
104                install_folder_bin
105                    .join(highest_version)
106                    .join(arch)
107                    .join(binary),
108            ));
109        }
110
111        Ok(None)
112    }
113
114    /// You can set the `GPUI_FXC_PATH` environment variable to specify the path to the fxc.exe compiler.
115    fn find_fxc_compiler() -> String {
116        // Check environment variable
117        if let Ok(path) = std::env::var("GPUI_FXC_PATH")
118            && Path::new(&path).exists()
119        {
120            return path;
121        }
122
123        // Try to find in PATH
124        // NOTE: This has to be `where.exe` on Windows, not `where`, it must be ended with `.exe`
125        if let Ok(output) = std::process::Command::new("where.exe")
126            .arg("fxc.exe")
127            .output()
128            && output.status.success()
129        {
130            let path = String::from_utf8_lossy(&output.stdout);
131            return path.trim().to_string();
132        }
133
134        if let Ok(Some(path)) = find_latest_windows_sdk_binary("fxc.exe") {
135            return path.to_string_lossy().into_owned();
136        }
137
138        panic!("Failed to find fxc.exe");
139    }
140
141    fn compile_shader_for_module(
142        module: &str,
143        out_dir: &str,
144        fxc_path: &str,
145        shader_path: &str,
146        rust_binding_path: &str,
147    ) {
148        // Compile vertex shader
149        let output_file = format!("{}/{}_vs.h", out_dir, module);
150        let const_name = format!("{}_VERTEX_BYTES", module.to_uppercase());
151        compile_shader_impl(
152            fxc_path,
153            &format!("{module}_vertex"),
154            &output_file,
155            &const_name,
156            shader_path,
157            "vs_4_1",
158        );
159        generate_rust_binding(&const_name, &output_file, rust_binding_path);
160
161        // Compile fragment shader
162        let output_file = format!("{}/{}_ps.h", out_dir, module);
163        let const_name = format!("{}_FRAGMENT_BYTES", module.to_uppercase());
164        compile_shader_impl(
165            fxc_path,
166            &format!("{module}_fragment"),
167            &output_file,
168            &const_name,
169            shader_path,
170            "ps_4_1",
171        );
172        generate_rust_binding(&const_name, &output_file, rust_binding_path);
173    }
174
175    fn compile_shader_impl(
176        fxc_path: &str,
177        entry_point: &str,
178        output_path: &str,
179        var_name: &str,
180        shader_path: &str,
181        target: &str,
182    ) {
183        let output = Command::new(fxc_path)
184            .args([
185                "/T",
186                target,
187                "/E",
188                entry_point,
189                "/Fh",
190                output_path,
191                "/Vn",
192                var_name,
193                "/O3",
194                shader_path,
195            ])
196            .output();
197
198        match output {
199            Ok(result) => {
200                if result.status.success() {
201                    return;
202                }
203                println!(
204                    "cargo::error=Shader compilation failed for {}:\n{}",
205                    entry_point,
206                    String::from_utf8_lossy(&result.stderr)
207                );
208                process::exit(1);
209            }
210            Err(e) => {
211                println!("cargo::error=Failed to run fxc for {}: {}", entry_point, e);
212                process::exit(1);
213            }
214        }
215    }
216
217    fn generate_rust_binding(const_name: &str, head_file: &str, output_path: &str) {
218        let header_content = fs::read_to_string(head_file).expect("Failed to read header file");
219        let const_definition = {
220            let global_var_start = header_content.find("const BYTE").unwrap();
221            let global_var = &header_content[global_var_start..];
222            let equal = global_var.find('=').unwrap();
223            global_var[equal + 1..].trim()
224        };
225        let rust_binding = format!(
226            "const {}: &[u8] = &{}\n",
227            const_name,
228            const_definition.replace('{', "[").replace('}', "]")
229        );
230        let mut options = fs::OpenOptions::new()
231            .create(true)
232            .append(true)
233            .open(output_path)
234            .expect("Failed to open Rust binding file");
235        options
236            .write_all(rust_binding.as_bytes())
237            .expect("Failed to write Rust binding file");
238    }
239}
240
241#[cfg(all(target_os = "windows", not(debug_assertions)))]
242use shader_compilation::compile_shaders;
243
Served at tenant.openagents/omega Member data and write actions are omitted.