Skip to content

Commit af61fd1

Browse files
committed
Move glfw build code into setup.py
This was on my TODO list for a long time and doing this allows the setup.py module code to be re-used in slang.py
1 parent cfbae29 commit af61fd1

4 files changed

Lines changed: 229 additions & 231 deletions

File tree

glfw/__init__.py

Whitespace-only changes.

glfw/glfw.py

Lines changed: 0 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -2,234 +2,13 @@
22
# vim:fileencoding=utf-8
33
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
44

5-
import json
65
import os
76
import re
8-
import subprocess
97
import sys
10-
from enum import Enum
11-
from typing import Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
128

139
_plat = sys.platform.lower()
1410
is_linux = 'linux' in _plat
1511
is_openbsd = 'openbsd' in _plat
16-
base = os.path.dirname(os.path.abspath(__file__))
17-
18-
19-
def null_func() -> None:
20-
return None
21-
22-
23-
class CompileKey(NamedTuple):
24-
src: str
25-
dest: str
26-
27-
28-
class Command(NamedTuple):
29-
desc: str
30-
cmd: Sequence[str]
31-
is_newer_func: Callable[[], bool]
32-
on_success: Callable[[], None] = null_func
33-
key: Optional[CompileKey] = None
34-
keyfile: Optional[str] = None
35-
36-
37-
class ISA(Enum):
38-
X86 = 0x03
39-
AMD64 = 0x3e
40-
ARM64 = 0xb7
41-
Other = 0x0
42-
43-
44-
class BinaryArch(NamedTuple):
45-
bits: int = 64
46-
isa: ISA = ISA.AMD64
47-
48-
49-
class CompilerType(Enum):
50-
gcc = 'gcc'
51-
clang = 'clang'
52-
unknown = 'unknown'
53-
54-
55-
class Env:
56-
57-
cc: List[str] = []
58-
cppflags: List[str] = []
59-
cflags: List[str] = []
60-
ldflags: List[str] = []
61-
library_paths: Dict[str, List[str]] = {}
62-
ldpaths: List[str] = []
63-
ccver: Tuple[int, int]
64-
vcs_rev: str = ''
65-
binary_arch: BinaryArch = BinaryArch()
66-
native_optimizations: bool = False
67-
primary_version: int = 0
68-
secondary_version: int = 0
69-
xt_version: str = ''
70-
has_copy_file_range: bool = False
71-
72-
# glfw stuff
73-
all_headers: List[str] = []
74-
sources: List[str] = []
75-
wayland_packagedir: str = ''
76-
wayland_scanner: str = ''
77-
wayland_scanner_code: str = ''
78-
wayland_protocols: Tuple[str, ...] = ()
79-
80-
def __init__(
81-
self, cc: List[str] = [], cppflags: List[str] = [], cflags: List[str] = [], ldflags: List[str] = [],
82-
library_paths: Dict[str, List[str]] = {}, ldpaths: Optional[List[str]] = None, ccver: Tuple[int, int] = (0, 0),
83-
vcs_rev: str = '', binary_arch: BinaryArch = BinaryArch(),
84-
native_optimizations: bool = False,
85-
):
86-
self.cc, self.cppflags, self.cflags, self.ldflags, self.library_paths = cc, cppflags, cflags, ldflags, library_paths
87-
self.ldpaths = ldpaths or []
88-
self.ccver = ccver
89-
self.vcs_rev = vcs_rev
90-
self.binary_arch = binary_arch
91-
self.native_optimizations = native_optimizations
92-
self._cc_version_string = ''
93-
self._compiler_type: Optional[CompilerType] = None
94-
95-
@property
96-
def cc_version_string(self) -> str:
97-
if not self._cc_version_string:
98-
self._cc_version_string = subprocess.check_output(self.cc + ['--version']).decode()
99-
return self._cc_version_string
100-
101-
@property
102-
def compiler_type(self) -> CompilerType:
103-
if self._compiler_type is None:
104-
raw = self.cc_version_string
105-
if 'Free Software Foundation' in raw:
106-
self._compiler_type = CompilerType.gcc
107-
elif 'clang' in raw.lower().split():
108-
self._compiler_type = CompilerType.clang
109-
else:
110-
self._compiler_type = CompilerType.unknown
111-
return self._compiler_type
112-
113-
def copy(self) -> 'Env':
114-
ans = Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), dict(self.library_paths), list(self.ldpaths), self.ccver)
115-
ans.all_headers = list(self.all_headers)
116-
ans._cc_version_string = self._cc_version_string
117-
ans.sources = list(self.sources)
118-
ans.wayland_packagedir = self.wayland_packagedir
119-
ans.wayland_scanner = self.wayland_scanner
120-
ans.wayland_scanner_code = self.wayland_scanner_code
121-
ans.wayland_protocols = self.wayland_protocols
122-
ans.vcs_rev = self.vcs_rev
123-
ans.binary_arch = self.binary_arch
124-
ans.native_optimizations = self.native_optimizations
125-
ans.primary_version = self.primary_version
126-
ans.secondary_version = self.secondary_version
127-
ans.xt_version = self.xt_version
128-
ans.has_copy_file_range = self.has_copy_file_range
129-
return ans
130-
131-
132-
def wayland_protocol_file_name(base: str, ext: str = 'c') -> str:
133-
base = os.path.basename(base).rpartition('.')[0]
134-
return f'wayland-{base}-client-protocol.{ext}'
135-
136-
137-
def init_env(
138-
env: Env,
139-
pkg_config: Callable[..., List[str]],
140-
pkg_version: Callable[[str], Tuple[int, int]],
141-
at_least_version: Callable[..., None],
142-
test_compile: Callable[..., Any],
143-
module: str = 'x11'
144-
) -> Env:
145-
ans = env.copy()
146-
ans.cflags.append('-fPIC')
147-
ans.cppflags.append(f'-D_GLFW_{module.upper()}')
148-
ans.cppflags.append('-D_GLFW_BUILD_DLL')
149-
150-
with open(os.path.join(base, 'source-info.json')) as f:
151-
sinfo = json.load(f)
152-
module_sources = list(sinfo[module]['sources'])
153-
if module in ('x11', 'wayland'):
154-
remove = 'null_joystick.c' if is_linux else 'linux_joystick.c'
155-
module_sources.remove(remove)
156-
157-
ans.sources = sinfo['common']['sources'] + module_sources
158-
ans.all_headers = [x for x in os.listdir(base) if x.endswith('.h')]
159-
160-
if module in ('x11', 'wayland'):
161-
ans.cflags.append('-pthread')
162-
ans.ldpaths.extend('-pthread -lm'.split())
163-
if not is_openbsd:
164-
ans.ldpaths.extend('-lrt -ldl'.split())
165-
major, minor = pkg_version('xkbcommon')
166-
if (major, minor) < (0, 5):
167-
raise SystemExit('libxkbcommon >= 0.5 required')
168-
if major < 1:
169-
ans.cflags.append('-DXKB_HAS_NO_UTF32')
170-
171-
if module == 'x11':
172-
for dep in 'x11 xrandr xinerama xcursor xkbcommon xkbcommon-x11 x11-xcb dbus-1'.split():
173-
ans.cflags.extend(pkg_config(dep, '--cflags-only-I'))
174-
ans.ldpaths.extend(pkg_config(dep, '--libs'))
175-
176-
elif module == 'cocoa':
177-
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
178-
for f_ in 'Cocoa IOKit CoreFoundation CoreVideo QuartzCore UniformTypeIdentifiers'.split():
179-
ans.ldpaths.extend(('-framework', f_))
180-
181-
elif module == 'wayland':
182-
at_least_version('wayland-protocols', *sinfo['wayland_protocols'])
183-
ans.wayland_packagedir = os.path.abspath(pkg_config('wayland-protocols', '--variable=pkgdatadir')[0])
184-
ans.wayland_scanner = os.path.abspath(pkg_config('wayland-scanner', '--variable=wayland_scanner')[0])
185-
scanner_version = tuple(map(int, pkg_config('wayland-scanner', '--modversion')[0].strip().split('.')))
186-
ans.wayland_scanner_code = 'private-code' if scanner_version >= (1, 14, 91) else 'code'
187-
ans.wayland_protocols = tuple(sinfo[module]['protocols'])
188-
for p in ans.wayland_protocols:
189-
ans.sources.append(wayland_protocol_file_name(p))
190-
ans.all_headers.append(wayland_protocol_file_name(p, 'h'))
191-
for dep in 'wayland-client wayland-cursor xkbcommon dbus-1'.split():
192-
ans.cflags.extend(pkg_config(dep, '--cflags-only-I'))
193-
ans.ldpaths.extend(pkg_config(dep, '--libs'))
194-
has_memfd_create = test_compile(env.cc, '-Werror', src='''#define _GNU_SOURCE
195-
#include <unistd.h>
196-
#include <sys/syscall.h>
197-
int main(void) {
198-
return syscall(__NR_memfd_create, "test", 0);
199-
}''')
200-
if has_memfd_create:
201-
ans.cppflags.append('-DHAS_MEMFD_CREATE')
202-
203-
return ans
204-
205-
206-
def build_wayland_protocols(
207-
env: Env,
208-
parallel_run: Callable[[List[Command]], None],
209-
emphasis: Callable[[str], str],
210-
newer: Callable[..., bool],
211-
dest_dir: str
212-
) -> None:
213-
items = []
214-
for protocol in env.wayland_protocols:
215-
if '/' in protocol:
216-
src = os.path.join(env.wayland_packagedir, protocol)
217-
if not os.path.exists(src):
218-
raise SystemExit(f'The wayland-protocols package on your system is missing the {protocol} protocol definition file')
219-
else:
220-
src = os.path.join(os.path.dirname(os.path.abspath(__file__)), protocol)
221-
if not os.path.exists(src):
222-
raise SystemExit(f'The local Wayland protocol {protocol} is missing from kitty sources')
223-
for ext in 'hc':
224-
dest = wayland_protocol_file_name(src, ext)
225-
dest = os.path.join(dest_dir, dest)
226-
if newer(dest, src):
227-
q = 'client-header' if ext == 'h' else env.wayland_scanner_code
228-
items.append(Command(
229-
f'Generating {emphasis(os.path.basename(dest))} ...',
230-
[env.wayland_scanner, q, src, dest], lambda: True))
231-
if items:
232-
parallel_run(items)
23312

23413

23514
class Arg:

kitty/shaders/slang.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ def create_specialisations(sources: dict[str, SlangFile], build_dir: str, dest_d
404404

405405

406406
def compile_builtin_shaders(build_dir: str, dest_dir: str, parallel_run: ParallelRun) -> None:
407+
os.makedirs(build_dir, exist_ok=True)
408+
os.makedirs(dest_dir, exist_ok=True)
407409
src_dir = os.path.abspath('kitty/shaders')
408410
source_tree = get_ordered_sources_in_tree(src_dir)
409411
# First ensure all IR is generated

0 commit comments

Comments
 (0)