Files
obs-localvocal/flatpak/README.md
Florent Poinsaut 0e150fa29c Add Flatpak packaging support (#297)
* Initial plan

* feat: add Flatpak packaging support for obs-localvocal

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>

* fix: add disable-submodules: true to CTranslate2 git source in Flatpak manifest

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>

* fix: explicitly set OPENBLAS_INCLUDE_DIR and OPENBLAS_LIBRARY for CTranslate2 in Flatpak manifest

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>

* fix: correct OPENBLAS_INCLUDE_DIR to include/openblas subdirectory for CTranslate2

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/e3f2f7ef-fbe0-4462-b494-7ec90d19173a

* fix(flatpak): set ACCELERATION env var for obs-localvocal cmake configure

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/be96d349-07f2-4bf2-b6eb-17e6981b2c41

* feat(flatpak): add build.sh to make ACCELERATION configurable at build time

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/1d2428e1-3f26-4138-9bbd-7b1980a798fc

* fix(flatpak/cmake): resolve nvidia build failure - skip OpenCL and use local source

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/de149655-15b1-442a-9a1b-d443ef035fc1

* fix(flatpak/build.sh): replace Python heredoc with pure awk shell substitution

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/8e3820a8-3cb7-41d9-9d3f-87d2fac050c6

* fix(flatpak): pre-populate corrosion source to fix network-blocked sandbox build

cmake/BuildWebVTT.cmake uses FetchContent to clone corrosion-rs/corrosion
at configure time. The Flatpak sandbox blocks network access, causing the
clone to fail with "Could not resolve host: github.com".

Fix: add corrosion v0.5 as a pre-downloaded manifest source (dest: corrosion-src)
so flatpak-builder fetches it before entering the sandbox, and point CMake's
FetchContent at the pre-populated directory via FETCHCONTENT_SOURCE_DIR_CORROSION.

Also quote the ACCELERATION variable comparisons in BuildWhispercpp.cmake
for safer string comparison style.

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/65942026-4cfd-4684-92be-626897d87509

* fix(flatpak): add Rust SDK extension and vendor cargo dependencies for offline build

After the corrosion network-clone fix, the next error was:
  rustc not found in PATH or /root/.cargo/bin

The Flatpak sandbox has no network access, so the Rust toolchain must be
provided via an SDK extension, and all cargo crate dependencies must be
pre-downloaded by flatpak-builder (before the sandbox starts).

Changes:
- flatpak/com.obsproject.Studio.Plugin.LocalVocal.yaml:
  * Add sdk-extensions: org.freedesktop.Sdk.Extension.rust-stable//24.08
    (KDE SDK 6.8 is based on freedesktop SDK 24.08; this provides rustc/cargo
    at /usr/lib/sdk/rust-stable/bin)
  * Add append-path for the Rust bin dir to obs-localvocal build-options
  * Add CARGO_HOME=/run/build/obs-localvocal/cargo to env so cargo reads the
    vendor config and locates the pre-populated crate archives
  * Add inline source creating cargo/config.toml that redirects crates-io to
    the pre-vendored directory (absolute path, avoids network)
  * Reference new cargo-sources.json for the 67 crate archives

- flatpak/cargo-sources.json (new):
  Generated by flatpak-cargo-generator from
  deps/c-webvtt-in-video-stream/Cargo.lock.
  134 entries (67 archives + 67 .cargo-checksum.json inlines).
  The auto-generated cargo/config entry is removed since the manifest
  provides a correct config.toml with an absolute vendor path instead.

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/a70f729f-6724-4ef8-9aab-3a54344fda02

* fix(flatpak): use base-extensions to mount rust-stable at branch 24.08

sdk-extensions always resolves extension branches from the SDK branch (6.8),
so org.freedesktop.Sdk.Extension.rust-stable//24.08 was turned into
org.freedesktop.Sdk.Extension.rust-stable//24.08/x86_64/6.8 - a ref that
does not exist.

Replace sdk-extensions with base/base-version/base-extensions:
  base: org.freedesktop.Sdk
  base-version: "24.08"
  base-extensions:
    - org.freedesktop.Sdk.Extension.rust-stable

base-extensions resolves extension branches from base-version (24.08),
matching the only existing branch of the rust-stable extension.
KDE SDK 6.8 is itself built on org.freedesktop.Sdk//24.08, so using
that runtime as the base is fully compatible.

Local prerequisites:
  flatpak install flathub org.freedesktop.Sdk//24.08
  flatpak install flathub org.freedesktop.Sdk.Extension.rust-stable//24.08

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/a0eabff0-15c4-45be-b38b-0ada230bc17e

* fix(flatpak): install Rust toolchain as a module to avoid SDK branch mismatch

Remove base/base-version/base-extensions (the previous fix that caused
app/org.freedesktop.Sdk/x86_64/24.08 not installed because `base` resolves
refs as apps, not runtimes).

The underlying problem is that sdk-extensions always inherits the SDK branch
(6.8), but org.freedesktop.Sdk.Extension.rust-stable only exists at branch
24.08. There is no standard flatpak-builder mechanism to override the branch
for sdk-extensions.

Add a rust-toolchain module that installs Rust 1.89.0 directly to
/usr/lib/sdk/rust-stable/ using the same source (URL + SHA256) as
org.freedesktop.Sdk.Extension.rust-stable//24.08 on Flathub.

Benefits:
- Keeps sdk: org.kde.Sdk//6.8 (Qt6 headers remain available for ENABLE_QT=ON)
- No change needed to obs-localvocal build-options (append-path and CARGO_HOME
  continue to work as-is)
- Files installed to /usr/ are build-environment-only, NOT exported in the
  final extension package (prefix: /app/plugins/LocalVocal/)
- No manual flatpak install of any extension required before building

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/ecb4889b-352f-44a8-a681-0dc164fc4493

* fix(flatpak): install Rust toolchain under writable /app prefix, not read-only /usr

In a build-extension: true flatpak sandbox, /usr/ is the SDK mount and
is read-only.  The previous iteration used --prefix=/usr/lib/sdk/rust-stable
which caused:

  touch: cannot touch '/usr/lib/sdk/rust-stable/lib/rust-install-probe':
  Read-only file system

Fix by installing to /app/plugins/LocalVocal/rust-toolchain instead, which
is inside the extension's writable overlay.  Three changes:

1. rust-toolchain module: change --prefix to /app/plugins/LocalVocal/rust-toolchain
2. obs-localvocal build-options: update append-path accordingly
3. cleanup: add /rust-toolchain so the ~300 MB toolchain is stripped from
   the final extension package (cleanup runs after all modules are built,
   so rustc/cargo are available during the obs-localvocal build)

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/f844f598-0354-4a77-9ec7-3334d1485cd9

* fix(flatpak): add opencl-headers module and pre-bundle whispercpp prebuilt binary

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/b191ba1a-bad6-47a4-9b34-2fc1a738d919

* fix(flatpak): replace USE_SYSTEM_ONNXRUNTIME with FetchContent pre-bundle

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/23e8f01e-2866-404d-a181-d195b86406cf

* fix(flatpak): bypass ExternalProject git-clone failures for CTranslate2 and SentencePiece

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/eee2c356-902f-405a-b4c6-a976caa6c1bc

* fix(flatpak): fix post-install cpu_features path for builddir:true layout

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/fc306650-14f7-4a09-abc5-a84e083d6cda

* fix(flatpak/patches): fix malformed patch hunk headers — wrong line numbers and new-line count

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/06b4f42a-13b0-4d97-bc72-05737c028b7f

* fix(flatpak): prepend /app/lib to LD_LIBRARY_PATH so uic can find libicui18n.so.77

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/f3efa268-b29a-4ba5-9aea-1e1d816d8933

* fix(flatpak): add cmake-level uic wrapper to robustly fix libicui18n.so.77 error

cmake AutoUIC spawns /app/libexec/qt/uic as a child of ninja via
`cmake -E cmake_autogen`.  LD_LIBRARY_PATH set by flatpak-builder's
prepend-ld-library-path may not propagate reliably through that
subprocess chain.

Add a thin uic-wrapper shell script module that hard-codes /app/lib
into LD_LIBRARY_PATH before exec-ing the real uic binary.  cmake 3.14+
respects CMAKE_AUTOUIC_EXECUTABLE to override uic discovery; point it
at the wrapper so AutoUIC always uses the wrapper regardless of how
flatpak-builder sets up the environment.

Keep prepend-ld-library-path: /app/lib as belt-and-suspenders.
Add /uic-wrapper to cleanup so it is not shipped in the final package.

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/1af4d028-aa0b-4b05-a94d-90c8d636241b

* fix(flatpak): stage ICU 77 libraries at build time so uic-wrapper finds them

Root cause: /app/lib does NOT contain libicui18n.so.77 in the extension
build sandbox (OBS Studio may store ICU elsewhere, or the path is not
in the default dynamic-linker search path). Setting LD_LIBRARY_PATH to
/app/lib therefore never helped.

New approach in the qt-uic-wrapper module:

  1. At module-build time, locate the three ICU 77 .so files by checking
     six common installation directories (fast path) and falling back to
     a depth-limited `find` search.  Fail loudly if any library cannot
     be located so the problem is immediately visible.

  2. Copy the found libraries (dereferencing symlinks with cp -L) into
     ${FLATPAK_DEST}/icu-for-uic/ — a writable path inside our extension
     prefix that is guaranteed to exist when obs-localvocal later builds.

  3. Rewrite the wrapper to use `export LD_LIBRARY_PATH` (not `exec env
     VAR=...`) and point at /app/plugins/LocalVocal/icu-for-uic.

Remove the now-unnecessary prepend-ld-library-path: /app/lib from
obs-localvocal build-options; add /icu-for-uic to cleanup.

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/c0ad4a75-639b-46db-a6fe-97f8ca13bc67

* fix(flatpak): use SDK's uic when available; ICU shim uses any version as fallback

The previous attempt staged libicui18n.so.77 copies but find returned nothing
because the library genuinely does not exist anywhere in the extension build
sandbox. Root cause: OBS Studio's uic requires libicui18n.so.77, but the
extension sandbox only mounts the SDK (/usr), not the OBS app's private ICU.

New strategy in qt-uic-wrapper:

  Step 1 (primary): locate the KDE Platform SDK's own uic binary in /usr.
  The SDK ships Qt 6.8 including uic, linked against the SDK's ICU. It has
  no unsatisfied dependencies. Common paths checked first (fast), then a
  broader find /usr fallback. If found, write a one-line wrapper with no ICU
  setup needed at all.

  Step 2 (fallback, only if no SDK uic exists): use OBS Studio's uic at
  /app/libexec/qt/uic with an ICU shim. Instead of searching only for
  .so.77, search for ANY version of libicuXXX in the SDK (/usr), stage it
  as .so.77, and keep a copy under the original name so intra-ICU DT_NEEDED
  entries (e.g. libicuuc.so.74) also resolve from our staging dir.

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/502a8cf1-54ef-466d-b500-a1642ca1e11f

* fix(flatpak): always set LD_LIBRARY_PATH=/app/lib in uic wrapper; fix ICU .so.77.1 detection

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/ff0038ad-dbc2-4c9b-acff-f995229274e6

* fix(flatpak): use for-loop glob for ICU detection; guard uic path against shell injection

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/ff0038ad-dbc2-4c9b-acff-f995229274e6

* Fix flatpak uic: lazy-stage ICU 77 in wrapper, no /app/lib in LD_LIBRARY_PATH

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/5e50645b-1a3f-4437-9a15-b9666fb90e5d

* flatpak: uic-wrapper searches SDK /usr/lib* paths first for ICU 77

Co-authored-by: FlorentPoinsaut <1256948+FlorentPoinsaut@users.noreply.github.com>
Agent-Logs-Url: https://github.com/FlorentPoinsaut/obs-localvocal/sessions/9665b858-6bf0-4b37-b496-1de0faff41b7

* Fix ICU compatible version + doc

* Use org.freedesktop.Sdk//25.08

* Use local dir for localvocal in flatpak and remove cmake patches

* Get dep with archive in flatpak

* Add DICU_HASH_OVERRIDE

* Fix cmake format

* Fix bis cmake format

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-03-26 18:02:11 +00:00

3.5 KiB

Flatpak Build Configuration - OBS LocalVocal

Flatpak manifest for the OBS LocalVocal plugin using system dependencies where possible to reduce build time.

📁 Files

Flatpak Configuration

File Description
com.obsproject.Studio.Plugin.LocalVocal.yaml ⚙️ Main Flatpak manifest
com.obsproject.Studio.Plugin.LocalVocal.metainfo.xml 📋 AppStream metadata
cargo-sources.json 📦 Vendored Rust dependencies
build.sh 🔨 Build script
patches/ 🩹 Patches for USE_SYSTEM_* CMake options

🎯 Quick Start

Build the plugin

# Using build script
./flatpak/build.sh

# Or manually with flatpak-builder
flatpak-builder --force-clean --repo=repo build \
  flatpak/com.obsproject.Studio.Plugin.LocalVocal.yaml

📊 Key Features

SDK and Dependencies

Component Version Notes
SDK org.freedesktop.Sdk//25.08 Same as OBS Studio
Rust SDK extension (1.94.0) Saves 15-20 min build time
ICU SDK system library Saves 8-10 min build time

Library Versions

All libraries use versions with native CMake 3.x/4.x support:

  • OpenBLAS v0.3.32 (CMake 3.16+)
  • OpenCL-Headers v2025.07.22 (CMake 3.16+)
  • CTranslate2 v4.7.1 (CMake 3.7+)
    • cpu_features v0.10.1 (CMake 3.13+)
    • spdlog v1.17.0 (CMake 3.10+)
  • whisper.cpp v1.8.2
  • SentencePiece v0.2.1

🔍 Technical Details

Build Architecture

com.obsproject.Studio (runtime)
├── org.freedesktop.Sdk//25.08
│   ├── sdk-extensions
│   │   └── rust-stable (1.94.0)
│   └── System libraries
│       └── ICU (system)
└── LocalVocal Extension
    ├── Compiled modules
    │   ├── OpenBLAS
    │   ├── whisper.cpp
    │   ├── CTranslate2
    │   ├── SentencePiece
    │   └── OpenCL-Headers
    └── Prebuilt binaries
        ├── whispercpp-prebuilt
        └── onnxruntime-prebuilt

Applied Patches

Patches in patches/ add CMake options to use system libraries:

  • 0001-BuildCTranslate2-use-system-option.patchUSE_SYSTEM_CTRANSLATE2
  • 0002-BuildSentencepiece-use-system-option.patchUSE_SYSTEM_SENTENCEPIECE

🧪 Testing

Verify build environment

# Check Flatpak configuration
flatpak remotes --show-details
flatpak list --runtime

# Verify SDK extension availability
flatpak search org.freedesktop.Sdk.Extension.rust-stable

Test build with timing

# Full build with timing
time flatpak-builder --force-clean build \
  flatpak/com.obsproject.Studio.Plugin.LocalVocal.yaml

# Partial build (stop at specific module)
flatpak-builder --force-clean --stop-at=obs-localvocal build \
  flatpak/com.obsproject.Studio.Plugin.LocalVocal.yaml

🐛 Troubleshooting

Common Issues

Error Solution
Rust extension not found flatpak install flathub org.freedesktop.Sdk.Extension.rust-stable//25.08
CMake version errors Update library versions in manifest (already done)
UIC wrapper fails Check Qt installation in SDK with flatpak-builder --run ... which uic

Debug build

# Verbose build
flatpak-builder -v --force-clean build manifest.yaml

# Debug specific module
flatpak-builder --force-clean --stop-at=MODULE build manifest.yaml
flatpak-builder --run build manifest.yaml bash

📜 License

See the LICENSE file in the project root.


Last updated: March 24, 2026