Suporte a multiarquitetura¶
Flatpak tem suporte multiarch/multilib, mas não está habilitado por padrão e requer algumas etapas adicionais para habilitá-lo. Esta seção abrange a ativação de multiarch/multilib em seu pacote de aplicativos.
Executando programas de 32 bits¶
Para configurar o ambiente de runtime para executáveis de 32 bits, primeiro você precisa permitir isso em finish-args
:
finish-args:
- --allow=multiarch
Isso é suficiente para binários estáticos, mas a maioria dos programas GNU/Linux do mundo real são vinculados dinamicamente. Esses precisam de algumas bibliotecas compartilhadas para funcionar.
Os SDKs do Freedesktop.org e do GNOME fornecem uma extensão flatpak especial com um conjunto de bibliotecas para a arquitetura correspondente. Esta extensão pode ser anexada a um aplicativo de arquitetura diferente. Para habilitar a extensão para seu aplicativo, defina um ponto de extensão para ela no manifesto do aplicativo:
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
Para o tempo de execução do GNOME, use org.gnome.Platform.Compat.i386
em vez disso.
Note que esta extensão version
deve corresponder à runtime-version
do aplicativo.
Se os programas de 32 bits fizerem uso de aceleração de GPU ou tiverem alguma interface gráfica em geral, você também precisará de drivers GL de 32 bits. Adicione um ponto de extensão para ele:
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
Observe que a propriedade versions
aqui deve conter 1.4
e o mesmo valor que em runtime-version
.
Certifique-se de criar diretórios onde as extensões serão montadas (os pontos de montagem são especificados nas propriedades do directory
e são relativos ao ponto de montagem do pacote de aplicativos, ou seja, para /app/
). Isso pode ser feito na fase de compilação.
Finalmente, você precisa fazer com que o carregador dinâmico de bibliotecas conheça os caminhos para bibliotecas de 32 bits. Para fazer isso, você pode instalar um arquivo /app/etc/ld.so.conf
com conteúdo como este:
/app/lib32
/app/lib/i386-linux-gnu
Aqui /app/lib32
é o diretório onde você instala bibliotecas adicionais de 32 bits, se houver.
Você pode combinar as duas etapas acima em um módulo especial, por exemplo.
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
Compilando módulos de 32 bits¶
A seção acima descreve como executar programas de 32 bits já compilados. Esta seção descreverá o processo de construção de componentes de 32 bits por conta própria para enviá-los com o aplicativo. Ele pressupõe que você já esteja familiarizado com a construção de flatpaks (arco único). Caso contrário, consulte primeiro o guia Flatpak Builder.
Em primeiro lugar, você precisará habilitar algumas extensões do SDK no momento da compilação:
sdk-extensions:
- org.freedesktop.Sdk.Compat.i386
- org.freedesktop.Sdk.Extension.toolchain-i386
A primeira é a parte de 32 bits do SDK, contendo bibliotecas de 32 bits e arquivos de desenvolvimento.
O segundo é um compilador cruzado. Normalmente gcc -m32
é usado para compilações multilib, mas o SDK flatpak vem com gcc sem suporte a multilib. Assim, você precisará de um compilador cruzado para compilar x86 em x86_64 assim como precisaria para qualquer arquitetura estrangeira como aarch64.
Para compilar um módulo de 32 bits, algumas opções globais de compilação precisam ser substituídas. Os exemplos aqui assumem que as bibliotecas de 32 bits estão instaladas no diretório /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
Essas build-options
precisam ser definidas para cada módulo de 32 bits. Se o manifesto do seu aplicativo estiver no formato YAML, as âncoras YAML podem ser úteis e evitar que você copie e cole o mesmo trecho de código. Você pode definir o objeto build-options
de 32 bits em algum lugar no manifesto, adicionar uma âncora a ele e então apontar cada build-options
de cada módulo de 32 bits para essa âncora:
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
É claro que, para realmente usar os módulos de 32 bits que você construiu, você também precisará da mesma configuração da seção anterior.