Skip to content

The Packaged Building Mode

ilya-fedin edited this page Oct 11, 2021 · 71 revisions

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, FreeBSD 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 October 11, 2021, you need:

  • Python (2 or 3, required for codegens)
  • extra-cmake-modules (Linux-only, can be disabled with DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
  • Qt5 (required: qtbase, qtimageformats, qtsvg; make sure qtimageformats is a hard runtime dependency, tdesktop requires the webp plugin to be present)
  • 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, on Linux it depends on ALSA/pulseaudio that can be turned off with LIBTGVOIP_DISABLE_ALSA/LIBTGVOIP_DISABLE_PULSEAUDIO respectively when building the bundled copy)
  • tg_owt (required)
  • FFmpeg (required)
  • glibmm (Linux/FreeBSD, can be disabled with DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
  • Microsoft's GSL (required, fallbacks to the bundled copy if not found)
  • Hunspell (fallbacks to the bundled copy if not found, can be disabled with DESKTOP_APP_DISABLE_SPELLCHECK, 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 (required, Linux-only, fallbacks to the bundled copy if not found, it's recommended to build it with clang to avoid random crashes)
  • kwayland (Linux-only, can be disabled with DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
  • libdbusmenu-qt (Linux/FreeBSD, fallbacks to the bundled copy if not found, can be disabled with DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
  • 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)
  • OpenSSL (required)
  • Opus (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)
  • wayland-client (Linux-only, can be disabled with DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
  • WebKitGTK (Linux-only, can be disabled with DESKTOP_APP_DISABLE_WEBKITGTK)
  • xcb, xcb-record, xcb-screensaver, xcb-keysyms (Linux/FreeBSD, 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.

As of October 11, 2021, there's DESKTOP_APP_USE_PACKAGED_FFMPEG_STATIC and TG_OWT_PACKAGED_BUILD_FFMPEG_STATIC (for tg_owt respectively) invented for convenient building of macOS app bundle. That is, macdeployqt rewrites rpaths of direct dependencies only and doesn't process libraries recursively. Since brew's ffmpeg contains a lot of dependencies, you may want to build ffmpeg manually and link it statically, to avoid the headache of manual libraries processing.

As of October 11, 2021, there's DESKTOP_APP_USE_PACKAGED_FONTS that defaults to ON. If you leave it to default value, 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, set DESKTOP_APP_USE_PACKAGED_FONTS to OFF. 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.

tg_owt dependencies, as of October 11, 2021:

  • abseil (required, fallbacks to the bundled copy if not found)
  • FFmpeg (required)
  • glib (can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
  • JPEG (required)
  • libevent (required, fallbacks to the bundled copy if not found)
  • OpenH264 (required, fallbacks to the bundled copy if not found)
  • OpenSSL (required)
  • Opus (required)
  • PipeWire (can be disabled with TG_OWT_USE_PIPEWIRE=OFF)
  • usrsctp (required, fallbacks to the bundled copy if not found)
  • VPX (required, fallbacks to the bundled copy if not found)
  • X11: Xcomposite Xdamage Xext Xfixes Xrender Xrandr Xtst (required)
cmake -B build . -DBUILD_SHARED_LIBS=OFF -DTG_OWT_BUILD_AUDIO_BACKENDS=OFF
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.