From c801efdd033ac03749d97dade2bf01431d92b214 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 26 Jun 2026 11:45:55 +0530 Subject: [PATCH] Function to build slang code to IR --- kitty/constants.py | 2 +- kitty/shaders/slang.py | 61 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/kitty/constants.py b/kitty/constants.py index 2d14a7007..d38c4a8cb 100644 --- a/kitty/constants.py +++ b/kitty/constants.py @@ -35,7 +35,7 @@ kitty_run_data: dict[str, Any] = getattr(sys, 'kitty_run_data', {}) launched_by_launch_services = kitty_run_data.get('launched_by_launch_services', False) is_quick_access_terminal_app = kitty_run_data.get('is_quick_access_terminal_app', False) unserialize_launch_flag = 'kitty-unserialize-data=' -slangc = [os.environ.get('SLANGC', 'slangc')] +slangc = os.environ.get('SLANGC', 'slangc').split() if getattr(sys, 'frozen', False): diff --git a/kitty/shaders/slang.py b/kitty/shaders/slang.py index 049b29280..c00f17f0b 100644 --- a/kitty/shaders/slang.py +++ b/kitty/shaders/slang.py @@ -7,9 +7,12 @@ import os import re import shutil +import time +from collections import OrderedDict +from contextlib import suppress from enum import Enum from functools import lru_cache -from typing import NamedTuple +from typing import Iterator, NamedTuple class Stage(Enum): @@ -29,6 +32,10 @@ class SlangFile(NamedTuple): entry_points: frozenset[EntryPoint] module: str + @property + def should_compile_to_ir(self) -> bool: + return bool(self.module or self.entry_points) + def parse_slang_text(text: str, path: str = '') -> SlangFile: text = re.sub(r'/\*[\s\S]*?\*/', '', text) @@ -102,10 +109,9 @@ def topological_sort(graph: dict[str, SlangFile]) -> list[str]: return order -def get_ordered_sources_in_tree(dirpath: str) -> dict[str, SlangFile]: - ans = build_import_graph(dirpath) - topological_sort(ans) - return ans +def get_ordered_sources_in_tree(dirpath: str) -> OrderedDict[str, SlangFile]: + g = build_import_graph(dirpath) + return OrderedDict({k: g[k] for k in topological_sort(g)}) @@ -118,4 +124,47 @@ def slangc() -> tuple[str, ...]: if not ans: raise SystemExit('Could not find the slangc shader compiler on PATH') slangc = [ans] - return tuple(slangc + ['-std', '2026']) + return tuple(slangc) + + +def future() -> float: + return time.time() + 1000000 + + +def safe_mtime(path: str, defval: float = 0) -> float: + with suppress(OSError): + return os.path.getmtime(path) + return defval if defval >= 0 else future() + + +def read_deps_file(path: str) -> Iterator[str]: + with open(path) as f: + for line in f: + line = line.partition(':')[2].strip() + yield from line.split() + + +def get_newest_dep_time(path: str) -> float: + with suppress(OSError): + ans = 0. + for deppath in read_deps_file(path): + mtime = os.path.getmtime(deppath) + ans = max(mtime, ans) + return ans + return future() + + +def commands_to_compile_dir_to_ir(dirpath: str, output_dirpath: str) -> Iterator[tuple[bool, list[str]]]: + cmdbase = list(slangc()) + for name, sfile in get_ordered_sources_in_tree(dirpath).items(): + if sfile.should_compile_to_ir: + parts = name.split('.') + base_dest = os.path.join(output_dirpath, *parts) + slang_module = f'{base_dest}.slang-module' + deps_file = f'{base_dest}.deps' + module_mtime = safe_mtime(slang_module) + needs_build = module_mtime < get_newest_dep_time(deps_file) + yield needs_build, cmdbase + [ + sfile.path, '-I', output_dirpath, '-I', dirpath, '-depfile', deps_file, + '-target', 'none', '-o', slang_module + ]