Skip to the content.

Build Information

Details supplementing the quick-start build steps in README.md.

Qt modules

core gui widgets printsupport serialport network xml concurrent opengl bluetooth (see the find_package(Qt6 ...) call in CMakeLists.txt for the authoritative list).

core, gui, widgets, printsupport, network, xml, concurrent, and opengl all ship with Qt’s base “Desktop” component. serialport and bluetooth do not — if you’re installing Qt via the official Qt Online Installer / Maintenance Tool, you must explicitly check them under your Qt version’s Additional Libraries: Qt Serial Port and Qt Bluetooth. Building will fail at the find_package(Qt6 ...) step (missing component) if either is skipped. On Linux distro packages (e.g. apt), these are typically separate packages too — e.g. qt6-serialport-dev and qt6-connectivity-dev (Bluetooth ships under “connectivity”) on Debian/Ubuntu.

Qt Linguist tools (for translations)

Needed to build the app: .qm translation files are compiled from locales/*.ts as part of the normal CMake build (see Translations), not checked in. Install Qt Linguist tools (provides lrelease/lupdate), listed under the installer’s Developer and Designer Tools section, or the qt6-l10n-tools distro package. find_package(Qt6 ... LinguistTools) fails the configure step if it’s missing.

Linux-only

Build options

ANTSCOPEZ_SANITIZE (off by default) builds with AddressSanitizer + UndefinedBehaviorSanitizer – catches out-of-bounds reads/writes and similar live, with an exact file/line/stack, instead of by code audit. Configure a separate build dir (CMAKE_PREFIX_PATH must be passed explicitly, or CMake silently resolves the system’s older bundled Qt6 instead of the one under /opt/Qt):

cmake -B build-debug-asan -DCMAKE_BUILD_TYPE=Debug -DANTSCOPEZ_SANITIZE=ON \
  -DCMAKE_PREFIX_PATH=/opt/Qt/6.11.2/gcc_64
cmake --build build-debug-asan --target AntScopeZ --parallel

Run with ASAN_OPTIONS="suppressions=../asan-suppressions.txt:detect_leaks=0" ./AntScopeZ from build-debug-asan/ – the suppressions file (repo root) covers a real bug in libxcb-cursor (not ours) and turns off LeakSanitizer’s exit-time report, which for a Qt/GTK GUI app is almost entirely third-party-library noise rather than anything actionable.

.clang-tidy (repo root) is also available for static analysis – bugprone-*/clang-analyzer-* checks, no separate install needed since both it and clang-tidy itself already ship with Qt Creator’s bundled clang toolchain. Point it at build-debug/.qtc_clangd/compile_commands.json (already generated for clangd).

Otherwise none currently – ANTSCOPE_NEW_CONNECTION, ANTSCOPE_NEW_ANALYZER, and ANTSCOPE_OLD_TDR used to gate old code paths they replaced; all three were always ON, and the flags and their dead OFF-path code are gone. ANTSCOPE_DEBUG_BLE’s raw TX/RX qDebug() calls are commented out at their call sites in analyzer/ble_analyzer.cpp instead of a build option – uncomment locally when actually debugging Bluetooth.

macOS packaging

build.sh runs a release build (which compiles the translations as part of the normal CMake build – see Translations) and produces a .dmg via macdeployqt:

./build.sh [build-dir]

Build performance

Always build with --parallel (or -j<N>) – cmake --build on the Unix Makefiles generator (the default here; no generator is pinned in CMakePresets.json) defaults to serial, one file at a time, regardless of how many cores are available. Confirmed (2026-08-16): touching a widely-included header and rebuilding took 3m07s plain vs 51s with --parallel 16 on a 16-core box – same build, same everything else. Qt Creator’s own Build button is a separate question – check Projects > Build Settings > Build Steps for a jobs override if it also feels serial.

This is unrelated to translations (.ts/.qm, see Translations below) and unrelated to the .deb self-dependency fix (see “Known issues”) – that fix only touches the CPack packaging step (cpack/fix-deb-self-dependency.sh), never cmake --build, so it structurally can’t affect ordinary build times.

Linux packaging (.deb)

cmake --preset release
cmake --build --preset release --parallel
cd build-release && cpack
../cmake/fix-deb-self-dependency.sh antscopez_<version>_amd64.deb

Produces antscopez_<version>_amd64.deb. The fix-deb-self-dependency.sh step is required, not optional – see “Known issues” below (self-dependency bug). Uses the release preset (Qt 6.11 from /opt/Qt), not system-qt – the CMake install rules bundle that build’s own Qt 6.11 libraries and plugins into /usr/lib/x86_64-linux-gnu/antscopez/ rather than linking whatever Qt6 the target’s distro ships, so the package doesn’t depend on a system Qt install at all (see “Known issues” below for why). The system-qt preset still exists for reproducing/comparing the system-Qt-specific bugs that motivated this.

Qt Creator

Open CMakeLists.txt as the project. The old AntScope.pro has been removed; if Qt Creator still shows the qmake project, delete .qtcreator/AntScope.pro.user and reopen.

Translations

Source .ts files live in locales/. qt_add_translations() in CMakeLists.txt compiles them to .qm at build time (target release_translations, built by default – AntScopeZ depends on it, so a parallel build can’t race ahead of it) and leaves them as loose files (not embedded in the Qt resource system): QTranslator loads them from disk at runtime, checking a per-user override folder before the shared/installed copy (MainWindow::loadLanguage(); see Settings::localDataFolder() / languageDataFolder()). Nothing needs to be checked in or regenerated by hand — building the app regenerates them from whatever’s currently in locales/*.ts.

The View → Language menu is populated by scanning both of those folders for QtLanguage_<code>.qm files (Settings::availableLanguages(), called from MainWindow – Settings itself no longer has a language control of its own, moved to the View menu along with Theme/Bands highlighting/Band Selector), not from a fixed list – adding a language is “add locales/QtLanguage_<code>.ts, rebuild” (or, without a rebuild, drop a .qm compiled elsewhere into either folder). The combo’s display name for each comes from QLocale(code).nativeLanguageName(), since the .ts/.qm format has no display-name field of its own.

To add or update a translation: edit/create locales/QtLanguage_<code>.ts (Qt Linguist, or by hand) and rebuild – or run the update_translations target first (manual/opt-in, since it rewrites .ts file contents) to have lupdate refresh locales/*.ts from the current source strings before translating:

cmake --build --preset debug --target update_translations --parallel

qt_add_translations() passes -no-obsolete to lupdate (see CMakeLists.txt), so a string no longer found in source is dropped outright rather than left behind marked obsolete/vanished – keeps locales/*.ts from accumulating dead entries across releases.

Before assuming a “translated” string just needs updating, check whether its <translation> is actually just a copy of the English <source>lupdate’s same-text heuristic can reuse a match from elsewhere in the file for a new entry, but older entries translated by hand or by an earlier pass can also just be an untouched English copy with no visual indication besides that. Found repeatedly (2026-08-16) across all three languages this way, well after they’d otherwise seemed complete.

Build timestamp

cmake/generate-build-timestamp.cmake, invoked via an add_custom_target() with no tracked OUTPUT (so it reruns on every build, not just on reconfigure), regenerates build-timestamp.h in the build directory with ANTSCOPEZ_BUILD_TIMESTAMP (yymmdd-hhmmss, local time) fresh each time. Shown in Help → About AntScopeZ, below the version. A plain target_compile_definitions() value (like ANTSCOPEZ_VER) would only be recomputed at configure time, going stale across ordinary incremental rebuilds – not useful for actually identifying which build you’re looking at.

Platform notes

Developed on Linuxmint. Using a RigExpert Match RFE (BLE and hidusb):

Known issues