diff --git a/docs/dependencies.rst b/docs/dependencies.rst index 541de80d..7174acf2 100644 --- a/docs/dependencies.rst +++ b/docs/dependencies.rst @@ -98,84 +98,48 @@ Extensions Runtimes and applications can define extension points which allow optional additional runtimes to be mounted at a specified location inside the sandbox -when they are present on the system. Typical uses for extension points include +when they are present on the system. Typical uses for extensions include translations for applications, debuginfo for sdks, or adding more functionality to the application. Some software refers to these extensions as "Add-ons". -By convention, extension points follow the application ID of the application in -question, followed by a generic term the extension is conveying. For example, -OBS Studio supports plugins to extend the application's functionality. -OBS Studio Flatpak has an extension point that goes by -``com.obsproject.Studio.Plugin``, as "Plugin" conveys the extension type. +For an extension to be loaded in the application or runtime, an extension +point first needs to be defined in the application or runtime in +question. -We can use the ``add-extensions`` property in the manifest to specify where -and how should extensions be installed: +By convention, extension points follow the ID of the application or +runtime in question, followed by a generic term for the extension. +For example, the OBS Studio flatpak may define an extension point +``com.obsproject.Studio.Plugin``, where "Plugin" is the generic term +prefixed by the application ID. -.. code-block:: yaml +To see available extension points, it's best to look at the application +or runtime manifest. - add-extensions: - org.flatpak.App.ExampleExtension: - directory: my-dir # Installs extensions in $FLATPAK_DEST/my-dir - version: '1.0' # Branch version of extension - versions: 21.08;22.08beta # Supported extension versions - subdirectories: true # Creates $FLATPAK_DEST/my-dir/ExampleExtension directory - no-autodownload: true # Don't automatically download directories - autodelete: false # Don't autodelete - add-ld-path: lib # Add $FLATPAK_DEST/lib to library path - merge-dirs: my-dir1;my-dir2;my-dir3 # Merge these directories - download-if: conditional # Download only if 'conditional' exists - enable-if: conditional # Enable extension only if 'conditional' exists - subdirectory-suffix - locale-subset +Any extension now choosing to be loaded inside the OBS Studio flatpak +must prefix their ID by ``com.obsproject.Studio.Plugin`` for example +``com.obsproject.Studio.Plugin.Gstreamer``. -Debug Extensions -```````````````` +Some extension names having special significance are discussed below. -Debug extensions (stylized as ``.Debug``) are used for debugging purposes. -To get a list of debug extensions, please visit -:doc:`available-runtimes?highlight=.Debug`. +- ``.Debug`` is used for Debug extensions by applications, runtimes and + SDKs. They are used for debugging purposes. Every application or runtime + built with ``flatpak-builder`` produces a ``.Debug`` extension unless + specifically disabled in the manifest. -Compatibility Debug Extensions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + A ``.Debug`` extension will be needed when generating useful + backtraces. This is explained more in :doc:`debugging`. -DESCRIPTION NEEDED +- ``.Locale`` is used for Locale extensions by applications or runtimes. + They add support for more languages to the parent application or runtime. + These are usually partially downloaded by ``flatpak`` based on the + configured system locale. Every application or runtime built with + ``flatpak-builder`` produces a ``.Locale`` extension unless specifically + disabled in the manifest. -.. code-block:: yaml +- ``.Sources`` is used for Sources extension by application or runtime. + They are used to bundle sources of the modules used in the application + or runtime in question. ``flatpak-builder`` will produce a ``.Sources`` + extension prefixed by ID when ``--bundle-sources`` is used. - add-extensions: - $FLATPAK_ID.Compat.{architecture}: - directory: lib/{architecture}-linux-gnu - version: '21.08' - - $FLATPAK_ID.Compat.{architecture}.Debug: - directory: lib/debug/lib/{architecture}-linux-gnu - version: '21.08' - no-autodownload: true - -SDK Debug Extensions -^^^^^^^^^^^^^^^^^^^^ - -DESCRIPTION NEEDED - -.. code-block:: yaml - - sdk-extensions: - $FLATPAK_ID.Sdk.Debug - - -DESCRIPTION AND EXAMPLE NEEDED - -Locale Extensions -````````````````` - -Locale extensions (stylized as ``.Locale``) are used to add support for -more languages. To get a list of locale extensions, please visit -:doc:`available-runtimes?highlight=.Locale`. - -.. code-block:: yaml - - add-extensions: - $FLATPAK_ID.Locale - - sdk-extensions: - $FLATPAK_ID.Sdk.Locale +Please visit :doc:`extension` for a guide on how to create +extension points and extensions. diff --git a/docs/extension.rst b/docs/extension.rst new file mode 100644 index 00000000..efcc435d --- /dev/null +++ b/docs/extension.rst @@ -0,0 +1,420 @@ +Extensions +========== + +A brief overview of extensions can be found in :doc:`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. + +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. + +.. code-block:: yaml + + 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 :doc:`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 example ``org.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. This will be the ``branch`` used in the + extension manifest. + + If not specified it defaults to application or runtime branch of the + extension point. + +.. tip:: + ``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. + +- ``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 + for ``help``. + +- ``subdirectories: true`` allows to have multiple extensions under the + same ``directory``. So two extensions like + ``org.flatpak.app.plugin.foo`` and ``org.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. + +- ``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 using ``post-install`` or ``build-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``. + +.. note:: + + 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. + +.. code-block:: yaml + + 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. + +For a list of this conditionals, please see ``man flatpak-metadata``. + +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. +ld-path prepended before ``/app/lib`` for app extensions and appended +after ``/app/lib`` in case of runtime extensions. + +``org.freedesktop.Platform.ffmpeg-full`` is an extension of the runtime +``org.freedesktop.Platform`` and ``org.kde.Platform`` is a child runtime +of ``org.freedesktop.Platform``. + +.. code-block:: yaml + + 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 of the SDK +``org.freedesktop.Sdk``. + +.. code-block:: yaml + + 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: '22.08' + cleanup-commands: + - mkdir -p ${FLATPAK_DEST}/texlive + +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 extensions + having an extension point in the parent runtime or base that is inherited + in the application. This for example, can be used to inherit i386 + graphics drivers ``org.freedesktop.Platform.GL32`` or ffmpeg + ``org.freedesktop.Platform.ffmpeg-full`` in any application that + uses the ``org.freedesktop.Platform`` runtime or a child runtime of it. + +.. code-block:: yaml + + 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 as ``add-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 use + ``org.freedesktop.Sdk.Extension.openjdk11`` as a build-extension. + +.. code-block:: yaml + + 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. + +.. code-block:: yaml + + 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. + +.. code-block:: yaml + + inherit-sdk-extensions: + - org.freedesktop.Sdk.Compat.i386 + - org.freedesktop.Sdk.Compat.i386.Debug + +.. note:: + + 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. + +.. code-block:: yaml + + 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 + appstream-compose: 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: + - + - install -Dm644 org.flatpak.app.plugin.foo.metainfo.xml -t ${FLATPAK_DEST}/share/metainfo + - appstream-compose --basename=${FLATPAK_ID} --prefix=${FLATPAK_DEST} --origin=flatpak ${FLATPAK_ID} + sources: + ... + +- ``id`` must have the correct prefix of the extension point. +- ``branch`` refers to the extension version. +- ``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 the + ``branch`` property in its manifest, it defaults to ``master``, + otherwise the value in ``branch`` is used. + + Applications on Flathub usually use either ``stable`` or ``beta``. +- ``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. +- ``appstream-compose: false`` disables running ``appstream-compose``. + This is run manually in the build or cleanup stage. + +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. + +An appdata file should be provided for discoverability in software +stores. This is a typical example of an extension appdata. + +.. code-block:: xml + + + + org.flatpak.app.plugin.foo + org.flatpak.app + Foo + A nice summary + GPL-2.0 + CC0-1.0 + Bar + https://flatpak.github.io/ + bar_AT_example.org + + + +
    +
  • A release note
  • +
  • A bugfix
  • +
+
+ +
+
+ +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: + +.. code-block:: yaml + + 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 `_. diff --git a/docs/guides.rst b/docs/guides.rst index 11775db4..41125021 100644 --- a/docs/guides.rst +++ b/docs/guides.rst @@ -13,3 +13,4 @@ standard guidance provided elsewhere in the Flatpak documentation. electron qt multiarch + extension