diff --git a/glfw/glfw.py b/glfw/glfw.py index 05074000248..1eecdedddf3 100755 --- a/glfw/glfw.py +++ b/glfw/glfw.py @@ -6,7 +6,7 @@ import os import re import sys -from typing import Callable, List, Optional, Tuple +from typing import Callable, Dict, List, Optional, Tuple _plat = sys.platform.lower() is_linux = 'linux' in _plat @@ -19,6 +19,7 @@ class Env: cppflags: List[str] = [] cflags: List[str] = [] ldflags: List[str] = [] + library_paths: Dict[str, List[str]] = {} ldpaths: List[str] = [] ccver: Tuple[int, int] @@ -32,13 +33,13 @@ class Env: def __init__( self, cc: str = '', cppflags: List[str] = [], cflags: List[str] = [], ldflags: List[str] = [], - ldpaths: Optional[List[str]] = None, ccver: Tuple[int, int] = (0, 0) + library_paths: Dict[str, List[str]] = {}, ldpaths: Optional[List[str]] = None, ccver: Tuple[int, int] = (0, 0) ): - self.cc, self.cppflags, self.cflags, self.ldflags, self.ldpaths = cc, cppflags, cflags, ldflags, [] if ldpaths is None else ldpaths - self.ccver = ccver + self.cc, self.cppflags, self.cflags, self.ldflags, self.library_paths = cc, cppflags, cflags, ldflags, library_paths + self.ldpaths, self.ccver = [] if ldpaths is None else ldpaths, ccver def copy(self) -> 'Env': - ans = Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), list(self.ldpaths), self.ccver) + ans = Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), dict(self.library_paths), list(self.ldpaths), self.ccver) ans.all_headers = list(self.all_headers) ans.sources = list(self.sources) ans.wayland_packagedir = self.wayland_packagedir diff --git a/kitty/desktop.c b/kitty/desktop.c index bd8f872e31d..1417e0815ee 100644 --- a/kitty/desktop.c +++ b/kitty/desktop.c @@ -34,10 +34,14 @@ init_x11_startup_notification(PyObject UNUSED *self, PyObject *args) { done = true; const char* libnames[] = { +#if defined(_KITTY_STARTUP_NOTIFICATION_LIBRARY) + _KITTY_STARTUP_NOTIFICATION_LIBRARY, +#else "libstartup-notification-1.so", // some installs are missing the .so symlink, so try the full name "libstartup-notification-1.so.0", "libstartup-notification-1.so.0.0.0", +#endif NULL }; for (int i = 0; libnames[i]; i++) { @@ -113,10 +117,14 @@ load_libcanberra(void) { if (done) return; done = true; const char* libnames[] = { +#if defined(_KITTY_CANBERRA_LIBRARY) + _KITTY_CANBERRA_LIBRARY, +#else "libcanberra.so", // some installs are missing the .so symlink, so try the full name "libcanberra.so.0", "libcanberra.so.0.2.5", +#endif NULL }; for (int i = 0; libnames[i]; i++) { diff --git a/setup.py b/setup.py index d1a52505fe5..97aaa347d88 100755 --- a/setup.py +++ b/setup.py @@ -63,6 +63,9 @@ class Options(argparse.Namespace): libdir_name: str = 'lib' extra_logging: List[str] = [] update_check_interval: float = 24 + egl_library: Optional[str] = None + startup_notification_library: Optional[str] = None + canberra_library: Optional[str] = None class CompileKey(NamedTuple): @@ -231,6 +234,9 @@ def init_env( sanitize: bool = False, native_optimizations: bool = True, profile: bool = False, + egl_library: Optional[str] = None, + startup_notification_library: Optional[str] = None, + canberra_library: Optional[str] = None, extra_logging: Iterable[str] = () ) -> Env: native_optimizations = native_optimizations and not sanitize and not debug @@ -289,7 +295,26 @@ def init_env( cppflags.append('-DWITH_PROFILER') cflags.append('-g3') ldflags.append('-lprofiler') - return Env(cc, cppflags, cflags, ldflags, ccver=ccver) + + library_paths = {} + + if egl_library is not None: + assert('"' not in egl_library) + library_paths['glfw/egl_context.c'] = ['_GLFW_EGL_LIBRARY="' + egl_library + '"'] + + desktop_libs = [] + if startup_notification_library is not None: + assert('"' not in startup_notification_library) + desktop_libs = ['_KITTY_STARTUP_NOTIFICATION_LIBRARY="' + startup_notification_library + '"'] + + if canberra_library is not None: + assert('"' not in canberra_library) + desktop_libs += ['_KITTY_CANBERRA_LIBRARY="' + canberra_library + '"'] + + if desktop_libs != []: + library_paths['kitty/desktop.c'] = desktop_libs + + return Env(cc, cppflags, cflags, ldflags, library_paths, ccver=ccver) def kitty_env() -> Env: @@ -349,7 +374,7 @@ def run_tool(cmd: Union[str, List[str]], desc: Optional[str] = None) -> None: raise SystemExit(ret) -def get_vcs_rev_defines(env: Env) -> List[str]: +def get_vcs_rev_defines(env: Env, src: str) -> List[str]: ans = [] if os.path.exists('.git'): try: @@ -368,7 +393,16 @@ def get_vcs_rev_defines(env: Env) -> List[str]: return ans -SPECIAL_SOURCES: Dict[str, Tuple[str, Union[List[str], Callable[[Env], Union[List[str], Iterator[str]]]]]] = { +def get_library_defines(env: Env, src: str) -> Optional[List[str]]: + try: + return env.library_paths[src] + except KeyError: + return None + + +SPECIAL_SOURCES: Dict[str, Tuple[str, Union[List[str], Callable[[Env, str], Union[Optional[List[str]], Iterator[str]]]]]] = { + 'glfw/egl_context.c': ('glfw/egl_context.c', get_library_defines), + 'kitty/desktop.c': ('kitty/desktop.c', get_library_defines), 'kitty/parser_dump.c': ('kitty/parser.c', ['DUMP_COMMANDS']), 'kitty/data-types.c': ('kitty/data-types.c', get_vcs_rev_defines), } @@ -556,8 +590,9 @@ def compile_c_extension( is_special = src in SPECIAL_SOURCES if is_special: src, defines_ = SPECIAL_SOURCES[src] - defines = defines_(kenv) if callable(defines_) else defines_ - cppflags.extend(map(define, defines)) + defines = defines_(kenv, src) if callable(defines_) else defines_ + if defines is not None: + cppflags.extend(map(define, defines)) cmd = [kenv.cc, '-MMD'] + cppflags + kenv.cflags cmd += ['-c', src] + ['-o', dest] @@ -662,7 +697,11 @@ def files( def build(args: Options, native_optimizations: bool = True) -> None: global env - env = init_env(args.debug, args.sanitize, native_optimizations, args.profile, args.extra_logging) + env = init_env( + args.debug, args.sanitize, native_optimizations, args.profile, + args.egl_library, args.startup_notification_library, args.canberra_library, + args.extra_logging + ) sources, headers = find_c_files() compile_c_extension( kitty_env(), 'kitty/fast_data_types', args.compilation_database, sources, headers @@ -1063,6 +1102,27 @@ def option_parser() -> argparse.ArgumentParser: # {{{ help='When building a package, the default value for the update_check_interval setting will' ' be set to this number. Use zero to disable update checking.' ) + p.add_argument( + '--egl-library', + type=str, + default=Options.egl_library, + help='The filename argument passed to dlopen for libEGL.' + ' This can be used to change the name of the loaded library or specify an absolute path.' + ) + p.add_argument( + '--startup-notification-library', + type=str, + default=Options.startup_notification_library, + help='The filename argument passed to dlopen for libstartup-notification-1.' + ' This can be used to change the name of the loaded library or specify an absolute path.' + ) + p.add_argument( + '--canberra-library', + type=str, + default=Options.canberra_library, + help='The filename argument passed to dlopen for libcanberra.' + ' This can be used to change the name of the loaded library or specify an absolute path.' + ) return p # }}}