From 3987c66d76d534bae804555ab1b361e86623c3bf Mon Sep 17 00:00:00 2001
From: Ludovico de Nittis <ludovico.denittis@collabora.com>
Date: Tue, 13 Apr 2021 11:23:21 +0200
Subject: [PATCH] runtime: Correctly handle data dirs when in a Flatpak
 environment

When we are in a Flatpak environment there are two issue:
- It's common to have multiple data directory, usually one for every
multiarch
- If we bind the data directory in "/usr/share/${dir_basename}" there is
no guarantee that it will be in the library search path

For this reason we avoid raising a warning if we have multiple data
directory and also we bind them preserving their original path.

Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
---
 pressure-vessel/runtime.c | 45 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c
index 4692ec55e..d7519f979 100644
--- a/pressure-vessel/runtime.c
+++ b/pressure-vessel/runtime.c
@@ -3788,6 +3788,51 @@ pv_runtime_finish_lib_data (PvRuntime *self,
                  lib_name, dir_basename);
     }
 
+  if (self->is_flatpak_env)
+    {
+      /* In a Flatpak environment is normal to have more than one data
+       * directory from provider, e.g. one for every multiarch */
+      GHashTableIter iter;
+      const gchar *data_path = NULL;
+
+      g_hash_table_iter_init (&iter, data_in_provider);
+      while (g_hash_table_iter_next (&iter, (gpointer *)&data_path, NULL))
+        {
+          /* If we are in a Flatpak environment we bind the lib data in the
+           * same path as the one in the provider because
+           * /usr/share/${dir_basename} is not expected to be in the library
+           * search path. */
+          if (!pv_runtime_take_from_provider (self, bwrap,
+                                              data_path, data_path,
+                                              TAKE_FROM_PROVIDER_FLAGS_IF_DIR,
+                                              error))
+            return FALSE;
+
+          if (g_str_has_prefix (data_path, "/app/lib/"))
+            {
+              /* In a freedesktop.org runtime, for some multiarch, there is
+               * a symlink /usr/lib/${arch} that points to /app/lib/${arch}
+               * https://gitlab.com/freedesktop-sdk/freedesktop-sdk/-/blob/70cb5835/elements/multiarch/multiarch-platform.bst#L24
+               * If we have a path in /app/lib/ here, we also try to
+               * replicate the symlink in /usr/lib/ */
+              g_autofree gchar *path_in_usr = NULL;
+              path_in_usr = g_build_filename ("/usr",
+                                              data_path + strlen ("/app"),
+                                              NULL);
+              if (_srt_fstatat_is_same_file (-1, data_path, -1, path_in_usr))
+                {
+                  if (!pv_runtime_take_from_provider (self, bwrap,
+                                                      data_path, path_in_usr,
+                                                      TAKE_FROM_PROVIDER_FLAGS_IF_DIR,
+                                                      error))
+                    return FALSE;
+                }
+            }
+        }
+
+      return TRUE;
+    }
+
   if (g_hash_table_size (data_in_provider) == 1)
     {
       best_data_in_provider = g_strdup (
-- 
GitLab