[gnome-builder] flatpak: Properly build, install, and run flatpak apps



commit 03109bc3d5ec75ca3ce7315d41c20ad5f10f9e9e
Author: Matthew Leeds <mleeds redhat com>
Date:   Mon Nov 14 23:28:05 2016 -0800

    flatpak: Properly build, install, and run flatpak apps
    
    This commit teaches the flatpak runtime how to use a number of flatpak
    commands to build, install, and run applications.
    
    1. In the prebuild worker, "flatpak remote-add" is used to ensure a repo exists
    where we can export the build, and either "flatpak-builder" or "flatpak build-init"
    is used to build dependencies and initialize the build directory (depending on
    whether a manifest was found in the source tree).
    2. In the create_launcher function, code was added to use the options and
    environment variables specified in the manifest to form a "flatpak build ..."
    command.
    3. In the postinstall worker, multiple subprocesses are created to run
    "flatpak build-finish" to finish the build directory, "flatpak build-export"
    to export the build to the repo created earlier, "flatpak uninstall" in case
    the app was previously installed, and "flatpak install" to install it on the
    host system.
    4. Finally, a create_runner function was added that builds a "flatpak run ..."
    command to run the app with access to the display even if that wasn't
    granted in the build-finish step.
    
    In this way we can exert more control over the build process than if we
    let flatpak-builder do all the work for us.
    
    NOTE: Currently this process only works if a manifest is present (so we
    know the app id) and at least one git commit has occurred (so
    flatpak-builder doesn't complain).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773764

 plugins/flatpak/gbp-flatpak-runtime.c |  500 +++++++++++++++++++++++++++++++--
 1 files changed, 472 insertions(+), 28 deletions(-)
---
diff --git a/plugins/flatpak/gbp-flatpak-runtime.c b/plugins/flatpak/gbp-flatpak-runtime.c
index 75dc51e..543aa9b 100644
--- a/plugins/flatpak/gbp-flatpak-runtime.c
+++ b/plugins/flatpak/gbp-flatpak-runtime.c
@@ -18,8 +18,11 @@
 
 #define G_LOG_DOMAIN "gbp-flatpak-runtime"
 
+#include <json-glib/json-glib.h>
+
 #include "gbp-flatpak-runtime.h"
 #include "gbp-flatpak-subprocess-launcher.h"
+#include "gbp-flatpak-runner.h"
 
 struct _GbpFlatpakRuntime
 {
@@ -97,11 +100,19 @@ gbp_flatpak_runtime_prebuild_worker (GTask        *task,
                                      GCancellable *cancellable)
 {
   GbpFlatpakRuntime *self = source_object;
+  IdeContext *context;
+  IdeConfigurationManager *config_manager;
+  IdeConfiguration *configuration;
+  const gchar *app_id = NULL;
+  const gchar *flatpak_repo_name = NULL;
   g_autofree gchar *build_path = NULL;
+  g_autofree gchar *flatpak_repo_path = NULL;
   g_autoptr(GFile) build_dir = NULL;
+  g_autoptr(GFile) flatpak_repo_dir = NULL;
   g_autoptr(IdeSubprocessLauncher) launcher = NULL;
-  g_autoptr(IdeSubprocess) subprocess = NULL;
-  g_autoptr(GFile) parent = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher2 = NULL;
+  g_autoptr(IdeSubprocess) process = NULL;
+  g_autoptr(IdeSubprocess) process2 = NULL;
   g_autoptr(GError) error = NULL;
 
   g_assert (G_IS_TASK (task));
@@ -111,17 +122,30 @@ gbp_flatpak_runtime_prebuild_worker (GTask        *task,
   build_path = get_build_directory (self);
   build_dir = g_file_new_for_path (build_path);
 
-  if (g_file_query_exists (build_dir, cancellable))
+  if (!g_file_query_exists (build_dir, cancellable))
     {
-      g_task_return_boolean (task, TRUE);
-      return;
+      if (!g_file_make_directory_with_parents (build_dir, cancellable, &error))
+        {
+          g_task_return_error (task, g_steal_pointer (&error));
+          return;
+        }
     }
 
-  parent = g_file_get_parent (build_dir);
+  context = ide_object_get_context (IDE_OBJECT (self));
+  config_manager = ide_context_get_configuration_manager (context);
+  configuration = ide_configuration_manager_get_current (config_manager);
 
-  if (!g_file_query_exists (parent, cancellable))
+  g_assert (IDE_IS_CONFIGURATION (configuration));
+
+  /* Make sure there's a local flatpak repo we can use to export the build */
+  flatpak_repo_path = g_build_filename (g_get_user_cache_dir (),
+                                        "gnome-builder",
+                                        "flatpak-repo",
+                                        NULL);
+  flatpak_repo_dir = g_file_new_for_path (flatpak_repo_path);
+  if (!g_file_query_exists (flatpak_repo_dir, cancellable))
     {
-      if (!g_file_make_directory_with_parents (parent, cancellable, &error))
+      if (!g_file_make_directory_with_parents (flatpak_repo_dir, cancellable, &error))
         {
           g_task_return_error (task, g_steal_pointer (&error));
           return;
@@ -129,40 +153,115 @@ gbp_flatpak_runtime_prebuild_worker (GTask        *task,
     }
 
   launcher = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
-
   if (launcher == NULL)
     {
       g_task_return_error (task, g_steal_pointer (&error));
       return;
     }
-
-  ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
-  ide_subprocess_launcher_set_clear_env (launcher, FALSE);
-
   ide_subprocess_launcher_push_argv (launcher, "flatpak");
-  ide_subprocess_launcher_push_argv (launcher, "build-init");
-  ide_subprocess_launcher_push_argv (launcher, build_path);
-  /* XXX: Fake name, probably okay, but can be proper once we get
-   * IdeConfiguration in place.
-   */
-  ide_subprocess_launcher_push_argv (launcher, "org.gnome.Builder.FlatpakApp.Build");
-  ide_subprocess_launcher_push_argv (launcher, self->sdk);
-  ide_subprocess_launcher_push_argv (launcher, self->platform);
-  ide_subprocess_launcher_push_argv (launcher, self->branch);
-
-  subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error);
-
-  if (subprocess == NULL)
+  ide_subprocess_launcher_push_argv (launcher, "remote-add");
+  ide_subprocess_launcher_push_argv (launcher, "--user");
+  ide_subprocess_launcher_push_argv (launcher, "--no-gpg-verify");
+  ide_subprocess_launcher_push_argv (launcher, "--if-not-exists");
+  flatpak_repo_name = ide_configuration_get_internal_string (configuration, "flatpak-repo-name");
+  g_assert (!ide_str_empty0 (flatpak_repo_name));
+  ide_subprocess_launcher_push_argv (launcher, flatpak_repo_name);
+  ide_subprocess_launcher_push_argv (launcher, flatpak_repo_path);
+  process = ide_subprocess_launcher_spawn (launcher, cancellable, &error);
+
+  if (!process || !ide_subprocess_wait_check (process, cancellable, &error))
     {
       g_task_return_error (task, g_steal_pointer (&error));
       return;
     }
 
-  if (!ide_subprocess_wait_check (subprocess, cancellable, &error))
+  ide_configuration_set_internal_object (configuration, "flatpak-repo-dir", flatpak_repo_dir);
+
+  if (self->manifest != NULL)
+    {
+      gchar *manifest_path;
+      g_autoptr(JsonParser) parser = NULL;
+      JsonNode *root_node = NULL;
+      JsonNode *modules_node = NULL;
+      JsonObject *root_object = NULL;
+      JsonArray *modules = NULL;
+      guint num_modules;
+
+      manifest_path = g_file_get_path (self->manifest);
+      g_assert (!ide_str_empty0 (manifest_path));
+
+      parser = json_parser_new ();
+      if (!json_parser_load_from_file (parser, manifest_path, &error))
+        {
+          g_task_return_error (task, g_steal_pointer (&error));
+          return;
+        }
+      root_node = json_parser_get_root (parser);
+      g_assert (JSON_NODE_HOLDS_OBJECT (root_node));
+      root_object = json_node_get_object (root_node);
+      modules_node = json_object_get_member (root_object, "modules");
+      g_assert (JSON_NODE_HOLDS_ARRAY (modules_node));
+      modules = json_node_get_array (modules_node);
+      num_modules = json_array_get_length (modules);
+
+      /* No need to run flatpak-builder if there are no dependencies */
+      if (num_modules > 1)
+        {
+          g_autoptr(IdeSubprocessLauncher) launcher3 = NULL;
+          g_autoptr(IdeSubprocess) process3 = NULL;
+          g_autofree gchar *stop_at_option = NULL;
+
+          /* Run flatpak-builder to build just the dependencies */
+          launcher3 = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME 
(self), &error);
+          if (launcher3 == NULL)
+            {
+              g_task_return_error (task, g_steal_pointer (&error));
+              return;
+            }
+          ide_subprocess_launcher_push_argv (launcher3, "flatpak-builder");
+          ide_subprocess_launcher_push_argv (launcher3, "--ccache");
+          ide_subprocess_launcher_push_argv (launcher3, "--force-clean");
+          stop_at_option = g_strdup_printf ("--stop-at=%s", self->primary_module);
+          ide_subprocess_launcher_push_argv (launcher3, stop_at_option);
+          ide_subprocess_launcher_push_argv (launcher3, build_path);
+          ide_subprocess_launcher_push_argv (launcher3, manifest_path);
+          process3 = ide_subprocess_launcher_spawn (launcher3, cancellable, &error);
+
+          if (!process3 || !ide_subprocess_wait_check (process3, cancellable, &error))
+            {
+              g_task_return_error (task, g_steal_pointer (&error));
+              return;
+            }
+
+          g_task_return_boolean (task, TRUE);
+          return;
+        }
+    }
+
+  app_id = ide_configuration_get_app_id (configuration);
+  if (ide_str_empty0 (app_id))
+    {
+      g_warning ("Could not determine application ID");
+      app_id = "org.gnome.FlatpakApp";
+    }
+
+  launcher2 = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
+  if (launcher2 == NULL)
     {
       g_task_return_error (task, g_steal_pointer (&error));
       return;
     }
+  ide_subprocess_launcher_push_argv (launcher2, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher2, "build-init");
+  ide_subprocess_launcher_push_argv (launcher2, build_path);
+  ide_subprocess_launcher_push_argv (launcher2, app_id);
+  ide_subprocess_launcher_push_argv (launcher2, self->sdk);
+  ide_subprocess_launcher_push_argv (launcher2, self->platform);
+  ide_subprocess_launcher_push_argv (launcher2, self->branch);
+  process2 = ide_subprocess_launcher_spawn (launcher2, cancellable, &error);
+
+  /* If the directory is already initialized, don't fail */
+  ide_subprocess_wait_check (process2, cancellable, NULL);
 
   g_task_return_boolean (task, TRUE);
 }
@@ -196,6 +295,202 @@ gbp_flatpak_runtime_prebuild_finish (IdeRuntime    *runtime,
   return g_task_propagate_boolean (G_TASK (result), error);
 }
 
+static void
+gbp_flatpak_runtime_postinstall_worker (GTask        *task,
+                                        gpointer      source_object,
+                                        gpointer      task_data,
+                                        GCancellable *cancellable)
+{
+  GbpFlatpakRuntime *self = source_object;
+  IdeContext *context;
+  IdeConfigurationManager *config_manager;
+  IdeConfiguration *configuration;
+  JsonArray *finish_args = NULL;
+  const gchar *command = NULL;
+  const gchar *repo_name = NULL;
+  const gchar *app_id = NULL;
+  g_autofree gchar *repo_path = NULL;
+  g_autofree gchar *build_path = NULL;
+  g_autofree gchar *manifest_path = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher2 = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher3 = NULL;
+  g_autoptr(IdeSubprocessLauncher) launcher4 = NULL;
+  g_autoptr(IdeSubprocess) process = NULL;
+  g_autoptr(IdeSubprocess) process2 = NULL;
+  g_autoptr(IdeSubprocess) process3 = NULL;
+  g_autoptr(IdeSubprocess) process4 = NULL;
+  g_autoptr(GError) error = NULL;
+  JsonParser *parser = NULL;
+
+  g_assert (G_IS_TASK (task));
+  g_assert (GBP_IS_FLATPAK_RUNTIME (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  config_manager = ide_context_get_configuration_manager (context);
+  configuration = ide_configuration_manager_get_current (config_manager);
+
+  build_path = get_build_directory (self);
+  repo_name = ide_configuration_get_internal_string (configuration, "flatpak-repo-name");
+  repo_path = g_file_get_path (ide_configuration_get_internal_object (configuration, "flatpak-repo-dir"));
+
+  g_assert (!ide_str_empty0 (repo_name));
+  g_assert (!ide_str_empty0 (repo_path));
+
+  /* Attempt to parse the flatpak manifest */
+  if (self->manifest != NULL && (manifest_path = g_file_get_path (self->manifest)))
+    {
+      GError *json_error = NULL;
+      JsonObject *root_object;
+
+      parser = json_parser_new ();
+      json_parser_load_from_file (parser, manifest_path, &json_error);
+      if (json_error)
+        g_debug ("Error parsing flatpak manifest %s: %s", manifest_path, json_error->message);
+      else
+        {
+          root_object = json_node_get_object (json_parser_get_root (parser));
+          if (root_object != NULL)
+            {
+              if (json_object_has_member (root_object, "command"))
+                command = json_object_get_string_member (root_object, "command");
+              if (json_object_has_member (root_object, "finish-args"))
+                finish_args = json_object_get_array_member (root_object, "finish-args");
+            }
+        }
+    }
+
+  /* Finalize the build directory */
+  launcher = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
+  if (launcher == NULL)
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+  ide_subprocess_launcher_push_argv (launcher, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher, "build-finish");
+  if (!ide_str_empty0 (command))
+    {
+      g_autofree gchar *command_option = NULL;
+      command_option = g_strdup_printf ("--command=%s", command);
+      ide_subprocess_launcher_push_argv (launcher, command_option);
+    }
+  if (finish_args != NULL)
+    {
+      for (guint i = 0; i < json_array_get_length (finish_args); i++)
+        {
+          const gchar *arg;
+          arg = json_array_get_string_element (finish_args, i);
+          if (!ide_str_empty0 (arg))
+            ide_subprocess_launcher_push_argv (launcher, arg);
+        }
+    }
+  ide_subprocess_launcher_push_argv (launcher, build_path);
+
+  if (parser != NULL)
+    g_object_unref (parser);
+
+  process = ide_subprocess_launcher_spawn (launcher, cancellable, &error);
+
+  /* Don't fail if the directory was already finished */
+  ide_subprocess_wait_check (process, cancellable, NULL);
+
+  /* Export the build to the repo */
+  launcher2 = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
+  if (launcher2 == NULL)
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+  ide_subprocess_launcher_push_argv (launcher2, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher2, "build-export");
+  ide_subprocess_launcher_push_argv (launcher2, "--subject=\"Development build\"");
+  ide_subprocess_launcher_push_argv (launcher2, repo_path);
+  ide_subprocess_launcher_push_argv (launcher2, build_path);
+  process2 = ide_subprocess_launcher_spawn (launcher2, cancellable, &error);
+
+  if (!process2 || !ide_subprocess_wait_check (process2, cancellable, &error))
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+
+  app_id = ide_configuration_get_app_id (configuration);
+  if (ide_str_empty0 (app_id))
+    {
+      g_warning ("Could not determine application ID");
+      app_id = "org.gnome.FlatpakApp";
+    }
+  /* Try to uninstall it in case this isn't the first run */
+  launcher3 = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
+  if (launcher3 == NULL)
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+  ide_subprocess_launcher_push_argv (launcher3, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher3, "uninstall");
+  ide_subprocess_launcher_push_argv (launcher3, "--user");
+  ide_subprocess_launcher_push_argv (launcher3, app_id);
+  process3 = ide_subprocess_launcher_spawn (launcher3, cancellable, NULL);
+
+  ide_subprocess_wait_check (process3, cancellable, NULL);
+
+  /* Finally install the app */
+  launcher4 = IDE_RUNTIME_CLASS (gbp_flatpak_runtime_parent_class)->create_launcher (IDE_RUNTIME (self), 
&error);
+  if (launcher4 == NULL)
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+  ide_subprocess_launcher_push_argv (launcher4, "flatpak");
+  ide_subprocess_launcher_push_argv (launcher4, "install");
+  ide_subprocess_launcher_push_argv (launcher4, "--user");
+  ide_subprocess_launcher_push_argv (launcher4, "--app");
+  ide_subprocess_launcher_push_argv (launcher4, repo_name);
+  ide_subprocess_launcher_push_argv (launcher4, app_id);
+
+  process4 = ide_subprocess_launcher_spawn (launcher4, cancellable, &error);
+
+  if (!process4 || !ide_subprocess_wait_check (process4, cancellable, &error))
+    {
+      g_task_return_error (task, g_steal_pointer (&error));
+      return;
+    }
+
+  g_task_return_boolean (task, TRUE);
+}
+
+static void
+gbp_flatpak_runtime_postinstall_async (IdeRuntime          *runtime,
+                                       GCancellable        *cancellable,
+                                       GAsyncReadyCallback  callback,
+                                       gpointer             user_data)
+{
+  GbpFlatpakRuntime *self = (GbpFlatpakRuntime *)runtime;
+  g_autoptr(GTask) task = NULL;
+
+  g_assert (GBP_IS_FLATPAK_RUNTIME (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_run_in_thread (task, gbp_flatpak_runtime_postinstall_worker);
+}
+
+static gboolean
+gbp_flatpak_runtime_postinstall_finish (IdeRuntime    *runtime,
+                                        GAsyncResult  *result,
+                                        GError       **error)
+{
+  GbpFlatpakRuntime *self = (GbpFlatpakRuntime *)runtime;
+
+  g_assert (GBP_IS_FLATPAK_RUNTIME (self));
+  g_assert (G_IS_TASK (result));
+
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
 static IdeSubprocessLauncher *
 gbp_flatpak_runtime_create_launcher (IdeRuntime  *runtime,
                                      GError     **error)
@@ -209,18 +504,163 @@ gbp_flatpak_runtime_create_launcher (IdeRuntime  *runtime,
 
   if (ret != NULL)
     {
-      g_autofree gchar *build_path = get_build_directory (self);
+      g_autofree gchar *build_path = NULL;
+      g_autofree gchar *manifest_path = NULL;
+      gchar *project_path;
+      gchar *project_name;
+      const gchar *cflags = NULL;
+      const gchar *cxxflags = NULL;
+      JsonObject *env_vars = NULL;
+      JsonParser *parser = NULL;
+      g_autoptr(GFileInfo) file_info = NULL;
+      IdeContext *context;
+      GFile *project_file;
+
+      build_path = get_build_directory (self);
+
+      /* Attempt to parse the flatpak manifest */
+      if (self->manifest != NULL && (manifest_path = g_file_get_path (self->manifest)))
+        {
+          GError *json_error = NULL;
+          JsonObject *root_object;
+
+          parser = json_parser_new ();
+          json_parser_load_from_file (parser, manifest_path, &json_error);
+          if (json_error)
+            g_debug ("Error parsing flatpak manifest %s: %s", manifest_path, json_error->message);
+          else
+            {
+              root_object = json_node_get_object (json_parser_get_root (parser));
+              if (root_object != NULL && json_object_has_member (root_object, "build-options"))
+                {
+                  JsonObject *build_options = NULL;
+                  build_options = json_object_get_object_member (root_object, "build-options");
+                  if (build_options != NULL)
+                    {
+                      if (json_object_has_member (build_options, "cflags"))
+                        cflags = json_object_get_string_member (build_options, "cflags");
+                      if (json_object_has_member (build_options, "cxxflags"))
+                        cxxflags = json_object_get_string_member (build_options, "cxxflags");
+                      if (json_object_has_member (build_options, "env"))
+                        env_vars = json_object_get_object_member (build_options, "env");
+                    }
+                }
+            }
+        }
 
+      /* Find the project directory path */
+      context = ide_object_get_context (IDE_OBJECT (self));
+      project_file = ide_context_get_project_file (context);
+      if (project_file != NULL)
+        {
+          if (g_file_test (g_file_get_path (project_file), G_FILE_TEST_IS_DIR))
+            project_path = g_file_get_path (project_file);
+          else
+            {
+              g_autoptr(GFile) project_dir = NULL;
+              project_dir = g_file_get_parent (project_file);
+              project_path = g_file_get_path (project_dir);
+              project_name = g_file_get_basename (project_dir);
+            }
+        }
+
+      /* Add 'flatpak build' and the specified arguments to the launcher */
       ide_subprocess_launcher_push_argv (ret, "flatpak");
       ide_subprocess_launcher_push_argv (ret, "build");
+      if (!ide_str_empty0 (project_path))
+        {
+          g_autofree gchar *filesystem_option = NULL;
+          g_autofree gchar *bind_mount_option = NULL;
+          g_autofree gchar *build_dir_option = NULL;
+          filesystem_option = g_strdup_printf ("--filesystem=%s", project_path);
+          bind_mount_option = g_strdup_printf ("--bind-mount=/run/build/%s=%s", project_name, project_path);
+          build_dir_option = g_strdup_printf ("--build-dir=/run/build/%s", project_name);
+          ide_subprocess_launcher_push_argv (ret, "--nofilesystem=host");
+          ide_subprocess_launcher_push_argv (ret, filesystem_option);
+          ide_subprocess_launcher_push_argv (ret, bind_mount_option);
+          ide_subprocess_launcher_push_argv (ret, build_dir_option);
+        }
+      if (env_vars != NULL)
+        {
+          g_autoptr(GList) env_list = NULL;
+          GList *l;
+          env_list = json_object_get_members (env_vars);
+          for (l = env_list; l != NULL; l = l->next)
+            {
+              const gchar *env_name = (gchar *)l->data;
+              const gchar *env_value = json_object_get_string_member (env_vars, env_name);
+              if (!ide_str_empty0 (env_name) && !ide_str_empty0 (env_value))
+                {
+                  g_autofree gchar *env_option = NULL;
+                  env_option = g_strdup_printf ("--env=%s=%s", env_name, env_value);
+                  ide_subprocess_launcher_push_argv (ret, env_option);
+                }
+            }
+        }
+      if (!ide_str_empty0 (cflags))
+        {
+          g_autofree gchar *cflags_option = NULL;
+          cflags_option = g_strdup_printf ("--env=CFLAGS=%s", cflags);
+          ide_subprocess_launcher_push_argv (ret, cflags_option);
+        }
+      if (!ide_str_empty0 (cxxflags))
+        {
+          g_autofree gchar *cxxflags_option = NULL;
+          cxxflags_option = g_strdup_printf ("--env=CXXFLAGS=%s", cxxflags);
+          ide_subprocess_launcher_push_argv (ret, cxxflags_option);
+        }
+
+      /* We want the configure step to be separate so IdeAutotoolsBuildTask can pass options to it */
+      ide_subprocess_launcher_push_argv (ret, "--env=NOCONFIGURE=1");
+
       ide_subprocess_launcher_push_argv (ret, build_path);
 
       ide_subprocess_launcher_set_run_on_host (ret, TRUE);
+
+      g_object_unref (parser);
     }
 
   return ret;
 }
 
+IdeRunner *
+gbp_flatpak_runtime_create_runner (IdeRuntime     *runtime,
+                                   IdeBuildTarget *build_target)
+{
+  GbpFlatpakRuntime *self = (GbpFlatpakRuntime *)runtime;
+  IdeContext *context;
+  IdeConfigurationManager *config_manager;
+  IdeConfiguration *configuration;
+  GbpFlatpakRunner *runner;
+  const gchar *app_id = NULL;
+
+  g_assert (GBP_IS_FLATPAK_RUNTIME (self));
+  g_assert (IDE_IS_BUILD_TARGET (build_target));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  config_manager = ide_context_get_configuration_manager (context);
+  configuration = ide_configuration_manager_get_current (config_manager);
+
+  runner = gbp_flatpak_runner_new (context);
+  g_assert (GBP_IS_FLATPAK_RUNNER (runner));
+
+  app_id = ide_configuration_get_app_id (configuration);
+  if (ide_str_empty0 (app_id))
+    {
+      g_warning ("Could not determine application ID");
+      app_id = "org.gnome.FlatpakApp";
+    }
+  ide_runner_set_run_on_host (IDE_RUNNER (runner), TRUE);
+  ide_runner_append_argv (IDE_RUNNER (runner), "flatpak");
+  ide_runner_append_argv (IDE_RUNNER (runner), "run");
+  ide_runner_append_argv (IDE_RUNNER (runner), "--share=ipc");
+  ide_runner_append_argv (IDE_RUNNER (runner), "--socket=x11");
+  ide_runner_append_argv (IDE_RUNNER (runner), "--socket=wayland");
+  ide_runner_append_argv (IDE_RUNNER (runner), app_id);
+
+  return IDE_RUNNER (runner);
+}
+
 static void
 gbp_flatpak_runtime_prepare_configuration (IdeRuntime       *runtime,
                                            IdeConfiguration *configuration)
@@ -233,6 +673,7 @@ gbp_flatpak_runtime_prepare_configuration (IdeRuntime       *runtime,
   if (!ide_str_empty0 (self->app_id))
     ide_configuration_set_app_id (configuration, self->app_id);
   ide_configuration_set_prefix (configuration, "/app");
+  ide_configuration_set_internal_string (configuration, "flatpak-repo-name", "gnome-builder-builds");
 }
 
 static void
@@ -340,7 +781,10 @@ gbp_flatpak_runtime_class_init (GbpFlatpakRuntimeClass *klass)
 
   runtime_class->prebuild_async = gbp_flatpak_runtime_prebuild_async;
   runtime_class->prebuild_finish = gbp_flatpak_runtime_prebuild_finish;
+  runtime_class->postinstall_async = gbp_flatpak_runtime_postinstall_async;
+  runtime_class->postinstall_finish = gbp_flatpak_runtime_postinstall_finish;
   runtime_class->create_launcher = gbp_flatpak_runtime_create_launcher;
+  runtime_class->create_runner = gbp_flatpak_runtime_create_runner;
   runtime_class->contains_program_in_path = gbp_flatpak_runtime_contains_program_in_path;
   runtime_class->prepare_configuration = gbp_flatpak_runtime_prepare_configuration;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]