Skip to content
Download

DocsPage 06 of 14

Development Guide

Qt/CMake/Cargo local setup, checks, CI, and release packaging

GitHubOpen in GitHub6 sections
On this page6 sections

OpenNOW's active desktop client lives in opennow-qt/ in the OpenCloudGaming/OpenNOW repository, with Rust services under native/. This site is the canonical public documentation for that codebase. You do not need Node.js or npm to build or run the desktop app.

Prerequisites#

  • Qt 6.8+ with Quick, Quick Controls 2, Multimedia, Network, Test, and ShaderTools
  • CMake 3.24+ and a C++20 toolchain
  • SDL3
  • Rust/Cargo
  • Platform media dependencies for the native streamer
  • Linux: pkg-config, libwayland-dev, and wayland-protocols (required even for X11 builds), the libva, libva-drm, and libdrm development packages, and libclang; ARM64 Linux also needs the libudev development package
  • A GeForce NOW account for end-to-end session testing
bash
git clone --branch main https://github.com/OpenCloudGaming/OpenNOW.git
cd OpenNOW
cmake -S opennow-qt -B build/opennow-qt -DCMAKE_BUILD_TYPE=Debug
cmake --build build/opennow-qt
ctest --test-dir build/opennow-qt --output-on-failure

main is the stable line: releases are published from it, and it also carries fixes merged since the newest release. Use dev instead of main for ongoing development. Point CMAKE_PREFIX_PATH at Qt and SDL3 when they are not already discoverable. The development executable is normally build/opennow-qt/OpenNOW.exe on Windows and build/opennow-qt/opennow-qt on Linux.

Common commands#

CommandPurpose
cmake -S opennow-qt -B build/opennow-qt …Configure the Qt app, core, and streamer FFI
cmake --build build/opennow-qtBuild the desktop app
ctest --test-dir build/opennow-qt --output-on-failureRun Qt/C++ and related tests
cmake --build build/opennow-qt --target opennow-ci-unit-tests then ctest --test-dir build/opennow-qt -L ci-unit --output-on-failureRun only the headless ci-unit Qt tests that CI runs
cmake --build build/opennow-qt --config Release --target packageCreate CPack packages: ZIP on Windows, DMG and ZIP on macOS, DEB on Linux

The Qt CMake build compiles opennow-streamer-ffi with Cargo's release profile and links the resulting shared library into the app, including in Debug builds. On Linux it enables the bundled FFmpeg software decoder and native H.264 VA-API. There is no separate packaged streamer executable.

A direct developer CPack DEB uses the distribution's Qt and SDL3, so it needs Qt 6.8+ and SDL3 on the target system. Release DEBs instead bundle the AppImage runtime under /opt/opennow.

Repository JavaScript under scripts/ is for tools such as localization checks (npm run locales:check). It is not required to build or launch the desktop client.

Source layout#

text
opennow-qt/                  Qt Quick desktop app, C++ integration, and Qt tests
native/opennow-core/         Rust accounts, settings, catalog, and session services
native/opennow-streamer/     Native NVST transport, media, input, and Qt FFI
locales/                     English source and Crowdin-managed translations
docs/                        Architecture, protocols, acceptance, and release guides
scripts/                     Repository-only tooling (for example localization)
playnite/                    Playnite library integration (C#)
.github/                     CI workflows and contributor guidance

Localization#

UI strings live in locales/en.json as the English source file. Crowdin manages the other locale files. For translations, edit only locales/en.json. See the upstream contributing guide for the current locale workflow.

Native streamer builds#

For the Qt app, the streamer is built and linked through CMake/Cargo as an in-process library. The standalone opennow-streamer binary remains a development host and is not evidence for the packaged Qt presentation path.

See Native Streamer for runtime behavior, GPU integration, and diagnostics.

CI and releases#

Workflows in .github/workflows/ on main:

Workflow (file)TriggerPurpose
qt-ci (qt-ci.yml)Pull requests and pushes to dev or main that touch the app, native code, locales, or workflows; manual dispatchLint, packaging-contract and localization checks, then native tests on linux-x64, windows-x64, macos-arm64, and macos-x64. A manual run also builds all six package platforms. With publish_nightly=true it publishes a nightly prerelease with signed update manifests
Qt checks (qt-checks.yml) and Qt unsigned build (qt-build.yml)Called by other workflowsShared checks and package builds
Qt Flatpak build (qt-flatpak.yml)ManualBuilds and checks an x86_64 Flatpak bundle and uploads it as an artifact. It creates no release
qt-release-candidate (qt-release-candidate.yml)Manual, with an exact 40-character commitBuilds a signed production candidate: macOS Developer ID signing and notarization, optional Windows Authenticode, and isolated Ed25519 update signing. It does not publish a release
Qt update-signed stable release (qt-stable-release.yml)Manual, on mainPromotes a successful qt-release-candidate run for the exact main commit to a public Latest release without rebuilding
CodeQL Advanced (codeql.yml)Pushes, pull requests, weekly scheduleCode scanning

Public Qt packages use names like OpenNOW-Qt-<version>-…. main now carries v1.0.3; each stable release is published from main through qt-release-candidate → qt-stable-release. Nightlies (vX.Y.Z-nightly.<run>.<attempt>, currently v1.0.4-nightly.*) are published from dev by a manual qt-ci run with publish_nightly=true. They are prereleases and never replace the Latest release. Windows packages now ship as -setup.exe and portable .zip only: the .msi installer is no longer built, so v1.0.3 is the last release that published one.

The v1.0.3 release contains Windows x64/ARM64 -setup.exe, .msi, and .zip; Linux x64/ARM64 .AppImage, .deb, and .flatpak; macOS Apple Silicon .dmg and .zip; two .AppImage.zsync sidecars; one <asset>.manifest.json per asset; RELEASE-INFO.json; and SHA256SUMS. Nightlies publish the macOS DMGs only, one for Apple Silicon and one for Intel; their macOS ZIPs are CI validation artifacts.

Current package matrix:

TargetQt packaging behaviorArtifacts
Windows x64 / ARM64Qt package embeds the streamer library beside OpenNOW and opennow-core. setup.exe installs per user into %LOCALAPPDATA%\OpenNOW; the MSI and portable ZIP carry the same binaries. Not Authenticode-signed, so SmartScreen can warnOpenNOW-Qt-<version>-Windows-<arch>-setup.exe, .msi, portable .zip
Linux x64 / ARM64AppImage recommended, with a .zsync sidecar for external delta-update tools. DEBs bundle Qt, QML plugins, SDL3, and the media runtime under /opt/opennow. The Flatpak (io.github.opencloudgaming.OpenNOW, x86_64) is a local or workflow build only and has no in-app updatesOpenNOW-Qt-<version>-Linux-<arch>.AppImage, .AppImage.zsync, .deb; Flatpak via workflow or local build
macOS Apple SiliconDMG or ZIP installs to Applications on macOS 13 or later; Intel Macs are not included. Nightlies publish the DMG onlyOpenNOW-Qt-<version>-Darwin-arm64.dmg, .zip

The Linux row above covers the AppImage and DEB. GitHub Releases also include OpenNOW-Qt-<version>-Linux-x64.flatpak and OpenNOW-Qt-<version>-Linux-arm64.flatpak. They are not on Flathub. The manual Qt Flatpak build workflow still uploads an artifact and does not publish a release by itself.

Manual publication details live in the upstream nightly guide, release-candidate guide, and stable release guide. Prefer those docs over historical Electron packaging notes.