Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
fwupd is a Linux firmware update daemon built with Meson, written in C with GLib, and includes 130+ plugins for various hardware vendors. It provides both a daemon (fwupd) and command-line tools (fwupdmgr, fwupdtool) for firmware management.
ghcr.io/fwupd/fwupd/fwupd-debian-x86_64:latest for consistent development environment./contrib/ci/fwupd_setup_helpers.py install-dependencies -o debian --yes (inside container) -- takes 30+ minutes for dependency installation. NEVER CANCEL.build-fwupd (in venv) -- takes 45+ minutes. NEVER CANCEL. Set timeout to 60+ minutes.test-fwupd (in venv) -- takes 15+ minutes. NEVER CANCEL. Set timeout to 30+ minutes.Container-based development (REQUIRED for automation)
# Use the pre-built fwupd container for consistent Debian environment # Container: https://github.com/fwupd/fwupd/pkgs/container/fwupd%2Ffwupd-debian-x86_64 docker pull ghcr.io/fwupd/fwupd/fwupd-debian-x86_64:latest # Run container with source mounted docker run -it --privileged -v $(pwd):/workspace ghcr.io/fwupd/fwupd/fwupd-debian-x86_64:latest # Inside container - install dependencies first cd /workspace ./contrib/ci/fwupd_setup_helpers.py install-dependencies -o debian --yes # Create virtual environment python3 -m venv venv --system-site-packages --prompt fwupd source venv/bin/activate # Setup development wrappers BASE=../contrib/ BIN=venv/bin/ TEMPLATE=${BASE}/launch-venv.sh for F in fwupdtool fwupdmgr fwupd; do rm -f ${BIN}/${F} ln -s $TEMPLATE ${BIN}/${F} done rm -f ${BIN}/build-fwupd ln -s ${BASE}/build-venv.sh ${BIN}/build-fwupd rm -f ${BIN}/test-fwupd ln -s ${BASE}/test-venv.sh ${BIN}/test-fwupd # Build the project - takes 45+ minutes, NEVER CANCEL, set timeout 60+ minutes build-fwupd # Run tests - takes 15+ minutes, NEVER CANCEL, set timeout 30+ minutes test-fwupd
All tools run with elevated privileges automatically in the venv:
fwupdtool - Debugging tool for developers, runs standalone without daemonfwupdmgr - End-user client tool, requires daemon runningfwupd - Background daemon, run manually in development# Get devices from specific plugin (fastest for development) fwupdtool --plugins vli get-devices --verbose # Get all devices (comprehensive) fwupdtool get-devices # Parse firmware blob fwupdtool firmware-parse /path/to/firmware.bin # Install firmware blob to device fwupdtool --verbose --plugins PLUGIN install-blob /path/to/firmware.bin DEVICE_ID
Terminal 1 - Run daemon:
source venv/bin/activate fwupd --verbose
Terminal 2 - Run client:
source venv/bin/activate fwupdmgr install ~/firmware.cab
# Format code ./contrib/reformat-code.py # Run linting pre-commit run --all-files # Build and test (with proper timeouts) build-fwupd # 45+ minutes, NEVER CANCEL test-fwupd # 15+ minutes, NEVER CANCEL
Always test at least one complete end-to-end scenario:
fwupdtool --plugins YOURPLUGIN get-devices --verbosefwupdtool install-blob for quick testingsrc/ - Main daemon and tool source codelibfwupd/ - Client library sourcelibfwupdplugin/ - Plugin framework libraryplugins/ - 130+ hardware vendor pluginscontrib/ - Build scripts and CI helpersdata/ - Configuration files and resourcesdocs/ - Documentation and building guidesmeson.build - Main build configurationmeson_options.txt - Build options (117 configurable options)contrib/setup - Development environment setup scriptcontrib/ci/fwupd_setup_helpers.py - Dependency installation helper.github/workflows/matrix.yml - CI build matrix (Fedora, Debian, Arch, etc.)Over 80 packages including: meson, libglib2.0-dev, libxmlb-dev, libjcat-dev, libarchive-dev, libcbor-dev, libcurl4-gnutls-dev, valgrind, clang-tools, python3-gi-cairo, and many more.
# Test specific plugin only fwupdtool --plugins YOUR_PLUGIN get-devices --verbose # Parse plugin-specific firmware fwupdtool firmware-parse firmware.bin # Choose the appropriate parser from the list # Install plugin firmware fwupdtool --verbose --plugins YOUR_PLUGIN install-blob firmware.bin DEVICE_ID
# Auto-format current patch ./contrib/reformat-code.py # Format specific commits ./contrib/reformat-code.py HEAD~5 # Run all pre-commit hooks pre-commit run --all-files # Check specific files shellcheck contrib/ci/*.sh
The CI tests on: Fedora, CentOS, Debian x86_64, Debian i386, Ubuntu x86_64, Arch Linux
Ctrl+Shift+B - runs build-fwupdCtrl+Shift+P -> “Run test task”gdbserver-fwupd for daemon debugging# Debug any tool with gdbserver DEBUG=1 fwupdtool get-devices DEBUG=1 fwupdmgr get-devices
-Dbuild=all|standalone|library - What to build-Dtests=true|false - Enable/disable tests-Dplugin_*=enabled|disabled|auto - Individual plugin control-Dsystemd=enabled|disabled|auto - systemd integration-Dintrospection=enabled|disabled|auto - GObject introspection# Library only (faster) meson setup build -Dbuild=library # Without tests (faster) meson setup build -Dtests=false # Specific plugins only meson setup build -Dplugin_uefi_capsule=enabled # enable specific plugin
ghcr.io/fwupd/fwupd/fwupd-debian-x86_64:latest for consistent Debian environment./contrib/ci/fwupd_setup_helpers.py install-dependencies -o debian --yes inside containergit config --global --add safe.directory /workspace inside container./contrib/ci/fwupd_setup_helpers.py test-mesonsource venv/bin/activate should show (fwupd) promptpython3 -m venv venv --system-site-packages after dependency installationfwupdtool instead of full daemon./contrib/reformat-code.py first