Getting Started with Source and Builds
This topic explains how to get the QGroundControl source code and build it natively, in a container, or in a virtual machine. It also provides information about optional or OS-specific functionality.
Daily Builds
If you just want to test (and not debug) a recent build of QGroundControl you can use the Daily Build. Versions are provided for all platforms.
Source Code
Source code for QGroundControl is kept on GitHub. It is dual-licensed under Apache 2.0 and GPLv3.
To get the source files, clone the repo (or your fork):
git clone -j8 https://github.com/mavlink/qgroundcontrol.gitBuild QGroundControl
QGroundControl uses Qt as its cross-platform support library and is built exclusively with CMake (qmake is no longer supported). You can build it:
- Natively on your own machine.
- In a container, without installing any requirements locally (Linux builds and a VS Code Dev Container).
- In a disposable Linux virtual machine with Vagrant or Multipass.
Native Builds
QGroundControl builds are supported for Windows, macOS, Linux, Android and iOS.
The required version of Qt is 6.12.0 (only).
WARNING
Do not use any other version of Qt! QGC has been thoroughly tested with the specified version of Qt (6.12.0). Other Qt versions carry a significant risk of injecting bugs that affect stability and safety (even if QGC compiles).
The Qt version, the minimum CMake version, and the pinned GStreamer, Android and Xcode versions are all defined in .github/build-config.json. just info prints the Qt, CMake and GStreamer versions for your checkout. For more information see: Qt 6 supported platform list.
Prerequisites
Python 3.10+ and uv: QGC's code generators and tools run in a locked Python environment in
tools/.venv, which CMake creates with uv the first time you configure. On Linux and macOS,python3 tools/setup/install_uv.pyinstalls uv; on Windows, follow the uv installation guide.CMake 3.28 or newer and Ninja: the dependency scripts below install them on Linux and macOS, and the
justrecipes run CMake from the locked tool environment. If you runcmake/qt-cmakeyourself, make sure thecmakeon yourPATHis new enough. Ubuntu 24.04's package is; on older distributions, such as Ubuntu 22.04 or Debian 12, use the CMake from Developer and Designer Tools in the Qt Online Installer orpip install cmake.just (recommended): the command runner used for the everyday build, test and lint commands. Install it, together with prek (the pre-commit hook runner) and the other developer tools, into
tools/.venv:shpython3 tools/setup/install_python.py dev . tools/.venv/bin/activate # Windows PowerShell: tools\.venv\Scripts\Activate.ps1Run
justwith no arguments to list every recipe; the tools README describes them.
Install Qt
You must install Qt as described below instead of using pre-built packages from, say, a Linux distribution.
To install Qt with the Qt Online Installer:
- Download and run the Qt Online Installer.
- Ubuntu: Set the downloaded file to executable using
chmod +x. It may also be necessary to install libxcb-cursor0.
- Ubuntu: Set the downloaded file to executable using
- On the Installation Folder page select Custom Installation.
- On the Select Components page:
- If you don't see Qt 6.12.0 listed check the Archive checkbox and click Filter.
- Under Qt -> Qt 6.12.0 select:
- Windows: MSVC 2022 <arch> - where <arch> is the architecture of your machine
- Mac: Desktop
- Linux: Desktop gcc 64-bit
- Android: Android (plus the Desktop kit for your host)
- Select all Additional Libraries.
- Deselect Qt Design Studio.
Alternatively, tools/setup/install_qt.py installs exactly the Qt version and modules CI uses (with QGC's own installer on Linux, which needs CMake, and aqtinstall elsewhere), for example on Linux:
python3 tools/setup/install_qt.py install --from-config --host linux --arch linux_gcc_64 --outdir ~/QtUse --host mac --arch clang_64 on macOS, or --host windows --arch win64_msvc2022_64 on Windows.
Install Additional Packages
Run the dependency script from the root of the cloned repository (cd qgroundcontrol). It is the same script CI uses:
- Linux (Debian/Ubuntu, Fedora or Arch) and macOS:
python3 tools/setup/install_dependencies(orjust deps). The platform is detected automatically; override it with--platform debian|fedora|arch|macos. It installs system packages with apt, dnf or pacman (usingsudo), or with Homebrew plus the GStreamer framework on macOS. - Windows:
python tools/setup/install_dependencies --platform windows, from an Administrator prompt. By default it installs only GStreamer (x64 only, from the QGC dependency mirror). Optional flags:--nsisinstalls NSIS (needed to build the installer),--msvcinstalls the Visual Studio 2022 Build Tools C++ workload, and--vulkaninstalls the Vulkan SDK.
Useful options: --dry-run shows what would be installed, --list lists the packages by category, and on Linux --category <name> installs a single category (core, qt, gstreamer, sdl, audio or misc; on Debian/Ubuntu also android, which is core plus the JDK for Gradle).
TIP
Android dependencies are best set up by following the Qt documentation: read Qt 6 for Android carefully, then continue with Getting Started with Qt 6 for Android. See Android and iOS below for the QGC-specific settings.
OS-Specific Functionality
Optional features that depend on the operating system and user-installed libraries are described below. Features can be forcibly enabled or disabled by passing -D options to CMake (for example -DQGC_ENABLE_GST_VIDEOSTREAMING=OFF).
- Video Streaming/GStreamer: Installed by the dependency script on Linux. On Windows, macOS, Android and iOS, CMake also downloads the GStreamer SDK at configure time if it isn't already installed. See Video Streaming for details. Without GStreamer, network streams play through Qt Multimedia's player, which records a stream by encoding the video on display anew, so only while it is shown. When cross-compiling for Windows ARM64 from an x64 host, disable video streaming with
-DQGC_ENABLE_GST_VIDEOSTREAMING=OFF(this is what CI does): the ARM64 GStreamer SDK installer cannot run on an x64 host, so the automatic download fails. - Windows Installer: Building the Windows installer requires NSIS, which the dependency script installs when run with
--nsis.
Install Visual Studio Compiler (Windows Only)
An MSVC 2022 C++ toolchain is required. Either of the following works:
- The Visual Studio 2022 Build Tools with the C++ build tools workload (this is what CI uses, and what the dependency script installs when run with
--msvc), or - Visual Studio 2022 Community Edition with the Desktop development with C++ workload, if you also want the IDE.
INFO
Visual Studio is ONLY used to get the compiler. Building QGroundControl is done using just, CMake or Qt Creator as outlined below; run command-line builds from an x64 Native Tools Command Prompt for VS 2022.
Build using just
From the root of the repository:
just configure # Configure a Debug build in build/ (CMake "default" preset)
just build # Build, using all cores (JOBS=N limits parallel jobs)
just run # Launch the application you just built
just test # Run the unit testsjust releaseconfigures and builds Release instead.BUILD_TYPEselects other build types, for exampleBUILD_TYPE=RelWithDebInfo just configure build.tools/configure.py(whichjust configureruns) uses theqt-cmakefrom the newest Qt it finds under~/Qt(orC:\Qton Windows). SetQT_ROOT_DIRto a Qt kit directory, such as~/Qt/6.12.0/gcc_64, to choose a different one.just checkruns the lint checks, the Python tooling tests and the unit tests; see Code Submission and Unit Tests.
Build using CMake on CLI
Example commands to build a default QGC and run it afterwards:
Change into the repository folder (see Source Code above):
shcd qgroundcontrolConfigure:
sh~/Qt/6.12.0/gcc_64/bin/qt-cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=DebugChange the directory for
qt-cmaketo match your install location for Qt and the kit you want to use.Windows: use the corresponding kit path, for example
C:\Qt\6.12.0\msvc2022_64\bin\qt-cmake.bat, from an x64 Native Tools Command Prompt for VS 2022.Mac: To Sign/Notarize/Staple the QGC app bundle, add
-DQGC_MACOS_SIGN_WITH_IDENTITY=ONto the configure command line. During theinstallphase the following environment variables will need to be available:QGC_MACOS_SIGNING_IDENTITY- Signing identity for your Developer ID certificate which must be in the keychainQGC_MACOS_NOTARIZATION_USERNAME- Username for your Apple Developer AccountQGC_MACOS_NOTARIZATION_PASSWORD- App specific password for Notarization from your Apple Developer AccountQGC_MACOS_NOTARIZATION_TEAM_ID- Apple Developer Account Team ID
Build:
shcmake --build build --config DebugNinja builds in parallel by default; add
--parallel <N>to limit the number of jobs.Run the QGroundControl binary that was just built:
sh./build/Debug/QGroundControlOn Windows:
build\Debug\QGroundControl.exe; on macOS:./build/Debug/QGroundControl.app/Contents/MacOS/QGroundControl.
CMake Presets
CMakePresets.json defines the configurations CI builds, so local and CI builds match. The platform presets (Linux-debug, macOS-debug, Windows-debug, Linux-sanitizers, Linux-coverage, iOS-simulator, and so on) take the Qt kit from QT_ROOT_DIR and build in build/<preset>:
export QT_ROOT_DIR=~/Qt/6.12.0/gcc_64
cmake --list-presets=all # Show every preset
cmake --workflow --preset Linux-debug # Configure, build and testCross-compiling presets need more environment variables; see the CMake development guide for each preset family's requirements. Put machine-local presets in CMakeUserPresets.json, which Git ignores.
Building using Qt Creator
Launch Qt Creator, select Open Project and select the CMakeLists.txt file.
On the Configure Project page it should default to the version of Qt you just installed using the instruction above. If not select that kit from the list and click Configure Project.
TIP
Don't forget to check boxes in case you want to build a Release instead of Debug, or check the other types. To create the installation file go to the Deploy Settings tab, click the Add Deploy Step menu button, select CMake Install and set at least
--config Releaseas its argument.Build using the "hammer" icon. After that, in order to deploy the build, use the "play" icon. Or use the menu Build on top for a detailed alternative.
Building using VS Code
Run just vscode to install the workspace settings, build/test tasks and debugger launch configurations from the tracked templates in .vscode/ (existing files are never overwritten), then install the recommended extensions when VS Code prompts you. To develop inside a container instead, see VS Code Dev Container.
Android and iOS
- Android: Install Qt for Android together with the matching desktop Qt (the host Qt), plus the Android SDK, NDK and JDK versions listed under
androidinbuild-config.json. On Debian/Ubuntu,python3 tools/setup/install_dependencies --category androidinstalls the build tools and the matching OpenJDK. TheAndroidandAndroid-debugpresets readQT_TARGET_ROOT_DIR(Qt for Android),QT_HOST_PATH(desktop Qt),ANDROID_NDKandANDROID_MIN_SDKfrom the environment. The build produces an APK;cmake --build <build-dir> --target aabalso builds an Android App Bundle. - iOS (macOS host with Xcode): Install Qt for iOS together with the matching macOS Qt. The
iOS,iOS-debugandiOS-simulatorpresets readQT_ROOT_DIR(Qt for iOS) andQT_HOST_PATH(macOS Qt);iOS-simulatorbuilds a Debug app for the x86_64 iOS Simulator.
Building QGC Installation Files
You can additionally create installation files for QGroundControl from a Release build:
Linux AppImage and macOS DMG: run the install step:
shcmake --install build --config ReleaseUse the same build directory you passed to
-Bwhen configuring, and a configuration (Release/Debug) that you actually built.Windows installer: build the
qgc-packagetarget, which creates the NSIS installer (requires NSIS, installed by the dependency script when run with--nsis):shcmake --build build --config Release --target qgc-packageLinux
.deband.rpmpackages: withQT_ROOT_DIRset, run theLinux-deborLinux-rpmworkflow preset, for examplecmake --workflow --preset Linux-deb.
Build Caching
QGC uses two build caches, both enabled automatically at configure time and stored in the source tree so they survive build directory deletion:
- ccache caches compiler output (
.cache/ccache/). Used ifccacheis installed and on yourPATH(the Linux and macOS dependency scripts install it);sccacheis used instead if only it is found, with precompiled headers turned off because sccache can reuse a stale GCC precompiled header. - moccache caches Qt moc output (
.cache/moccache/). QGC has a large number of moc-processed headers, so on clean builds, branch switches, and rebuilds after deleting the build directory a warm moccache skips the entire moc phase. Controlled by theQGC_USE_MOCCACHECMake option (ON by default).
Neither cache requires any setup. To bypass moccache for a single build set MOCCACHE_DISABLE=1, or configure with -DQGC_USE_MOCCACHE=OFF to turn it off entirely.
moccache Details
moccache (the tools/moccache/ package) is a content-addressed cache wired in automatically as the AUTOMOC_EXECUTABLE via a launcher script generated at configure time. Cached moc output is keyed on moc version + arguments + input content + transitive include contents + the input's path relative to the output directory (moc embeds that relative path as an #include in its output, so build trees laid out at a different depth intentionally don't share entries). Entries are otherwise shared across build trees: build-dir paths are rewritten to a token, like ccache's base_dir. The launcher runs tools/moccache_launcher.py, which imports the moccache package so Python reuses its cached bytecode instead of recompiling it on every moc run.
Cache misses fall through to the real moc and never fail the build; corrupt or stale entries are caught on every use, when each recorded include is re-validated by content hash unless its mtime, ctime and size still match the values recorded with that hash.
Environment variables (set by the launcher, overridable at build time):
| Variable | Default | Purpose |
|---|---|---|
MOCCACHE_DIR | <repo>/.cache/moccache | Cache location (persisted by CI, like ccache) |
MOCCACHE_MAX_SIZE | 1G | LRU auto-trim threshold (trims after misses) |
MOCCACHE_DISABLE | unset | Pass through to real moc (no caching) |
MOCCACHE_STATS | unset | Log hits/misses; print this build's stats after linking |
MOCCACHE_STATS=1 just build # This build's hit/miss stats print after linking
MOCCACHE_BASEDIR=$PWD/build python3 ./tools/moccache_launcher.py --show-stats --build-dir build --verbose # Per-miss reasons for the last build
python3 ./tools/moccache_launcher.py --zero-stats # Reset the stats log
python3 ./tools/moccache_launcher.py --trim --max-size 1G # Explicitly trim the cache (LRU)
MOCCACHE_DISABLE=1 just build # Bypass the cache for one buildEach miss is logged with a reason, and the report explains each kind inline, so you can tell expected misses from cache problems: miss-first-seen, miss-header-changed, miss-include-changed and miss-predefs-changed are expected; miss-cache-evicted means the cache is too small (raise MOCCACHE_MAX_SIZE); miss-args-changed and miss-output-depth-differs mean build trees differ in a way that defeats sharing and are worth investigating (--verbose shows the first differing argument per miss). See the docstring in tools/moccache/__init__.py for the full list. --markdown prints the same report as tables, with the cache size; CI build jobs add it to the job summary.
Virtual Machines
Both VM options provision an Ubuntu guest, install the dependencies and Qt with the repository's own scripts, and build a Release AppImage.
Vagrant
Vagrant can be used to build and run QGroundControl within a Linux virtual machine (the build can also be run on the host machine if it is compatible).
- Download and Install Vagrant and a provider (VirtualBox, VMware or libvirt). With libvirt the guest boots via UEFI: install the
ovmfpackage (Debian/Ubuntu), or pointQGC_VM_UEFI_LOADERat your distribution's combined OVMF firmware image. - From the
deploy/vagrantdirectory of the repository runvagrant up. This provisions an Ubuntu desktop guest (with Qt Creator) that shares the repository as/vagrant, builds QGC, and copies the build toshadow_build/in your checkout. - To use the graphical environment run
vagrant reload.
To reproduce the CI Vagrant job on an Ubuntu host, run deploy/vagrant/run_vagrant.py. Its install step sets up Vagrant, libvirt/KVM, UEFI firmware and the vagrant-libvirt plugin; the default build step runs a headless VM, copies the AppImage to OUTPUT_DIR (default: the current directory) and destroys the VM:
python3 deploy/vagrant/run_vagrant.py install
OUTPUT_DIR=artifacts python3 deploy/vagrant/run_vagrant.pyQGC_VM_CPUS, QGC_VM_MEM_MB and QGC_VM_UP_TIMEOUT (seconds, default 150 minutes) adjust the VM size and the vagrant up time limit. The script refuses to run while another Vagrant machine (such as the desktop VM above) exists in deploy/vagrant; remove it first with vagrant destroy.
Multipass
Multipass builds in a throwaway Ubuntu VM and copies the AppImage to OUTPUT_DIR (default: the current directory):
QGC_SOURCE_DIR=$PWD OUTPUT_DIR=artifacts python3 deploy/multipass/run_multipass.pyWithout QGC_SOURCE_DIR the VM clones upstream master instead of building your checkout. MP_CPUS (default 4), MP_MEM (8G), MP_DISK (25G) and MP_IMAGE size and select the VM, and MP_TIMEOUT (default 900 seconds) bounds multipass launch. The instance (MP_NAME, default qgc) must not already exist, and is deleted when the build finishes.