{"id":14982707,"url":"https://github.com/quotient-im/libquotient","last_synced_at":"2026-02-15T22:11:46.338Z","repository":{"id":37458516,"uuid":"55817137","full_name":"quotient-im/libQuotient","owner":"quotient-im","description":"A Qt library to write cross-platform clients for Matrix","archived":false,"fork":false,"pushed_at":"2025-04-11T08:55:14.000Z","size":8054,"stargazers_count":137,"open_issues_count":93,"forks_count":57,"subscribers_count":11,"default_branch":"dev","last_synced_at":"2025-04-11T10:54:59.884Z","etag":null,"topics":["c-plus-plus","chat","client","cpp","hacktoberfest","matrix","qt","qt5","sdk"],"latest_commit_sha":null,"homepage":"https://quotient-im.github.io/libQuotient/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quotient-im.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-04-09T00:12:50.000Z","updated_at":"2025-04-06T18:15:21.000Z","dependencies_parsed_at":"2023-10-23T17:31:07.281Z","dependency_job_id":"17ef334f-5f15-47fc-947e-8fb8cd02d619","html_url":"https://github.com/quotient-im/libQuotient","commit_stats":{"total_commits":3298,"total_committers":49,"mean_commits":67.3061224489796,"dds":0.2328684050939963,"last_synced_commit":"982702576378c5b0a46823fe6d2f81be4ed77283"},"previous_names":[],"tags_count":75,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quotient-im%2FlibQuotient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quotient-im%2FlibQuotient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quotient-im%2FlibQuotient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quotient-im%2FlibQuotient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quotient-im","download_url":"https://codeload.github.com/quotient-im/libQuotient/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248531249,"owners_count":21119730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","chat","client","cpp","hacktoberfest","matrix","qt","qt5","sdk"],"created_at":"2024-09-24T14:05:53.551Z","updated_at":"2026-02-15T22:11:46.331Z","avatar_url":"https://github.com/quotient-im.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libQuotient\n\n\u003c!--\u003ca href='https://matrix.org'\u003e\u003cimg src='https://matrix.org/docs/projects/images/made-for-matrix.png' alt='Made for Matrix' height=64 target=_blank /\u003e\u003c/a\u003e--\u003e\n\n[![license](https://img.shields.io/github/license/quotient-im/libQuotient.svg)](https://github.com/quotient-im/libQuotient/blob/dev/COPYING)\n![status](https://img.shields.io/badge/status-beta-yellow.svg)\n[![release](https://img.shields.io/github/release/quotient-im/libQuotient/all.svg)](https://github.com/quotient-im/libQuotient/releases/latest)\n[![](https://img.shields.io/cii/percentage/1023.svg?label=CII%20best%20practices)](https://bestpractices.coreinfrastructure.org/projects/1023/badge)\n![](https://img.shields.io/github/commit-activity/y/quotient-im/libQuotient.svg)\n![CI Status](https://img.shields.io/github/actions/workflow/status/quotient-im/libQuotient/ci.yml)\n![Sonar Tech Debt](https://img.shields.io/sonar/tech_debt/quotient-im_libQuotient?server=https%3A%2F%2Fsonarcloud.io)\n![Sonar Coverage](https://img.shields.io/sonar/coverage/quotient-im_libQuotient?server=https%3A%2F%2Fsonarcloud.io)\n![Matrix](https://img.shields.io/matrix/quotient:matrix.org?logo=matrix)\n\nThe Quotient project aims to produce a Qt-based SDK to develop applications for\n[Matrix](https://matrix.org). libQuotient is a library that enables client applications. It is\nthe backbone of [Quaternion](https://github.com/quotient-im/Quaternion),\n[NeoChat](https://invent.kde.org/network/neochat) and other projects.\n\n## Contacts\n\nYou can find Quotient developers in the Matrix room:\n[#quotient:matrix.org](https://matrix.to/#/#quotient:matrix.org).\n\nYou can file issues at\n[the project issue tracker](https://github.com/quotient-im/libQuotient/issues).\nIf you find what looks like a security issue, please use instructions\nin [SECURITY.md](./SECURITY.md).\n\n## Getting and using libQuotient\n\nDepending on your platform, the library can be obtained from a package management system.\nRecent releases of Fedora, Debian and openSUSE already have it. Alternatively, you can build\nthe library from the source and bundle it with your application, as described below.\n\n### Pre-requisites\n\nTo use libQuotient (i.e. build or run applications with it), you'll need:\n\n- A recent Linux, macOS or Windows system (desktop versions are known to work, and there's also\n  limited positive experience with Android)\n  - Recent enough Linux examples: Debian Trixie; Fedora 41; Ubuntu 25.04\n- Qt 6.8 or newer - either Open Source or Commercial\n- QtKeychain (https://github.com/frankosterfeld/qtkeychain) - the newest release is recommended;\n  the build configuration of QtKeychain must use the same Qt major version, i.e. Qt 6.\n\nTo build applications with libQuotient, you'll also need:\n\n- CMake 3.26 or newer\n- A C++ toolchain that has reasonably complete C++20 support and some C++23 elements\n  (`std::expected`, in particular)\n  - GCC 14 (Windows, Linux, macOS), Clang 19 (Linux), Apple Clang 15 (macOS 14+)\n    and Visual Studio 2022 17.6 (Windows) are the oldest officially supported\n- libolm 3.2.5 or newer (the latest 3.x strongly recommended)\n- OpenSSL 3.x (1.1.x may still work but is strongly discouraged)\n- Any build system that works with CMake should be fine; known to work are GNU Make and\n  ninja (recommended) on any platform; NMake and jom on Windows should also work\n\nThe requirements to build libQuotient itself are basically the same except that you should install\ndevelopment libraries for the dependencies listed above.\n\n#### Linux\n\nJust install the prerequisites using your preferred package manager. If your Qt package base is\nfine-grained you might want to run CMake and look at error messages. The library is entirely\noffscreen; however, aside from QtCore and QtNetwork it also depends on QtGui in order to handle\navatar thumbnails, without any on-screen drawing.\n\n#### macOS\n\n`brew install qt qtkeychain libolm openssl@3` should get you the most recent versions of\nthe runtime libraries.\n\nYou may need to add `$(brew --prefix qt)`, `$(brew --prefix qtkeychain)` etc. to `CMAKE_PREFIX_PATH`\n(see below) to make CMake aware of the library locations.\n\n#### Windows\n\nInstall Qt and OpenSSL using The Qt Project official installer; make sure to also tick the CMake box\nin the list of components to install unless you already have it. This will get you both the runtime\nlibraries and the development files, which are also suitable to build libQuotient itself. If you go\nthis way, you'll have to build QtKeychain from the source code.\n\nAlternatively, you can use vcpkg to install Qt, OpenSSL, and QtKeychain. In that case you're\nnot getting Qt Creator, which is a very nice IDE to deal with Qt-based projects; but if you already\nuse VSCode or CLion, you might prefer this route. You can also mix and match, installing Qt Creator\nfrom the official installer and the rest from vcpkg. Mixing Qt from the official installer with Qt\nKeychain from vcpkg may or may not work, depending on the Qt version used to build Qt Keychain.\n\n_If you build from the command line_: the commands in further sections imply that `cmake` is in your\n`PATH`, otherwise you have to prepend those commands with actual paths. It's a good idea to run\nthe `qtenv2.bat` script that can be found in `C:\\Qt\\\u003cQt version\u003e\\\u003ctoolchain\u003e\\bin` (assuming you\ninstalled Qt to `C:\\Qt`). This script adds necessary paths to `PATH`. You might not want to run\nthat script on system startup but it's very handy to setup the environment before building.\n\n_If you use a C++ IDE_: you should be able to configure CMake path and extra options\n(`CMAKE_PREFIX_PATH`, in particular) in its settings. It is recommended NOT to add the path for Qt\n(or any other library) to `PATH` explicitly; use `CMAKE_PREFIX_PATH` instead and leave `PATH`\nunchanged. If your IDE is Qt Creator, you shouldn't need to deal with Qt paths at all, just pick\nthe right kit and go straight to building.\n\nYou will also need libolm. You'll have to build it yourself - there's no binary for Windows that you\ncan download from vcpkg or elsewhere, as of this writing. The source code is available\nat https://gitlab.matrix.org/matrix-org/olm; you can use the same toolchain (CMake+MSVC, e.g.) as\nfor the rest of Quotient.\n\n## Using the library\n\nIf you're just starting a project using libQuotient from scratch, you can copy\n`quotest/CMakeLists.txt` to your project and change `quotest` to your project name. If you already\nhave an existing CMakeLists.txt, you need to insert a `find_package(Quotient REQUIRED)` line to an\nappropriate place in it (use `find_package(Quotient)` if libQuotient is not a hard dependency for\nyou) and then add `Quotient` to your `target_link_libraries()` line.\n\nDynamic linking is only tested on Linux at the moment and is the recommended way of linking with\nlibQuotient on this platform. Static linking is the default on Windows/macOS; feel free to\nexperiment with dynamic linking and provide feedback with your results.\n\n### Documentation\n\nA (very basic) overview can be found\nat [the respective wiki page](https://github.com/quotient-im/libQuotient/wiki/libQuotient-overview).\nThe Doxygen documentation for the library can be found\nat https://quotient-im.github.io/libQuotient/. Further on, looking at the source code\nfor [Quotest](quotest) - the test application that comes with libQuotient - may help you with most\ncommon use cases such as sending messages, uploading files, setting room state etc.\n\nFor examples and patterns of more extensive usage feel free to check out (and copy, with appropriate\nattribution) the source code of [Quaternion](https://github.com/quotient-im/Quaternion)\n(the reference client for libQuotient) or [NeoChat](https://invent.kde.org/network/neochat).\n\n### API/ABI stability\n\nSince Quotient 0.7.2, symbols in all header files of libQuotient *except files ending with `_p.h`\nand namespace `_impl`* are considered public and covered by API/ABI stability guarantees.\nSpecifically, the API and ABI are backwards compatible within every minor version (0.7.x releases)\nwith every next minor version (0.8, e.g.) breaking the compatibility. Once we reach 1.0, this rule\nwill apply to the major version, aligning with [semantic versioning](https://semver.org/) rules.\n`*_p.h` files and namespace `_impl` are not covered by these guarantees; client code should not\ndirectly include these files, nor use symbols defined in these locations.\n\n## Building the library\n\nOn platforms other than Linux you will have to build libQuotient yourself before usage - nobody\npackaged it so far (contributions welcome!). You may also want to build the library on Linux if you\nneed a newer version or snapshot than that coming in your distro.\n\n[The source code is at GitHub](https://github.com/quotient-im/libQuotient). Checking out a certain\ncommit or tag (rather than downloading the archive) along with submodules is strongly recommended.\nIf you want to hack on the library as a part of another project (e.g. you are working on Quaternion\nbut need to do some changes to the library code), it makes sense to make a recursive check out of\nthat project (in this case, Quaternion) and update the library submodule (also recursively) within\nthe appropriate branch. Be mindful of API compatibility restrictions: e.g., each version of\nQuaternion may require the specific branch of libQuotient (`0.8.x`, `0.9.x` etc.).\n\nTags consisting solely of digits and fullstops (e.g., `0.7.0`) correspond to released versions; tags\nending with `-betaN` or `-rcN` mark respective pre-releases. If/when packaging pre-releases, it is\nadvised to replace the leading `-` with `~` (tilde).\n\nlibQuotient is a classic CMake-based project; assuming the dependencies are in place, the following\ncommands issued in the root directory of the project sources:\n\n```shell script\ncmake -B build -S . # [-D\u003ccmake-variable\u003e=\u003cvalue\u003e...], see below\ncmake --build build --target all\n```\n\nwill get you a compiled library in `build` (make sure it exists before running). Any C++ IDE that\nworks with CMake should be able to do the same with minimal configuration effort.\n\nStatic builds are tested on all supported platforms. Dynamic libraries are the recommended\nconfiguratiion on Linux; likely workable on macOS; and untested on Windows (you're welcome to try\nand report on the results).\n\nBefore proceeding, double-check that you have installed development libraries for all prerequisites\nabove. CMake will stop and tell you if something's missing.\n\nThe first CMake invocation above configures the build. You can pass CMake variables (such as\n`-DCMAKE_PREFIX_PATH=\"path1;path2;...\"` and `-DCMAKE_INSTALL_PREFIX=path`) to that invocation\nif needed. [CMake documentation](https://cmake.org/cmake/help/latest/index.html) (pick the CMake\nversion at the top of the page that you use) describes the standard variables coming with CMake.\nOn top of them, Quotient understands:\n\n- `Quotient_INSTALL_TESTS=\u003cON/OFF\u003e`, `ON` by default - install `quotest` along with the library\n  files when `install` target is invoked. `quotest` is a small command-line program that (assuming\n  correct parameters, see `quotest --help`) that tries to connect to a given room as a given user\n  and perform some basic Matrix operations, such as sending messages and small files, redaction,\n  setting room tags etc. This is useful to check the sanity of your library installation.\n- `MATRIX_SPEC_PATH` and `GTAD_PATH` - these two variables are used to point CMake to the directory\n  with the matrix-doc repository containing API files and to a GTAD binary. These two are used to\n  generate C++ files from Matrix Client-Server API description made in OpenAPI notation. This is\n  not needed if you just need to build the library; if you're really into hacking on it, please read\n  the respective sections in [CONTRIBUTING.md](./CONTRIBUTING.md)\n  and [CODE_GENERATION.md](./CODE_GENERATION.md).\n- `QUOTIENT_FORCE_NAMESPACED_INCLUDES=\u003cON/OFF\u003e`, `OFF` by default (note that QUOTIENT is in caps\n  here, unlike options above) - when this option is set to `ON`, CMake skips adding\n  `\u003ctop-level include prefix\u003e/Quotient/` to include paths, thereby forcing the client code to use\n  `#include \u003cQuotient/header.h\u003e` instead of historically accepted `#include \u003cheader.h\u003e`. By default\n  this is set to `OFF` for backwards compatibility; eventually this default may/will change so it is\n  recommended to at least occasionally add `-DQUOTIENT_FORCE_NAMESPACED_INCLUDES=1` to a CMake\n  invocation (or set the variable in your IDE) and make sure your code has prefixed paths.\n\nYou can install the library with CMake:\n```shell script\ncmake --build . --target install\n```\n\nThis will also install cmake package config files; once this is done, you should be able to use\n[`quotest/CMakeLists.txt`](quotest/CMakeLists.txt) to compile quotest with the _installed_ library.\nAs mentioned above, installation of the `quotest` binary along with the rest of the library can be\nskipped by setting `Quotient_INSTALL_TESTS` to `OFF`.\n\n## Troubleshooting\n\n#### Building fails\n\n- If `cmake` fails with\n  ```\n  CMake Warning at CMakeLists.txt:11 (find_package):\n    By not providing \"FindQt6Widgets.cmake\" in CMAKE_MODULE_PATH this project\n    has asked CMake to find a package configuration file provided by\n    \"Qt6Widgets\", but CMake did not find one.\n  ```\n  then you need to set the right `-DCMAKE_PREFIX_PATH` variable, see above.\n\n- If `cmake` fails with a message similar to:\n  ```\n  CMake Error at /usr/lib64/cmake/Qt6Core/Qt6CoreVersionlessTargets.cmake:37 (message):\n    Some (but not all) targets in this export set were already defined.\n\n    Targets Defined: Qt::Core\n\n    Targets not yet defined: Qt::CorePrivate\n  ```\n  then you likely have both Qt 5 and Qt 6 on your system, and your code uses a different major\n  version of Qt than Quotient. Make sure you configure the build so that the same major Qt version\n  is used both by libQuotient and your code.\n\n#### Logging configuration\n\nlibQuotient uses Qt's logging categories to make switching certain types of logging easier. In case\nof troubles at runtime (bugs, crashes) you can increase logging if you add the following to\nthe `QT_LOGGING_RULES` environment variable:\n\n```\nquotient.\u003ccategory\u003e.\u003clevel\u003e=\u003cflag\u003e\n```\n\nwhere\n\n- `\u003ccategory\u003e` is one of: `main`, `jobs`, `jobs.sync`, `jobs.thumbnail`, `events`, `events.state`\n  (covering both the \"usual\" room state and account data), `events.members`, `events.messages`,\n  `events.ephemeral`, `database`, `network`, `e2ee` and `profiler` - you can always find the full\n  list in `Quotient/logging_categories_p.h`;\n- `\u003clevel\u003e` is one of `debug`, `info`, and `warning`;\n- `\u003cflag\u003e` is either `true` or `false`.\n\nYou can use `*` (asterisk) as a wildcard for any part between two dots, and semicolon is used for a\nseparator. Latter statements override former ones, so if you want to switch on all debug logs except\n`jobs` you can set `QT_LOGGING_RULES=\"quotient.*.debug=true;quotient.jobs.debug=false\"`\n\nYou may also want to set `QT_MESSAGE_PATTERN` to make logs slightly more informative\n(see https://doc.qt.io/qt-6/qtlogging.html#qSetMessagePattern for the format description). To give\nan example, here's what one of the library developers uses for `QT_MESSAGE_PATTERN`:\n\n```\n`%{time h:mm:ss.zzz}|%{category}|%{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}|%{message}`\n```\n\n(the scary `%{if}`s are just encoding the logging level into its initial letter).\n\n#### Cache format\n\nIn case of troubles with room state and caching it may be useful to switch cache format from binary\nCBOR to plaintext JSON. To do that, set `libQuotient/cache_type` key in your client's configuration\nfile/registry to `json` (you might need to create the libQuotient group as it's the only recognised\nkey in it so far). This will make cache saving and loading work slightly slower but the cache will\nbe in text JSON files (very long and with no indentation; prepare a good JSON viewer or text editor\nwith JSON formatting capabilities).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquotient-im%2Flibquotient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquotient-im%2Flibquotient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquotient-im%2Flibquotient/lists"}