Digging further into Flatpak with NVIDIA
As you may know the development environment used by WebKitGTK and WPE is based on Flatpak. I feel hacking software within Flatpak like teleoperating a rover in Mars, since I have to go through Flatpak commands to execute the commands I want to execute. The learning curve is steeper in exchange of a common development environment.I started to work on another project where is required to use an NVIDIA GPU, without stopping to work on WebKitGTK/WPE. So I needed to use the card within Flatpak, and it’s well known that, currently, that setup is not available out-of-the-box. Furthermore, I have to use a very specific version of the graphics card drive for Vulkan.
This is the story of how I make it work.
My main reference is, of course, the blog post of my colleague TingPing: Using host Nvidia driver with Flatpak, besides Flatpak for NVIDIA GL runtime platform.
As TingPing explained, Flatpak does not use host libraries, that’s why it might need runtimes and extensions for specific hardware setups, with the libraries for user-space, such as NVIDIA GL platform runtime. And it must have the same version as the one running in kernel.
NVIDIA GL platform
extension is a
small project which generates Flatpak’s runtimes for every public NVIDIA
driver. The interesting part is that those runtimes are not created in building
time, but at install-time. When the user installs the runtime, a driver blob is
downloaded from NVIDIA servers (see --extra-data
in flatpak build-finish
for
reference), and a small program is executed, which extracts the embedded tarball
in the blob, and from it, it extracts the required libraries. In a few words,
initially, the runtime is composed only by a definition of the file to download,
and the small program that populates the Flatpak’s file system at install-time.
The trick here, that took me a lot to be aware, is that this small program has to be statically compiled, since it has be executed regardless the available runtime.
This little program uses libarchive to extract
the libraries from NVIDIA’s tarball, but libarchive
is not available
statically in any Flatpak’s SDK. Furthermore, our use of libarchive
will
depend on libz
and liblzma
, both statically compile as well. Gladly, there’s
only one, very old version, obsolete, of freedesktop SDK, which offers static
versions of libz
and liblzma
: 1.6. And that’s why
org.freedesktop.Platform.GL.nvidia demands that specific old version of the
SDK. Then, the manifest of the extension contains basically the static
compilation of libarchive
and the static compilation of the next-to-be
apply_extra
.
Update: There’s a merge request to use current freedesktop SDK
21.08,
which, basically, builds statically libz
and liblzma
, besides libarchive
.
I needed to modify org.freedesktop.Platform.GL.nvidia
sources a bit, since it,
by default, consist in a big loop of downloading, hashing, templating a json
manifest, and building, for every supported driver. But, as my case is just one
custom driver, I don’t want to waste time in that loop. The hack to achieve it
is fairly simple:
diff --git a/versions.sh b/versions.sh
index 8b72664..86686c0 100755
--- a/versions.sh
+++ b/versions.sh
@@ -15,4 +15,5 @@ TESLA_VERSIONS="450.142.00 450.119.04 450.51.06 450.51.05 440.118.02 440.95.01 4
# Probably never: https://ahayzen.com/direct/flathub_downloads_only_nvidia_runtimes.txt
UNSUPPORTED_VERSIONS="390.147 390.144 390.143 390.141 390.138 390.132 390.129 390.116 390.87 390.77 390.67 390.59 390.48 390.42 390.25 390.12 387.34 387.22 387.12 384.130 384.111 384.98 384.90 384.69 384.59 384.47 381.22 381.09 378.13 375.82 375.66 375.39 375.26 370.28 367.57"
-DRIVER_VERSIONS="$BETA_VERSIONS $VULKAN_VERSIONS $NEW_FEATURE_VERSIONS $PRODUCTION_VERSIONS $LEGACY_VERSIONS $TESLA_VERSIONS $UNSUPPORTED_VERSIONS"
+#DRIVER_VERSIONS="$BETA_VERSIONS $VULKAN_VERSIONS $NEW_FEATURE_VERSIONS $PRODUCTION_VERSIONS $LEGACY_VERSIONS $TESLA_VERSIONS $UNSUPPORTED_VERSIONS"
+DRIVER_VERSIONS="470.XX.XX"
But in order to make it work, it needs a file in data/
directory with the
specification of the file to download, with the format:
NAME:SHA256:DOWNLOAD-SIZE:INSTALL-SIZE:URL
.
--- /dev/null
+++ b/data/nvidia-470.XX.XX-x86_64.data
@@ -0,0 +1 @@
+:34...checksum-sha264...:123456789::http://compu.home.arpa/NVIDIA/NVIDIA-Linux-x86_64-470.XX.XX.run
The last parameter is the URL where the driver shall be downloaded. In my case is a local server to ease the testing.
Long story short, the command to execute are:
To setup the building environment:
flatpak install org.freedesktop.Sdk//1.6 org.freedesktop.Platform//1.6
To build the Flatpak repository and package:
make
The command will output a repo
directory in the current one. There’s where the
generated Flatpak package is stored.
To install the local repository and the extension:
flatpak --user remote-add --no-gpg-verify nvidia-local repo
flatpak -v install nvidia-local org.freedesktop.Platform.GL.nvidia-470-XX-XX
To remove the obsolete SDK and platform once built:
flatpak uninstall org.freedesktop.Sdk//1.6 org.freedesktop.Platform//1.6
To remove the local repository and the extension if something went wrong:
flatpak -v uninstall org.freedesktop.Platform.GL.nvidia-470-62-15
flatpak --user remote-delete nvidia-local
One way to verify if the libraries are installed correctly and if they match
with the driver running in the kernel’s host, is to install and run
GreenWithEnvy
:
flatpak install com.leinardi.gwe
flatpak run com.leinardi.gwe
If you want to install the driver in your WebKit development environment, you
just need to set the environment variable FLATPAK_USER_DIR
:
FLATPAK_USER_DIR=~/WebKit/WebKitBuild/UserFlatpak flatpak --user remote-add --no-gpg-verify nvidia-local repo
FLATPAK_USER_DIR=~/WebKit/WebKitBuild/UserFlatpak flatpak -v install nvidia-local org.freedesktop.Platform.GL.nvidia-470-XX-XX
- Previous: GstVA in GStreamer 1.20
- Next: From gst-build to local-projects