The Packaging Building Mode (enabled with DESKTOP_APP_USE_PACKAGED) is an unofficial building mode made by the community that uses cmake features like find_package, find_library and pkg-config's pkg_search_modules. The official building instructions uses self-built static libraries of pre-defined versions installed to hard-coded paths. That mode is official since it's made by the hired developer who is mostly a Windows developer and this is convenient on Windows, so these practices are used in official building instructions of other platforms, as well.
Disclaimer: This instruction is not for newbies, it doesn't describe all the things in detail, it's more a documentation on a mode for experienced enough users, mostly package maintainers willing to build tdesktop with system packages. If you want to just build tdesktop, use official instructions.
As of October 11, 2021, this mode is proven to work on Linux and MacOS (you can use packages from brew). Since it's a community-maintained building method, it can break at any time and no one guarantees it will be ever fixed.
To build in the packaged building mode, as of May 20, 2024, you need:
- Python 3 (required for codegens)
- Qt6Core (required)
- Qt6Gui (required)
- Qt6OpenGL (required)
- Qt6Widgets (required)
- Qt6OpenGLWidgets (required)
- Qt6Network (required)
- Qt6Svg (required)
- Qt6Quick (Linux-only, optional)
- Qt6QuickWidgets (Linux-only, optional)
- Qt6WaylandCompositor (Linux-only, optional)
- Qt6 Image Formats (webp plugin is required, make sure it's a hard runtime dependency, or else tdesktop will coredump at startup without it)
- libtgvoip (required, fallbacks to the bundled copy if not found, it's recommended to use the bundled copy since it's a legacy library and its upstream build scripts aren't adapted to build with tg_owt, so the calls will crash due to two webrtc libraries being in one address space)
- tg_owt (required)
- abseil (required, fallbacks to the bundled copy if not found)
- drm (Linux-only, can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
- FFmpeg (required)
- gbm (part of Mesa) (Linux-only, can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
- glib (Linux-only, can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
- glvnd (Linux-only, can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
- JPEG (required)
- OpenH264 (required, fallbacks to the bundled copy if not found)
- OpenSSL (required)
- Opus (required)
- PipeWire (Linux-only, can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
- VPX (required, fallbacks to the bundled copy if not found)
- X11: Xcomposite Xdamage Xext Xfixes Xrender Xrandr Xtst (Linux-only, required)
- libprisma (required, always bundled fork)
- Boost::regex (required)
- cld3 (required on Linux, always bundled, can be disabled with DESKTOP_APP_USE_CLD3=OFF on Windows, not used on macOS)
- Protobuf (required)
- cppgir (Linux-only, required, always bundled, build-time only codegen)
- Boost (required)
- FFmpeg (required)
- glibmm (Linux-only, required)
- GObject Introspection (Linux-only, required, build-time only codegen)
- Libtool (g-ir-scanner doesn't use
-Wl,--export-dynamic
without it for whatever reason what leads to build error)
- Libtool (g-ir-scanner doesn't use
- Grand Central Dispatch (Linux-only, fallbacks to poor QThreadPool if not found and can't build bundled copy)
- Guidelines Support Library (required, always bundled fork)
- Hunspell (Linux + Windows 7 only, required, fallbacks to the bundled copy if not found, can be replaced with enchant on Linux with DESKTOP_APP_USE_ENCHANT, but you should know that enchant backend is proven to crash continuously and drain your RAM if you have too much dictionaries installed)
- jemalloc (Linux-only, fallbacks to the bundled copy if not found, can be disabled with DESKTOP_APP_DISABLE_JEMALLOC which is likely to make media leak, it's recommended to use clang-built jemalloc to avoid random crashes)
- KCoreAddons (required, fallbacks to the bundled copy if not found)
- Qt6DBus (Linux-only, optional)
- LZ4 (fallbacks to the bundled copy if not found, can be disabled with DESKTOP_APP_LOTTIE_USE_CACHE=OFF)
- minizip (part of zlib, required, fallbacks to the bundled copy if not found)
- OpenAL (required, you can try to use the system version on macOS)
- Open Sans (required in runtime, bundled if DESKTOP_APP_USE_PACKAGED_FONTS is not set, UI artifacts are likely without it)
- OpenSSL (required)
- QR Code Generator (required, fallbacks to the bundled copy if not found)
- range-v3 (required, fallbacks to the bundled copy if not found)
- rlottie (required, fallbacks to the bundled copy if not found, it's recommended to use the bundled copy since tdesktop needs APIs that exist only in its fork)
- rnnoise (required)
- tl-expected (required, fallbacks to the bundled copy if not found)
- WebKitGTK (Linux-only, runtime-only optional dependency)
- xcb, xcb-record, xcb-screensaver, xcb-keysyms (Linux-only, can be disabled with DESKTOP_APP_DISABLE_X11_INTEGRATION)
- xxHash (required, fallbacks to the bundled copy if not found)
- zlib (required)
As of October 11, 2021, packaged mode is the default, it's controlled by DESKTOP_APP_USE_PACKAGED. Its default value depends on DESKTOP_APP_SPECIAL_TARGET that indicates official building mode. That is, you should never override DESKTOP_APP_SPECIAL_TARGET default value or you can end up with hardcoded paths, autoupdater and the requesting of private keys you don't have.
As of October 11, 2021, there's DESKTOP_APP_USE_PACKAGED_LAZY, it silences the warnings when some library is not found + activates bundling of third-party (i.e. not included in Qt) CJK input methods for Linux (as of October 11, 2021: fcitx, fcitx5, hime, nimf). It's invented for self-contained distribution formats like AppImage, Flatpak, Snap. The official non-packaged mode bundles them as well.
Tip: you can also silence the warnings per-dependency with CMAKE_DISABLE_FIND_PACKAGE_<PackageName> or make packaged variants of bundled dependencies required with CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>.
As of April 13, 2022, there's DESKTOP_APP_USE_PACKAGED_FONTS that defaults to OFF. If you enable it, make sure your package hardly depends on Open Sans font in your packaging system. tdesktop's widgets won't work properly without Open Sans. If you can't package Open Sans or make tdesktop depend on it, don't override DESKTOP_APP_USE_PACKAGED_FONTS. That way, you can provide non-broken UI for users of your package.
I won't describe how to build all the dependencies since the point of the manual is how to build tdesktop using pre-built packages, but I'll describe how to build tg_owt, Telegram's fork of Intel's fork of Google WebRTC library. Sounds like a matroska, yeah? The reason for that is they use H265 for calls that is present only in Intel's fork. The reason for their own fork is Telegram uses libraries such as ffmpeg that are used by WebRTC as well, but WebRTC uses its own bundled copies that results in multiple copies of the same libraries mess up in one binary. There's also an annoying thing you must use gclient to clone webrtc and its minimal supported version of macOS is greater than minimal supported version of macOS in webrtc itself, so you can't build on older macOS just due to gclient. If these two problems aren't problems for you, you can try your luck with the Intel's fork. I think, it should work, but you would need some changes to tdesktop's cmake files since it finds tg_owt with find_package in the packaged mode.
cmake -B build .
cmake --build build
cmake --install build
These three commands will build & install tg_owt as a static library (I don't really recommend to build it as a shared library: google never thought it will be built as a shared library, so it doesn't have stable ABI and will change the ABI even if you just change some build options, so after each rebuild you should rebuild tdesktop as well) without audio backends (tdesktop uses its own backend based on openal, so you don't need ones in tg_owt, not to mention Google considers them good for demo purposes only) in the build subdirectory (out-of-tree build, it's optional, just remove -B build
and replace refences to the directory in the next commands with .
). The installation command is optional, you can specify -Dtg_owt_DIR=$PATH_TO_TG_OWT_REPO/build
to tdesktop cmake flags to let it find tg_owtConfig.cmake without installing it to the system.
Finally, tdesktop build:
cmake -B build . -DTDESKTOP_API_ID=your_id -DTDESKTOP_API_HASH=your_hash
cmake --build build
cmake --install build
As you can see, you must get API ID/hash in order to build tdesktop, that's quite tricky though since you can have only one API key per account and according to the official rules, you can't publish them or they'll be banned. So you need to find a way to privately set API keys in your builds scripts, via some secret mechanism. If you can't do that, then you can't build tdesktop officialy, unfortunately. You can try to use -DTDESKTOP_API_TEST=ON
instead that will build tdesktop with test API key that is very limited.