[gnome-builder] meson: implement --installed fallback for build targets
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] meson: implement --installed fallback for build targets
- Date: Wed, 18 Oct 2017 07:41:59 +0000 (UTC)
commit 98b05f48f21a1a0959776e0635ab4aa287f4c627
Author: Christian Hergert <chergert redhat com>
Date: Wed Oct 18 00:30:55 2017 -0700
meson: implement --installed fallback for build targets
This gets the last missing piece of the port from Python, which
is to access the installed files looking for things in
${prefix}/bin that might not be meson build targets (scripts).
src/plugins/meson/gbp-meson-build-system.c | 164 +++++++++++++++++++++++++++-
1 files changed, 161 insertions(+), 3 deletions(-)
---
diff --git a/src/plugins/meson/gbp-meson-build-system.c b/src/plugins/meson/gbp-meson-build-system.c
index 249b069..9dbdbc4 100644
--- a/src/plugins/meson/gbp-meson-build-system.c
+++ b/src/plugins/meson/gbp-meson-build-system.c
@@ -46,6 +46,32 @@ enum {
static GParamSpec *properties [N_PROPS];
+static IdeSubprocessLauncher *
+gbp_meson_build_system_create_launcher (GbpMesonBuildSystem *self,
+ GError **error)
+{
+ IdeBuildPipeline *pipeline;
+ IdeBuildManager *build_manager;
+ IdeContext *context;
+
+ g_assert (GBP_IS_MESON_BUILD_SYSTEM (self));
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ build_manager = ide_context_get_build_manager (context);
+ pipeline = ide_build_manager_get_pipeline (build_manager);
+
+ if (pipeline == NULL)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Pipeline is not ready, cannot create launcher");
+ return NULL;
+ }
+
+ return ide_build_pipeline_create_launcher (pipeline, error);
+}
+
static void
gbp_meson_build_system_ensure_config_cb (GObject *object,
GAsyncResult *result,
@@ -463,20 +489,113 @@ gbp_meson_build_system_get_build_flags_finish (IdeBuildSystem *build_system,
}
static void
+gbp_meson_build_system_get_build_targets_communciate_cb2 (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeSubprocess *subprocess = (IdeSubprocess *)object;
+ GbpMesonBuildSystem *self;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(JsonParser) parser = NULL;
+ g_autofree gchar *stdout_buf = NULL;
+ JsonObjectIter iter;
+ const gchar *key;
+ IdeContext *context;
+ JsonObject *obj;
+ JsonNode *root;
+ JsonNode *value;
+
+ g_assert (IDE_IS_SUBPROCESS (subprocess));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ if (!ide_subprocess_communicate_utf8_finish (subprocess, result, &stdout_buf, NULL, &error))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ self = g_task_get_source_object (task);
+ context = ide_object_get_context (IDE_OBJECT (self));
+
+ parser = json_parser_new ();
+
+ if (!json_parser_load_from_data (parser, stdout_buf, -1, &error))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ if (NULL == (root = json_parser_get_root (parser)) ||
+ !JSON_NODE_HOLDS_OBJECT (root) ||
+ NULL == (obj = json_node_get_object (root)))
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_DATA,
+ "Invalid JSON received from meson introspect");
+ return;
+ }
+
+ json_object_iter_init (&iter, obj);
+
+ while (json_object_iter_next (&iter, &key, &value))
+ {
+ const gchar *path;
+ g_autofree gchar *dir = NULL;
+
+ if (!JSON_NODE_HOLDS_VALUE (value) ||
+ NULL == (path = json_node_get_string (value)))
+ continue;
+
+ dir = g_path_get_dirname (path);
+
+ if (dir != NULL && g_str_has_suffix (dir, "/bin"))
+ {
+ g_autofree gchar *name = NULL;
+ g_autoptr(GPtrArray) ret = NULL;
+ g_autoptr(GFile) gdir = NULL;
+
+ gdir = g_file_new_for_path (dir);
+ name = g_path_get_basename (path);
+
+ /* We only need one result */
+ ret = g_ptr_array_new_with_free_func (g_object_unref);
+ g_ptr_array_add (ret, gbp_meson_build_target_new (context, gdir, name));
+ g_task_return_pointer (task, g_steal_pointer (&ret), (GDestroyNotify)g_ptr_array_unref);
+
+ return;
+ }
+ }
+
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Failed to locate any build targets");
+}
+
+static void
gbp_meson_build_system_get_build_targets_communciate_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
IdeSubprocess *subprocess = (IdeSubprocess *)object;
+ g_autofree gchar *stdout_buf = NULL;
g_autoptr(GTask) task = user_data;
g_autoptr(JsonParser) parser = NULL;
+ g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+ g_autoptr(IdeSubprocess) all_subprocess = NULL;
g_autoptr(GError) error = NULL;
- g_autofree gchar *stdout_buf = NULL;
g_autoptr(GPtrArray) ret = NULL;
GbpMesonBuildSystem *self;
+ IdeBuildPipeline *pipeline;
+ IdeBuildManager *build_manager;
+ GCancellable *cancellable;
IdeContext *context;
JsonArray *array;
JsonNode *root;
+ gboolean found_bindir = FALSE;
guint len;
g_assert (IDE_IS_SUBPROCESS (subprocess));
@@ -560,6 +679,8 @@ gbp_meson_build_system_get_build_targets_communciate_cb (GObject *object,
target = gbp_meson_build_target_new (context, dir, base);
+ found_bindir |= ide_str_equal0 (name_of_dir, "bin");
+
/*
* Until Builder supports selecting a target to run, we need to prefer
* bindir targets over other targets.
@@ -571,7 +692,44 @@ gbp_meson_build_system_get_build_targets_communciate_cb (GObject *object,
}
}
- g_task_return_pointer (task, g_steal_pointer (&ret), (GDestroyNotify)g_ptr_array_unref);
+ /*
+ * If we didn't find a target while processing the targets, we need to scan
+ * for all installed targets to locate a potential script such as python/gjs.
+ */
+
+ if (ret->len > 0 && found_bindir)
+ {
+ g_task_return_pointer (task, g_steal_pointer (&ret), (GDestroyNotify)g_ptr_array_unref);
+ return;
+ }
+
+ if (NULL == (launcher = gbp_meson_build_system_create_launcher (self, &error)))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ build_manager = ide_context_get_build_manager (context);
+ pipeline = ide_build_manager_get_pipeline (build_manager);
+ cancellable = g_task_get_cancellable (task);
+
+ ide_subprocess_launcher_push_argv (launcher, "meson");
+ ide_subprocess_launcher_push_argv (launcher, "introspect");
+ ide_subprocess_launcher_push_argv (launcher, "--installed");
+ ide_subprocess_launcher_push_argv (launcher, ide_build_pipeline_get_builddir (pipeline));
+
+ if (NULL == (all_subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error)))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ ide_subprocess_communicate_utf8_async (all_subprocess,
+ NULL,
+ cancellable,
+ gbp_meson_build_system_get_build_targets_communciate_cb2,
+ g_steal_pointer (&task));
}
static void
@@ -613,7 +771,7 @@ gbp_meson_build_system_get_build_targets_ensure_cb (GObject *object,
return;
}
- if (NULL == (launcher = ide_build_pipeline_create_launcher (pipeline, &error)))
+ if (NULL == (launcher = gbp_meson_build_system_create_launcher (self, &error)))
{
g_task_return_error (task, g_steal_pointer (&error));
return;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]