prism-sys 0.1.3

Raw FFI bindings to the prism speech library
Documentation
# SPDX-License-Identifier: MPL-2.0
{
  description = "The the Platform-agnostic Reader Interface for Speech and Messages";
  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixos-26.05/nixexprs.tar.xz";
    godot-cpp = {
      url = "git+https://github.com/godotengine/godot-cpp?ref=4.5";
      flake = false;
    };
  };
  outputs =
    {
      self,
      nixpkgs,
      godot-cpp,
    }:
    let
      systems = [
        "x86_64-linux"
        "aarch64-linux"
      ];
      forAllSystems =
        f:
        nixpkgs.lib.genAttrs systems (
          system:
          f {
            inherit system;
            pkgs = nixpkgs.legacyPackages.${system};
          }
        );
      inherit (nixpkgs) lib;
      llvmFor = pkgs: pkgs.llvmPackages_22;
      speechProviderFor =
        pkgs:
        pkgs.stdenv.mkDerivation {
          pname = "libspeechprovider";
          version = "1.0.3";
          src = pkgs.fetchFromGitHub {
            owner = "project-spiel";
            repo = "libspeechprovider";
            rev = "07e6a2a4f1df7149966588e57daf43336eba28ed";
            hash = "sha256-OUIK2PWnAh6zEqYV8a/YJw8L0bsewA5wnD3rEbIFZ3U=";
          };
          nativeBuildInputs = with pkgs; [
            meson
            ninja
            pkg-config
            glib
            gobject-introspection
            python3
          ];
          buildInputs = with pkgs; [ glib ];
          mesonFlags = [
            "-Dtests=false"
            "-Ddocs=false"
            "-Drust-bindings=false"
          ];
          meta.description = "Speech provider D-Bus interface library for Spiel";
        };
      spielFor =
        pkgs:
        pkgs.stdenv.mkDerivation {
          pname = "libspiel";
          version = "1.0.5-unstable-2026-01-09";
          src = pkgs.fetchFromGitHub {
            owner = "project-spiel";
            repo = "libspiel";
            rev = "adceb561f10cd0db335503b95273177b1a2b73b5";
            hash = "sha256-YiOz3irXgHeKcZmFuIiUmSVXTcH1HHHJ7plNcf8RMck=";
          };
          nativeBuildInputs = with pkgs; [
            meson
            ninja
            pkg-config
            glib
            gobject-introspection
            python3
          ];
          buildInputs = with pkgs; [
            glib
            gst_all_1.gstreamer
            gst_all_1.gst-plugins-base
            (speechProviderFor pkgs)
          ];
          mesonFlags = [
            "-Dtests=false"
            "-Ddocs=false"
            "-Dutils=false"
          ];
          meta.description = "Client library for the Spiel speech framework";
        };
      libsFor =
        pkgs: with pkgs; [
          speechd
          glib
          glibmm_2_68
          libsigcxx30
          dbus
          gst_all_1.gstreamer
          gst_all_1.gst-plugins-base
          fmt
          simdutf
          (spielFor pkgs)
        ];
      toolsFor =
        pkgs: with pkgs; [
          cmake
          ninja
          pkg-config
          meson
          git
          zip
          gobject-introspection
          gi-docgen
          (python3.withPackages (
            ps: with ps; [
              tappy
              python-dbusmock
            ]
          ))
        ];
      wineFor = pkgs: [ pkgs.wine64 ];
      prismVersion =
        let
          lines = builtins.filter builtins.isString (
            builtins.split "\n" (builtins.readFile ./CMakeLists.txt)
          );
          hits = builtins.concatMap (
            l:
            let
              m = builtins.match "[[:space:]]*VERSION[[:space:]]+([0-9]+\\.[0-9]+\\.[0-9]+)[[:space:]]*" l;
            in
            if m == null then [ ] else m
          ) lines;
        in
        if hits == [ ] then
          throw "flake.nix: no 'VERSION x.y.z' line found in CMakeLists.txt"
        else
          builtins.head hits;
      mkShell =
        {
          pkgs,
          withWinelibs ? false,
          withLint ? false,
          withEmscripten ? false,
        }:
        pkgs.mkShell {
          name =
            "prism"
            + lib.optionalString withWinelibs "-winelibs"
            + lib.optionalString withEmscripten "-emscripten"
            + lib.optionalString withLint "-lint";
          PRISM_GODOT_CPP_SOURCE_DIR = "${godot-cpp}";
          buildInputs = libsFor pkgs;
          nativeBuildInputs =
            toolsFor pkgs
            ++ lib.optionals withWinelibs (wineFor pkgs)
            ++ lib.optionals withEmscripten [ pkgs.emscripten ]
            ++ lib.optionals withLint [
              (llvmFor pkgs).clang-tools
              (llvmFor pkgs).clang
            ];
          shellHook = lib.optionalString withEmscripten ''
            
                                    export EM_CACHE="''${EM_CACHE:-$PWD/.em_cache}"
                                    if [ ! -d "$EM_CACHE" ]; then
                                      mkdir -p "$EM_CACHE"
                                      cp -r --no-preserve=mode,ownership ${pkgs.emscripten}/share/emscripten/cache/. "$EM_CACHE" || true
                                    fi
          '';
        };
      mkPrism =
        {
          pkgs,
          shared ? true,
          buildType ? "Release",
          withWinelibs ? false,
          withGdextension ? false,
          withSpiel ? false,
          provider ? "BUNDLED",
        }:
        pkgs.stdenv.mkDerivation {
          pname = "prism";
          version = prismVersion;
          src = self;
          buildInputs = libsFor pkgs;
          nativeBuildInputs = toolsFor pkgs ++ lib.optionals withWinelibs (wineFor pkgs);

          cmakeFlags = [
            "-GNinja"
            "-DCMAKE_BUILD_TYPE=${buildType}"
            "-DBUILD_SHARED_LIBS=${if shared then "ON" else "OFF"}"
            "-DPRISM_ENABLE_TESTS=OFF"
            "-DPRISM_ENABLE_DEMOS=OFF"
            "-DPRISM_ENABLE_LEGACY_BACKENDS=ON"
            "-DPRISM_ENABLE_SHIMS=ON"
            "-DPRISM_ENABLE_GDEXTENSION=${if withGdextension then "ON" else "OFF"}"
            "-DPRISM_BUILD_WINELIBS=${if withWinelibs then "ON" else "OFF"}"
            "-DPRISM_ENABLE_SPIEL_BACKEND=${if withSpiel then "ON" else "OFF"}"
            "-DPRISM_FMT_PROVIDER=${provider}"
            "-DPRISM_SIMDUTF_PROVIDER=${provider}"
            "-DPRISM_CONCURRENTQUEUE_PROVIDER=BUNDLED"
          ]
          ++ lib.optionals withGdextension [ "-DPRISM_GODOT_CPP_SOURCE_DIR=${godot-cpp}" ];
          meta = {
            description = "Cross-platform screen reader and TTS abstraction library";
            license = lib.licenses.mpl20;
            platforms = systems;
          };
        };
    in
    {
      devShells = forAllSystems (
        { pkgs, ... }: {
          default = mkShell { inherit pkgs; };
          winelibs = mkShell {
            inherit pkgs;
            withWinelibs = true;
          };
          lint = mkShell {
            inherit pkgs;
            withLint = true;
          };
          winelibs-lint = mkShell {
            inherit pkgs;
            withWinelibs = true;
            withLint = true;
          };
          emscripten = mkShell {
            inherit pkgs;
            withEmscripten = true;
          };
          emscripten-lint = mkShell {
            inherit pkgs;
            withEmscripten = true;
            withLint = true;
          };
        }
      );
      packages = forAllSystems (
        { pkgs, ... }: {
          default = mkPrism { inherit pkgs; };
          prism-static = mkPrism {
            inherit pkgs;
            shared = false;
          };
          prism-debug = mkPrism {
            inherit pkgs;
            buildType = "Debug";
          };
          prism-system = mkPrism {
            inherit pkgs;
            provider = "SYSTEM";
          };
          gdextension = mkPrism {
            inherit pkgs;
            withGdextension = true;
          };
          libspiel = spielFor pkgs;
          libspeechprovider = speechProviderFor pkgs;
        }
      );
      checks = forAllSystems (
        { pkgs, system }:
        self.packages.${system}
        // {
          shell-default = self.devShells.${system}.default;
          shell-winelibs = self.devShells.${system}.winelibs;
          shell-lint = self.devShells.${system}.lint;
          shell-winelibs-lint = self.devShells.${system}.winelibs-lint;
          shell-emscripten = self.devShells.${system}.emscripten;
          shell-emscripten-lint = self.devShells.${system}.emscripten-lint;
        }
      );
    };
}