Поддержка MultiArch

Flatpak поддерживает multiarch/multilib но по умолчанию она не включена, и для ее включения требуются некоторые дополнительные действия. В этом разделе рассказывается о включении multiarch/multilib в вашем пакете приложений.

Запуск 32-битных программ

Чтобы настроить среду выполнения для 32-битных исполняемых файлов, сначала вам нужно разрешить это в finish-args:

finish-args:
  - --allow=multiarch

Этого достаточно для статических двоичных файлов, но большинство реальных программ GNU / Linux связаны динамически. Им для работы нужны общие библиотеки.

Freedesktop.org и GNOME SDKs предоставляют специальное расширение flatpak с набором библиотек для соответствующей архитектуры. Это расширение можно подключить к приложению с другой архитектурой. Чтобы включить расширение для вашего приложения, определите для него точку расширения в манифесте приложения:

add-extensions:
  org.freedesktop.Platform.Compat.i386:
    directory: lib/i386-linux-gnu
    version: '23.08'

  # This is not strictly required, but needed for debugging 32-bit programs
  org.freedesktop.Platform.Compat.i386.Debug:
    directory: lib/debug/lib/i386-linux-gnu
    version: '23.08'
    no-autodownload: true

Для среды выполнения GNOME используйте вместо этого org.gnome.Platform.Compat.i386.

Обратите внимание, что это расширение version должно соответствовать runtime-version приложения.

Если 32-разрядные программы используют ускорение графического процессора или имеют графический интерфейс в целом, вам также понадобятся 32-разрядные драйверы GL. Добавьте для него точку расширения:

add-extensions:
  org.freedesktop.Platform.GL32:
    directory: lib/i386-linux-gnu/GL
    version: '1.4'
    versions: 23.08;1.4
    subdirectories: true
    no-autodownload: true
    autodelete: false
    add-ld-path: lib
    merge-dirs: vulkan/icd.d;glvnd/egl_vendor.d;OpenCL/vendors;lib/dri;lib/d3d;vulkan/explicit_layer.d;vulkan/implicit_layer.d
    download-if: active-gl-driver
    enable-if: active-gl-driver

Обратите внимание, что свойство «versions» здесь должно содержать как «1.4», так и то же значение, что и в «runtime-version».

Обязательно создайте каталоги, в которых будут монтироваться расширения (точки монтирования указаны в свойствах «каталога» и относятся к точке монтирования пакета приложений, то есть в /app/). Это можно сделать на этапе сборки.

Наконец, вам нужно сделать так, чтобы загрузчик динамических библиотек знал пути к 32-битным библиотекам. Для этого вы можете установить файл /app/etc/ld.so.conf с таким содержимым:

/app/lib32
/app/lib/i386-linux-gnu

Здесь /app/lib32 - это каталог, в который вы устанавливаете дополнительные 32-битные библиотеки, если таковые имеются.

Вы можете комбинировать выше два шага в специальном модуле, например.

modules:
  - name: bundle-setup
    buildsystem: simple
    build-commands:
      - mkdir -p /app/lib/i386-linux-gnu
      - mkdir -p /app/lib/debug/lib/i386-linux-gnu
      - mkdir -p /app/lib/i386-linux-gnu/GL
      - install -Dm644 ld.so.conf /app/etc/ld.so.conf
    sources:
      - type: inline
        dest-filename: ld.so.conf
        contents: |
          /app/lib32
          /app/lib/i386-linux-gnu

Сборка 32-битных модулей

В приведенном выше разделе описано, как запускать уже созданные 32-разрядные программы. В этом разделе будет описан процесс самостоятельной сборки 32-разрядных компонентов для их доставки вместе с приложением. Предполагается, что вы уже знакомы с собранными (одноарочными) flatpaks. В противном случае сначала обратитесь к руководству Flatpak Builder.

Прежде всего, вам нужно включить некоторые расширения SDK во время сборки:

sdk-extensions:
  - org.freedesktop.Sdk.Compat.i386
  - org.freedesktop.Sdk.Extension.toolchain-i386

Первая - это 32-битная часть SDK, содержащая 32-битные библиотеки и файлы разработки.

Второй - кросс-компилятор. Обычно для сборок с несколькими библиотеками используется gcc -m32 , но пакет SDK flatpak поставляется с gcc без поддержки нескольких библиотек. Таким образом, вам понадобится кросс-компилятор для сборки x86 на x86_64 так же, как он понадобится для любой зарубежной архитектуры, такой как aarch64.

Чтобы построить 32-битный модуль, необходимо переопределить некоторые глобальные параметры сборки. Примеры здесь предполагают, что 32-битные библиотеки установлены в каталог /app/lib32:

modules:
  - name: some-lib-32bit
    build-options: &compat-i386-build-options
      # Make sure 32-bit dependencies are first on pkg-config search path
      prepend-pkg-config-path: /app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig
      # Add /app/lib32 to linker search path for modules without pkg-config
      ldflags: -L/app/lib32
      # Add the cross-compiler to PATH
      prepend-path: /usr/lib/sdk/toolchain-i386/bin
      # Tell the build systems to use the cross-compiler for compilation
      env:
        CC: i686-unknown-linux-gnu-gcc
        CXX: i686-unknown-linux-gnu-g++
      # Tell the build systems to install libraries to /app/lib32
      libdir: /app/lib32

Эти параметры сборки необходимо установить для каждого 32-битного модуля. Если манифест вашего приложения имеет формат YAML, привязки YAML могут пригодиться и избавить вас от копирования-вставки того же фрагмента. Вы можете определить 32-битный объект build-options где-нибудь в манифесте, добавить к нему привязку, а затем указать каждому 32-битному модулю build-options на эту привязку:

x-compat-i386-build-options: &compat-i386-build-options
  prepend-pkg-config-path: /app/lib32/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig
  ldflags: -L/app/lib32
  prepend-path: /usr/lib/sdk/toolchain-i386/bin
  env:
    CC: i686-unknown-linux-gnu-gcc
    CXX: i686-unknown-linux-gnu-g++
  libdir: /app/lib32

modules:
  - name: some-lib-32bit
    build-options: *compat-i386-build-options

  - name: some-other-lib-32bit
    build-options: *compat-i386-build-options

Конечно, для того, чтобы использовать созданные вами 32-битные модули, вам также потребуются все те же настройки, что и в предыдущем разделе.