Extensions¶
A brief overview of extensions can be found in Dependencies. This guide will go in depth on how to write an extension manifest and explain the various properties used.
The first step on writing or loading an extension is to define an extension point or use an existing one. The decision depends on where the extension should be made available.
If for example it is a GTK/QT theme, it’s best to define or use an extension point in the runtime, so that it can be made available for every application utilising said runtime.
If it is a specific tool eg. MPV plugins, which are only used by MPV, it’s best to define or use an extension point in the application. If the tool is generic enough to be used by multiple unrelated applications, the extension point should be defined in the runtime.
To see what are the available extension points in runtime or applications, please see the corresponding flatpak or build manifest.
.Debug, .Locale, .Sources
extensions created by Flatpak builder do
not need to be specified manually. These are automaitcally created and
loaded if installed.
Extension point¶
Now to define an extension point the add-extensions
property can be
used in the manifest.
This is a typical example of an application extension point.
id: org.flatpak.app
runtime: org.gnome.Platform
runtime-version: '45'
sdk: org.gnome.Sdk
command: foo
add-extensions:
org.flatpak.app.plugin:
version: '1.0'
directory: extension_directory
add-ld-path: lib
merge-dirs: plug-ins;help
subdirectories: true
no-autodownload: true
autodelete: true
cleanup-commands:
- mkdir -p ${FLATPAK_DEST}/extension_directory
The details of these properties are documented in the „Extension NAME“ section of Flatpak Command Reference. Some of it is discussed further below.
org.flatpak.app.plugin
is the name of the extension point. Extensions using this extension point must start their ID with the same prefix, for exampleorg.flatpak.app.plugin.foo
.version
is the branch to use when looking for the extension. This is useful to have parallel installations of the same extension in case of an API/ABI break. The value here will be thebranch
used in the extension manifest.If not specified it defaults to the
runtime
branch, that the extension point belongs to. So in the above example it is45
.
Tipp
versions
is same as version
but can be used for specifying
multiple versions. For example, if an extension is published in the
beta
branch and the application is published in the stable
branch, to mount the extension in the application, the extension point
in the application needs to have versions: 'stable;beta'
.
directory
is the path relative to prefix where everything is mounted by flatpak. For a runtime this will be relative to/usr
and for an application it will be relative to/app
. This supports a single value.add-ld-path
adds a path relative to the extension prefix/app/extension_directory/foo/lib
, so that a library residing there can be loaded. This supports a single value. If the$LD_LIBRARY_PATH
environment variable exists, the path here is appended to it, otherwise it is put in a ld config file in/run/flatpak/ld.so.conf.d
.merge-dirs: plug-ins;help
will merge the contents of these directories from multiple extensions using the same extension point. For example, if/app/extension_directory/foo/plug-ins
and/app/extension_directory/bar/plug-ins
exist, they will be merged and made available at/app/extension_directory/plug-ins
. Similarly forhelp
.subdirectories: true
allows to have multiple extensions under the samedirectory
. So two extensions likeorg.flatpak.app.plugin.foo
andorg.flatpak.app.plugin.bar
will be mounted at/app/extension_directory/foo
and/app/extension_directory/bar
.no-autodownload: true
will prevent installing all extensions under this extension point. This is the default.autodelete: true
will remove all extensions under this extension point when the application is removed..Debug
and.Locale
extensions are created withautodelete: true
by default.mkdir -p ${FLATPAK_DEST}/extension_directory
runs during the cleanup phase. It is used to initialise an empty directory for the extension to be loaded. This can also be done usingpost-install
orbuild-commands
in a module. The directory has to end up in the final flatpak. If it is missing, there will be an error while running the application.
There is no extension property to extend the PATH
.
Bemerkung
If the extension point is defined in a base runtime or SDK manifest
add-extensions
will make the extension point land in both
.Sdk
and .Platform
. If the extension point needs to be in only
the child .Sdk
but not in the child .Platform
inherit-sdk-extensions
should be used which is discussed below.
There are other properties like download-if
, enable-if
,
autoprune-unless
etc. These are conditionals which must be true
for the action to happen. These are typically not used in application
extension points.
An example of an extension point defined in runtime is the GL extension
point used in Freedesktop SDK
Freedesktop SDK uses buildstream,
so the format
is different from the usual json
or yaml
format used by Flatpak
manifests.
Extension org.freedesktop.Platform.GL:
# 1.4 is for Nvidia drivers
versions: "%{branch};%{branch-extra};1.4"
version: "1.4"
directory: "%{lib}/GL"
subdirectories: "true"
no-autodownload: "true"
autodelete: "false"
add-ld-path: "lib"
merge-dirs: "%{gl_merge_dirs}"
download-if: "active-gl-driver"
enable-if: "active-gl-driver"
autoprune-unless: active-gl-driver
Most of this is already discussed above. Variables starting with %
are private to the Freedesktop SDK. The version 1.4
is only used
for the proprietary NVIDIA drivers and is static since they have no
API/ABI guarantee.
active-gl-driver
is a flatpak conditional that is true if the name
of the active GL driver matches the extension point basename. The value
can be checked with flatpak --gl-drivers
where host
and
default
are always inserted. The command also looks at the
FLATPAK_GL_DRIVERS
environment variable and
/sys/module/nvidia/version
for nvidia kernel module version.
The default
corresponds to a stable mesa fallback build whereas
host
is for unmaintained Flatpak extensions installed on host.
The resultant extension is called org.freedesktop.Platform.GL.default
and it is downloaded and enabled automatically if active-gl-driver
is true and deleted if only it is false.
The following conditionals are available: download-if, autoprune-unless enable-if.
download-if
and enable-if
supports the following:
active-gl-driver
active-gtk-theme
is true if the host GTK theme viaorg.gnome.desktop.interface
matches the extension basename.have-intel-gpu
is true if the i915 kernel module is loaded.have-kernel-module-{module_name}
is true ifmodule_name
is found in/proc/modules
.on-xdg-desktop-{desktop_name}
is true ifdesktop_name
matches the value ofXDG_CURRENT_DESKTOP
on host.
autoprune-unless
supports only active-gl-driver
. If this evaluates
to false
the extension will be considered unused and removed
automatically when doing flatpak uninstall --unused
.
Loading existing extensions¶
This is a typical example of loading an existing extension in the application. The extension is loaded at runtime and the user needs to have it installed.
The extensions are mounted in alphabetical path order of directory.
Warnung
Some extensions are installed automatically by the runtime based on
certain conditions and these do not need be added to application
manifests. Please see below for the purpose of extensions or
extension points defined in the runtime. Similarly extensions created
by Flatpak builder like .Locale, .Debug
also do not need to be
in application manifest.
org.freedesktop.Platform.ffmpeg-full
is an application extension
(mounted inside /app/extension_directory
) belonging to
org.freedesktop.Platform.
id: org.flatpak.cool-app
runtime: org.kde.Platform
runtime-version: '5.15-23.08'
sdk: org.kde.Sdk
command: foo
add-extensions:
org.freedesktop.Platform.ffmpeg-full:
version: '23.08'
directory: lib/ffmpeg
add-ld-path: .
cleanup-commands:
- mkdir -p ${FLATPAK_DEST}/lib/ffmpeg
org.freedesktop.Sdk.Extension
is an extension point defined in
org.freedesktop.Sdk
.
id: org.flatpak.cool-app
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
command: foo
add-extensions:
org.freedesktop.Sdk.Extension.texlive:
directory: texlive
version: '23.08'
cleanup-commands:
- mkdir -p ${FLATPAK_DEST}/texlive
Note that Compat
or GL32
extensions need to specifically
requested. For providing runtime i386 support or for building i386
modules, please refer to Multiarch support.
There is currently no way to request autodownload of a runtime extension from an application. The extension point in the runtime has to be set to autodownload or the user has to manually install it.
A few related extension properties can be found in application or runtime manifests. These are:
inherit-extensions
can be used to specify an extra set of extension points or extensions from the parent runtime or base that is inherited into the application or the current runtime. This for example, can be used to inherit i386 graphics driversorg.freedesktop.Platform.GL32
or ffmpegorg.freedesktop.Platform.ffmpeg-full
in any application that uses theorg.freedesktop.Platform
runtime or a child runtime of it.
id: org.flatpak.cool-app
runtime: org.gnome.Platform
runtime-version: '45'
sdk: org.gnome.Sdk
base: org.winehq.Wine
base-version: stable-23.08
inherit-extensions:
- org.freedesktop.Platform.GL32
- org.freedesktop.Platform.ffmpeg-full
- org.freedesktop.Platform.ffmpeg_full.i386
- org.winehq.Wine.gecko
command: foo
add-build-extensions
is same asadd-extensions
but the extensions are made available during build. This can be used to add build dependencies that reside in an extension based on the runtime being used.For example an application using the runtime
org.freedesktop.Platform
can useorg.freedesktop.Sdk.Extension.openjdk11
as a build-extension.
id: org.flatpak.cool-app
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
add-build-extensions:
- org.freedesktop.Sdk.Extension.openjdk11
command: foo
sdk-extensions
can be used to install extra extensions having extension point in the parent runtime that has to be installed for the app to build. These are similarly made available during build and not in the final flatapk.
id: org.flatpak.cool-app
runtime: org.freedesktop.Platform
runtime-version: '23.08'
sdk: org.freedesktop.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.golang
command: foo
inherit-sdk-extensions
is used to inherit extension points from the parent SDK into the child SDK. They aren’t inherited into the child runtime. This is usually used when building runtimes or SDKs and not in applications.
inherit-sdk-extensions:
- org.freedesktop.Sdk.Compat.i386
- org.freedesktop.Sdk.Compat.i386.Debug
Bemerkung
There is currently no way to add or inherit extensions per-arch. This means the extension should be available or made available for all the arches used by the application and vice-versa.
This also means that certain extensions like i386 compatibility
extensions like org.freedesktop.Sdk.Compat.i386
should not be
added to modules that build for aarch64
.
Extension manifest¶
Once the extension point is defined, an extension like
org.flatpak.app.plugin.foo
can be created.
This is a typical example of such an extension manifest. The explanation is discussed below.
id: org.flatpak.app.plugin.foo
branch: '1.0'
runtime: org.flatpak.app
runtime-version: 'stable'
sdk: org.gnome.Sdk//45
build-extension: true
separate-locales: false
build-options:
prefix: /app/extension_directory/foo
prepend-path: /app/extension_directory/foo/bin
prepend-pkg-config-path: /app/extension_directory/foo/lib/pkgconfig
prepend-ld-library-path: /app/extension_directory/foo/lib
modules:
- name: foo
buildsystem: simple
build-commands:
- <build commands>
- install -Dm644 org.flatpak.app.plugin.foo.metainfo.xml -t ${FLATPAK_DEST}/share/metainfo
sources:
...
id
must have the correct prefix of the extension point.branch
must be theversion
declared in the extension point.runtime
should be the ID of the parent module where the extension point is defined.runtime-version
is the version of the runtime used by the application. If the runtime is built locally and has not specified thebranch
property in its manifest, it defaults tomaster
, otherwise the value inbranch
is used.Applications on Flathub usually use either
stable
orbeta
.sdk
should be the same SDK used to build the runtime, followed by its version.build-extension: true
instructs flatpak to build an extension.separate-locales: false
disables creating a.Locale
extension for this extension.
Flatpak-builder (>= 1.3.4), can compose metadata for extensions automatically and it is no longer required to manually compose them through commands in the manifest.
In case a manual compose is still required appstream-compose --basename=${FLATPAK_ID} --prefix=${FLATPAK_DEST} --origin=flatpak ${FLATPAK_ID}
for composing with appstream-glib or appstreamcli compose --components=${FLATPAK_ID} --prefix=/ --origin=${FLATPAK_ID} --result-root=${FLATPAK_DEST} --data-dir=${FLATPAK_DEST}/share/app-info/xmls ${FLATPAK_DEST}
for composing with appstreamcli can be used in build-commands
or post-install
along with having appstream-compose: false
in
the top.
Note that the extension prefix or location of pkg-config files will not
be in $PATH
or $PKG_CONFIG_PATH
by default. Any such additional
variables need to be set in build-options
. This is done using
prefix
and prepend-*
properties.
A MetaInfo file should be provided for discoverability in software stores. This is a typical example of an extension MetaInfo file.
<?xml version="1.0" encoding="UTF-8"?>
<component type="addon">
<id>org.flatpak.app.plugin.foo</id>
<extends>org.flatpak.app</extends>
<name>Foo</name>
<summary>A nice summary</summary>
<project_license>GPL-2.0-only</project_license>
<metadata_license>CC0-1.0</metadata_license>
<developer id="com.example">
<name>Bar</name>
</developer>
<url type="homepage">https://flatpak.github.io/</url>
<update_contact>bar_AT_example.org</update_contact>
<releases>
<release version="1.2.0" date="2023-12-03">
<description>
<p>Release description</p>
<ul>
<li>A release note</li>
<li>A bugfix</li>
</ul>
</description>
</release>
<release version="1.0.0" date="2020-04-20"/>
</releases>
</component>
Bundled extensions¶
Extensions can also be built directly from the application manifest
instead of creating a separate extension manifest. The bundle: true
property allows exporting them as separate extensions from the application
manifest. The extension needs to be defined in the application manifest
using add-extensions
. The contents of the directory
will be
exported into that extension.
id: org.flatpak.cool-app
runtime: org.kde.Platform
runtime-version: '6.7'
sdk: org.kde.Sdk
command: foo
add-extensions:
org.flatpak.cool-app.codecs:
directory: extensions/codecs
subdirectories: true
no-autodownload: true
autodelete: true
org.flatpak.cool-app.codecs.codec_pack1:
directory: extensions/codecs/codec-pack1
bundle: true
no-autodownload: true
autodelete: true
org.flatpak.cool-app.codecs.codec_pack2:
directory: extensions/codecs/codec-pack2
bundle: true
no-autodownload: true
autodelete: true
Unmaintained Flatpak extensions¶
Flatpak also supports unmaintained extensions that allows loading
extensions installed externally into /var/lib/flatpak/extension
and
$XDG_DATA_HOME/flatpak/extension
from the host. This can be useful
to expose administrator policies, extensions, graphics drivers etc. to
Flatpak applications. The extension point of unmaintained extensions is
the same as above.
An example of an unmaintained extension can be found in browsers such as Chromium or Firefox on Flathub.
The Firefox snippet translates to:
add-extensions:
org.mozilla.firefox.systemconfig:
directory: etc/firefox
no-autodownload: true
cleanup-commands:
- mkdir -p ${FLATPAK_DEST}/etc/firefox
Now the required policy files for Firefox pref
and policies.json
can be placed in /var/lib/flatpak/extension/org.mozilla.firefox.systemconfig/x86_64/stable/defaults/pref
and /var/lib/flatpak/extension/org.mozilla.firefox.systemconfig/x86_64/stable/policies/policies.json
(or in $XDG_DATA_HOME/flatpak/extension/...
) respectively on host.
The path here is dependent on the extension point. These would appear
under /app/etc/firefox/policies/policies.json
and
/app/etc/firefox/defaults/pref
inside the sandbox. (Firefox supports
reading policies from /app/etc
)
For details on Chromium, please look at the readme.
Creating an unmaintained Gtk theme extension¶
The following script can be used to create an unmaintained extension for the host’s Gtk 3 theme. This is useful when the theme is not packaged as an extension in a remote.
The script expects the theme to be installed in /usr/share/themes
or $XDG_DATA_HOME/themes
.
#!/bin/sh
DEFAULT_ARCH=$(flatpak --default-arch)
THEME_NAME=$(gsettings get org.gnome.desktop.interface gtk-theme | tr -d "'")
XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
THEME_EXTENSION_DIR=$XDG_DATA_HOME/flatpak/extension/org.gtk.Gtk3theme.$THEME_NAME/$DEFAULT_ARCH/3.22
mkdir -p "$THEME_EXTENSION_DIR"
if [ -d "/usr/share/themes/$THEME_NAME/gtk-3.0/" ]; then
cp -r /usr/share/themes/"$THEME_NAME"/gtk-3.0/* "$THEME_EXTENSION_DIR"
elif [ -d "$XDG_DATA_HOME/themes/$THEME_NAME/gtk-3.0/" ]; then
cp -r "$XDG_DATA_HOME"/themes/"$THEME_NAME"/gtk-3.0/* "$THEME_EXTENSION_DIR"
else
echo "Could not find theme files"
rmdir --ignore-fail-on-non-empty "$THEME_EXTENSION_DIR"
exit 1
fi
Extensions or extension points defined by runtime¶
The following extensions and extension points are defined in the Freedesktop runtime/SDK or are shipped along with it. Most of these are inherited by the GNOME and KDE runtimes as well. These may change over time, please check the respective project.
These are common to the Freedesktop SDK and runtime.
org.freedesktop.Platform.GL - Extension for graphics drivers managed by the runtime and installed or removed automatically. The default has two branches
${RUNTIME_VERSION}
and${RUNTIME_VERSION}-extra
, the latter containing support for patented codecs.org.freedesktop.Platform.GL.Debug - Debug extension point for org.freedesktop.Platform.GL, managed by the runtime but the user needs to explicitly install
org.freedesktop.Platform.GL.Debug.default//${RUNTIME_VERSION}
andorg.freedesktop.Platform.GL.Debug.default//${RUNTIME_VERSION}-extra
to have the debug symbols available.
The following extensions utilise the above two extension points:
org.freedesktop.Platform.GL.default//${RUNTIME_VERSION}
org.freedesktop.Platform.GL.default//${RUNTIME_VERSION}-extra
org.freedesktop.Platform.GL.Debug.default//${RUNTIME_VERSION}
org.freedesktop.Platform.GL.Debug.default//${RUNTIME_VERSION}-extra
org.freedesktop.Platform.GL32.default//${RUNTIME_VERSION}
org.freedesktop.Platform.GL32.default//${RUNTIME_VERSION}-extra
org.freedesktop.Platform.GL32.Debug.default//${RUNTIME_VERSION}
org.freedesktop.Platform.GL32.Debug.default//${RUNTIME_VERSION}-extra
org.freedesktop.Platform.GL.nvidia-${DRIVER_VERSION}
org.freedesktop.Platform.GL32.nvidia-${DRIVER_VERSION}
org.freedesktop.Platform.VulkanLayer - Extension point for Vulkan layers. Developers can provide extensions using this extension point and the user needs to install those extensions to have them available.
org.freedesktop.Platform.GStreamer - Extension point for GStreamer plugins. Developers can provide extensions using this extension point and the user needs to install those extensions to have them available.
org.freedesktop.Platform.Icontheme - Extension point for icon themes. Developers can provide extensions using this extension point and the user needs to install those extensions to have them available.
org.gtk.Gtk3theme - Extension point for Gtk3 themes. Extensions under this extension point are automatically installed by Flatpak if an extension matching the host theme is available. Developers can provide extensions using this extension point.
org.freedesktop.Platform.VAAPI.Intel - Extension providing Intel VAAPI media drivers. This is automatically installed if the user has an Intel GPU.
This has a compat i386 extension
org.freedesktop.Platform.VAAPI.Intel.i386
.org.freedesktop.Platform.openh264 - Extension providing OpenH264, automatically installed by the runtime.
org.freedesktop.Platform.ffmpeg - Extension providing ffmpeg with support for patented codecs. This needs to explicitly added to the manifest using
add-extensions
by the developer, so that it becomes available when the user installs it.This has a compat i386 extension
org.freedesktop.Platform.ffmpeg_full.i386
.
These are only in Freedesktop SDK.
org.freedesktop.Sdk.Extension - Extension point for SDK extensions like extra toolchains (eg. LLVM), compilers and language specific tools to aid building applications or provide language support for development tools such as IDEs.
The application developer needs to explicitly add these extensions in the manifest by using
sdk-extensions
when building an app.
Extensions marked as Compat
in the name or GL32
provide compat
support for extra architectures and needs to explicitly requested.
Additionally all SDKs provide a .Docs
extension for documentation.