Skip to content

Navigation Menu

Sign in
Sign up

Building

Mina Maher edited this page Apr 1, 2026 · 7 revisions

πŸ”¨ Building

πŸ“‹ Prerequisites

Dependency Version Notes
πŸ”§ CMake >= 3.22 Build system
⚑ Ninja any Recommended generator (make works too)
πŸ’» C++ compiler C++20 GCC 12+ or Clang 15+
🎨 Qt 6 >= 6.4 Core, Quick, Svg, DBus, Widgets, Concurrent, Test, QuickTest
πŸ”Œ libudev any Device discovery via udev/hidraw
πŸ§ͺ Google Test any Test framework (Ubuntu ships source only β€” needs manual build)
πŸ“¦ pkg-config any Finds libudev

🎨 Qt 6 Modules

The project uses these Qt 6 modules (from CMakeLists.txt):

find_package(Qt6 REQUIRED COMPONENTS Core Quick Svg DBus Widgets Concurrent Test QuickTest)

Plus these QML modules at runtime:

  • qml6-module-qtquick, qml6-module-qtquick-controls, qml6-module-qtquick-layouts
  • qml6-module-qtquick-window, qml6-module-qtquick-templates
  • qml6-module-qtquick-dialogs, qml6-module-qt5compat-graphicaleffects
  • qml6-module-qttest (for QML tests)

🐧 Ubuntu 24.04

sudo apt-get install -y \
 build-essential cmake ninja-build pkg-config \
 qt6-base-dev qt6-declarative-dev qt6-svg-dev \
 qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools \
 qml6-module-qtquick qml6-module-qtquick-controls \
 qml6-module-qtquick-layouts qml6-module-qtquick-window \
 qml6-module-qtquick-templates qml6-module-qtqml-workerscript \
 qml6-module-qtquick-dialogs qml6-module-qt5compat-graphicaleffects \
 qt6-qpa-plugins libqt6opengl6-dev libqt6svg6-dev \
 libqt6dbus6 libqt6widgets6 libxkbcommon-dev \
 qml6-module-qttest libudev-dev libgtest-dev
# Build and install GTest (Ubuntu ships source only)
cd /usr/src/googletest && sudo cmake -B build && sudo cmake --build build && sudo cmake --install build

πŸ”οΈ Arch Linux

sudo pacman -S cmake ninja qt6-base qt6-declarative qt6-svg qt6-tools \
 qt6-5compat gtest libudev0-shim pkgconf

πŸš€ Build from Source

git clone https://github.com/logitune/logitune.git
cd logitune
# Configure + build
make build
# Run with debug logging
make run

The make build target runs:

cmake -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -Wno-dev
cmake --build build -j$(nproc)

🎯 Build Commands

The Makefile provides these targets:

Command Description
make build πŸ”¨ Build the project (Debug mode)
make run ▢️ Build and run the app with --debug (host only)
make test πŸ§ͺ Run C++ unit/integration tests
make test-qml 🎨 Run QML component tests
make test-tray πŸ”” Run tray manager tests
make test-all βœ… Run all test tiers
make flatpak-setup πŸ“€ Install Flatpak SDK (first time, ~2GB)
make flatpak πŸ“¦ Build and install Flatpak
make release 🏷️ Version bump, tag, Flatpak, GitHub release
make setup-hooks πŸͺ Install git pre-push hook
make clean 🧹 Remove build artifacts
make help ❓ Show all targets

βš™οΈ CMake Options

Option Default Description
BUILD_TESTING ON Build test binaries
BUILD_HW_TESTING OFF Build hardware integration tests (requires connected device)
CMAKE_BUILD_TYPE Debug Debug or Release

πŸ“ Project Structure

logitune/
β”œβ”€β”€ CMakeLists.txt # Root CMake β€” project, Qt find, subdirs
β”œβ”€β”€ Makefile # Developer convenience targets
β”œβ”€β”€ com.logitune.Logitune.yml # Flatpak manifest
β”œβ”€β”€ data/
β”‚ β”œβ”€β”€ 71-logitune.rules # udev rules for hidraw + uinput
β”‚ β”œβ”€β”€ com.logitune.Logitune.desktop
β”‚ β”œβ”€β”€ com.logitune.Logitune.metainfo.xml
β”‚ └── com.logitune.Logitune.svg
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ core/ # Static library: logitune-core
β”‚ β”‚ β”œβ”€β”€ CMakeLists.txt
β”‚ β”‚ β”œβ”€β”€ DeviceManager.cpp/h # Device lifecycle, HID++ orchestration
β”‚ β”‚ β”œβ”€β”€ DeviceRegistry.cpp/h
β”‚ β”‚ β”œβ”€β”€ ProfileEngine.cpp/h # Profile CRUD, app bindings, cache
β”‚ β”‚ β”œβ”€β”€ ActionExecutor.cpp/h
β”‚ β”‚ β”œβ”€β”€ ButtonAction.h
β”‚ β”‚ β”œβ”€β”€ hidpp/ # HID++ protocol layer
β”‚ β”‚ β”‚ β”œβ”€β”€ HidppTypes.h # Report, FeatureId, ErrorCode
β”‚ β”‚ β”‚ β”œβ”€β”€ HidrawDevice.h # Raw hidraw fd wrapper
β”‚ β”‚ β”‚ β”œβ”€β”€ Transport.h # Send/receive with timeout + retry
β”‚ β”‚ β”‚ β”œβ”€β”€ FeatureDispatcher.h # Feature table, call(), callAsync()
β”‚ β”‚ β”‚ β”œβ”€β”€ CommandQueue.h # Paced sequential command sending
β”‚ β”‚ β”‚ └── features/ # Per-feature param builders + parsers
β”‚ β”‚ β”œβ”€β”€ devices/
β”‚ β”‚ β”‚ └── MxMaster3sDescriptor.cpp/h
β”‚ β”‚ β”œβ”€β”€ interfaces/
β”‚ β”‚ β”‚ β”œβ”€β”€ IDevice.h # Device descriptor interface
β”‚ β”‚ β”‚ β”œβ”€β”€ IDesktopIntegration.h
β”‚ β”‚ β”‚ β”œβ”€β”€ IInputInjector.h
β”‚ β”‚ β”‚ └── ITransport.h
β”‚ β”‚ β”œβ”€β”€ desktop/
β”‚ β”‚ β”‚ β”œβ”€β”€ KDeDesktop.cpp/h # KDE/KWin integration
β”‚ β”‚ β”‚ └── GenericDesktop.cpp/h
β”‚ β”‚ β”œβ”€β”€ input/
β”‚ β”‚ β”‚ └── UinputInjector.cpp/h
β”‚ β”‚ └── logging/
β”‚ β”‚ β”œβ”€β”€ LogManager.cpp/h
β”‚ β”‚ └── CrashHandler.cpp/h
β”‚ └── app/ # Static library: logitune-app-lib + executable
β”‚ β”œβ”€β”€ CMakeLists.txt
β”‚ β”œβ”€β”€ main.cpp # Entry point, QML engine, tray
β”‚ β”œβ”€β”€ AppController.cpp/h # Main orchestrator
β”‚ β”œβ”€β”€ TrayManager.cpp/h
β”‚ β”œβ”€β”€ models/
β”‚ β”‚ β”œβ”€β”€ DeviceModel.h # QML-facing device state
β”‚ β”‚ β”œβ”€β”€ ButtonModel.h # QAbstractListModel for buttons
β”‚ β”‚ β”œβ”€β”€ ActionModel.h # Available actions catalog
β”‚ β”‚ └── ProfileModel.h # Profile tabs
β”‚ β”œβ”€β”€ dialogs/
β”‚ β”‚ β”œβ”€β”€ CrashReportDialog.cpp/h
β”‚ β”‚ └── GitHubIssueBuilder.cpp/h
β”‚ └── qml/
β”‚ β”œβ”€β”€ Main.qml
β”‚ β”œβ”€β”€ Theme.qml # Singleton with design tokens
β”‚ β”œβ”€β”€ HomeView.qml
β”‚ β”œβ”€β”€ DeviceView.qml
β”‚ β”œβ”€β”€ pages/ # PointScrollPage, ButtonsPage, EasySwitchPage, SettingsPage
β”‚ β”œβ”€β”€ components/ # SideNav, BatteryChip, DeviceRender, etc.
β”‚ └── assets/ # Device images (PNG)
β”œβ”€β”€ tests/
β”‚ β”œβ”€β”€ CMakeLists.txt
β”‚ β”œβ”€β”€ test_main.cpp # GTest main with QCoreApplication
β”‚ β”œβ”€β”€ helpers/
β”‚ β”‚ β”œβ”€β”€ TestFixtures.h # ProfileFixture, ensureApp()
β”‚ β”‚ └── AppControllerFixture.h # Full integration test fixture
β”‚ β”œβ”€β”€ mocks/
β”‚ β”‚ β”œβ”€β”€ MockDesktop.h/cpp
β”‚ β”‚ β”œβ”€β”€ MockTransport.h/cpp
β”‚ β”‚ β”œβ”€β”€ MockInjector.h/cpp
β”‚ β”‚ └── MockDevice.h
β”‚ β”œβ”€β”€ test_*.cpp # C++ test files
β”‚ β”œβ”€β”€ qml/
β”‚ β”‚ β”œβ”€β”€ tst_*.qml # QML component tests
β”‚ β”‚ └── tst_qml_main.cpp
β”‚ └── hw/
β”‚ β”œβ”€β”€ HardwareFixture.h
β”‚ β”œβ”€β”€ hw_test_main.cpp
β”‚ └── test_hw_*.cpp # Hardware integration tests
β”œβ”€β”€ scripts/
β”‚ β”œβ”€β”€ pre-push # Git hook: run all tests before push
β”‚ └── release.sh
└── .github/workflows/
 β”œβ”€β”€ ci.yml # Build + test on push/PR
 └── release.yml # Flatpak bundle on tag push

πŸ“€ Flatpak Build

πŸ› οΈ First-Time Setup

make flatpak-setup

Note

This installs the Flathub remote and the KDE Platform/SDK 6.10 runtime (~2GB download).

πŸ“¦ Build

On host (builds and installs locally):

make flatpak

In devcontainer (build only β€” no user session):

make flatpak

The Flatpak manifest (com.logitune.Logitune.yml) configures:

Setting Value
πŸ–₯️ Runtime org.kde.Platform 6.10
πŸ”— D-Bus Talks to org.kde.KWin and org.kde.kglobalaccel, owns com.logitune.app
πŸ”Œ Device access --device=all for hidraw
πŸ“ Host filesystem Read-only access to host .desktop files for the app profile picker
πŸ’Ύ Config persistence ~/.config/Logitune and ~/.local/share/Logitune shared between host and sandbox

🐳 Devcontainer / GitHub Codespaces

The repository includes a devcontainer configuration for one-click development in VS Code or GitHub Codespaces.

πŸ“¦ What's Included

The Dockerfile (/.devcontainer/Dockerfile) builds an Ubuntu 24.04 container with:

  • βœ… All build dependencies (Qt 6, CMake, Ninja, GTest, libudev)
  • βœ… Development tools (clangd, gdb, fish shell, bat, eza, ripgrep, fzf)
  • βœ… Flatpak builder
  • βœ… Nerd Font for terminal icons
  • βœ… QT_QPA_PLATFORM=offscreen for headless testing

🧩 VS Code Extensions

The devcontainer auto-installs:

Extension Purpose
llvm-vs-code-extensions.vscode-clangd C++ language server
ms-vscode.cmake-tools CMake integration
theqtcompany.qt / qt-qml / qt-cpp Qt/QML support
vscode-icons-team.vscode-icons File icons

πŸš€ Post-Create

On container creation, postCreateCommand runs:

make setup-hooks
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build -j$(nproc)

Tip

The project is fully built and ready to test immediately after the container starts.

⚠️ Limitations

Warning

The devcontainer runs headless (QT_QPA_PLATFORM=offscreen), so:

  • βœ… All tests run fine (C++, QML, tray)
  • ❌ You cannot run the GUI application visually
  • ❌ No hidraw access (no physical device tests)

πŸ”„ CI Pipeline

The CI workflow (.github/workflows/ci.yml) runs on every push to master and every pull request:

graph LR
 A[Push / PR] --> B[Install Dependencies]
 B --> C[Configure CMake]
 C --> D[Build]
 D --> E[C++ Tests]
 D --> F[Tray Tests]
 D --> G[QML Tests]
 E --> H{All Pass?}
 F --> H
 G --> H
Loading

The release workflow (.github/workflows/release.yml) triggers on version tags (v*):

graph LR
 A[Tag Push v*] --> B[Install Flatpak Builder]
 B --> C[Install KDE SDK 6.10]
 C --> D[flatpak-builder]
 D --> E[Create Bundle]
 E --> F[GitHub Release]
Loading

Note

The release workflow builds a .flatpak bundle and creates a GitHub Release with auto-generated release notes.


Logitune Wiki


🏠 Home

πŸ“š User Guide

πŸ—οΈ Architecture

πŸ”§ Extending

πŸ§ͺ Quality

Clone this wiki locally

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /