[gnome-builder] libide: use makecache to extract build flags from autotools
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide: use makecache to extract build flags from autotools
- Date: Mon, 23 Mar 2015 23:47:52 +0000 (UTC)
commit 03e0835d025bfab3a0f353f63d0358fd782421b9
Author: Christian Hergert <christian hergert me>
Date: Sun Mar 1 18:01:37 2015 -0800
libide: use makecache to extract build flags from autotools
This implements the IdeBuildSystem::get_build_flags_async() and
IdeBuildSystem::get_build_flags_finish() virtual functions using the
makecache module.
TODO:
We should invalidate the makecache when we discover a makefile has been
changed (or configure.ac/dependency).
libide/autotools/ide-autotools-build-system.c | 350 +++++++++++++++++++++++--
1 files changed, 331 insertions(+), 19 deletions(-)
---
diff --git a/libide/autotools/ide-autotools-build-system.c b/libide/autotools/ide-autotools-build-system.c
index 3784fe6..e636c45 100644
--- a/libide/autotools/ide-autotools-build-system.c
+++ b/libide/autotools/ide-autotools-build-system.c
@@ -20,14 +20,20 @@
#include <gio/gio.h>
#include "ide-autotools-build-system.h"
+#include "ide-autotools-builder.h"
#include "ide-context.h"
#include "ide-device.h"
-
-#include "autotools/ide-autotools-builder.h"
+#include "ide-device-manager.h"
+#include "ide-file.h"
+#include "ide-makecache.h"
typedef struct
{
- gchar *tarball_name;
+ IdeMakecache *makecache;
+ gchar *tarball_name;
+ GPtrArray *makecache_tasks;
+
+ guint makecache_in_progress : 1;
} IdeAutotoolsBuildSystemPrivate;
static void async_initable_iface_init (GAsyncInitableIface *iface);
@@ -195,6 +201,322 @@ ide_autotools_build_system_discover_file_finish (IdeAutotoolsBuildSystem *syste
}
static void
+ide_autotools_build_system__bootstrap_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeAutotoolsBuilder *builder = (IdeAutotoolsBuilder *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GFile) build_directory = NULL;
+ g_autoptr(GFile) makefile = NULL;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_AUTOTOOLS_BUILDER (builder));
+ g_assert (G_IS_TASK (task));
+
+ if (!ide_autotools_builder_bootstrap_finish (builder, result, &error))
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ build_directory = ide_autotools_builder_get_build_directory (builder);
+ makefile = g_file_get_child (build_directory, "Makefile");
+
+ g_task_return_pointer (task, g_object_ref (makefile), g_object_unref);
+}
+
+static void
+ide_autotools_build_system_get_local_makefile_async (IdeAutotoolsBuildSystem *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeContext *context;
+ IdeDeviceManager *device_manager;
+ IdeDevice *device;
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(IdeBuilder) builder = NULL;
+ g_autoptr(GKeyFile) config = NULL;
+ g_autoptr(GFile) build_directory = NULL;
+ g_autoptr(GFile) makefile = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ device_manager = ide_context_get_device_manager (context);
+ device = ide_device_manager_get_device (device_manager, "local");
+ config = g_key_file_new ();
+ builder = ide_autotools_build_system_get_builder (IDE_BUILD_SYSTEM (self), config, device, &error);
+
+ if (!builder)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ /*
+ * If we haven't yet bootstrapped the project, let's go ahead and do that now.
+ */
+ if (ide_autotools_builder_get_needs_bootstrap (IDE_AUTOTOOLS_BUILDER (builder)))
+ {
+ ide_autotools_builder_bootstrap_async (IDE_AUTOTOOLS_BUILDER (builder),
+ cancellable,
+ ide_autotools_build_system__bootstrap_cb,
+ g_object_ref (task));
+ return;
+ }
+
+ build_directory = ide_autotools_builder_get_build_directory (IDE_AUTOTOOLS_BUILDER (builder));
+ makefile = g_file_get_child (build_directory, "Makefile");
+
+ g_task_return_pointer (task, g_object_ref (makefile), g_object_unref);
+}
+
+static GFile *
+ide_autotools_build_system_get_local_makefile_finish (IdeAutotoolsBuildSystem *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_return_val_if_fail (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self), NULL);
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static void
+ide_autotools_build_system__makecache_new_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeAutotoolsBuildSystemPrivate *priv;
+ IdeAutotoolsBuildSystem *self;
+ g_autoptr(IdeMakecache) makecache = NULL;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GPtrArray) tasks = NULL;
+ GError *error = NULL;
+
+ g_assert (G_IS_TASK (task));
+
+ makecache = ide_makecache_new_for_makefile_finish (result, &error);
+
+ if (!makecache)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ /*
+ * Complete all of the pending tasks in flight.
+ */
+
+ self = g_task_get_source_object (task);
+ priv = ide_autotools_build_system_get_instance_private (self);
+
+ tasks = priv->makecache_tasks;
+ priv->makecache_tasks = g_ptr_array_new ();
+ priv->makecache_in_progress = FALSE;
+
+ g_task_return_pointer (task, g_object_ref (makecache), g_object_unref);
+
+ while (tasks->len)
+ {
+ GTask *other_task;
+ gsize i = tasks->len - 1;
+
+ other_task = g_ptr_array_index (tasks, i);
+ g_task_return_pointer (other_task, g_object_ref (makecache), g_object_unref);
+ g_ptr_array_remove_index (tasks, i);
+ g_object_unref (other_task);
+ }
+}
+
+static void
+ide_autotools_build_system__local_makefile_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeAutotoolsBuildSystem *self = (IdeAutotoolsBuildSystem *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GFile) makefile = NULL;
+ IdeContext *context;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (task));
+
+ makefile = ide_autotools_build_system_get_local_makefile_finish (self, result, &error);
+
+ if (!makefile)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ ide_makecache_new_for_makefile_async (context,
+ makefile,
+ g_task_get_cancellable (task),
+ ide_autotools_build_system__makecache_new_cb,
+ g_object_ref (task));
+}
+
+static void
+ide_autotools_build_system_get_makecache_async (IdeAutotoolsBuildSystem *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeAutotoolsBuildSystemPrivate *priv = ide_autotools_build_system_get_instance_private (self);
+ g_autoptr(GTask) task = NULL;
+
+ g_return_if_fail (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+
+ /*
+ * If we already have the makecache loaded, we can just return that.
+ */
+ if (priv->makecache)
+ {
+ g_task_return_pointer (task, g_object_ref (priv->makecache), g_object_unref);
+ return;
+ }
+
+ /*
+ * If we have a makecache operation in progress, we need to queue the task to be completed
+ * when that operation completes.
+ */
+ if (priv->makecache_in_progress)
+ {
+ g_ptr_array_add (priv->makecache_tasks, g_object_ref (task));
+ return;
+ }
+
+ /*
+ * Nothing else is creating the makecache, so let's go ahead and create it now.
+ */
+ priv->makecache_in_progress = TRUE;
+ ide_autotools_build_system_get_local_makefile_async (self,
+ cancellable,
+ ide_autotools_build_system__local_makefile_cb,
+ g_object_ref (task));
+}
+
+static IdeMakecache *
+ide_autotools_build_system_get_makecache_finish (IdeAutotoolsBuildSystem *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_return_val_if_fail (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self), NULL);
+ g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static void
+ide_autotools_build_system__get_file_flags_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeMakecache *makecache = (IdeMakecache *)object;
+ g_autoptr(GTask) task = user_data;
+ gchar **flags;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_MAKECACHE (makecache));
+ g_assert (G_IS_TASK (task));
+
+ flags = ide_makecache_get_file_flags_finish (makecache, result, &error);
+
+ if (!flags)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ g_task_return_pointer (task, flags, (GDestroyNotify)g_strfreev);
+}
+
+static void
+ide_autotools_build_system__makecache_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeAutotoolsBuildSystem *self = (IdeAutotoolsBuildSystem *)object;
+ g_autoptr(IdeMakecache) makecache = NULL;
+ g_autoptr(GTask) task = user_data;
+ GError *error = NULL;
+ GFile *file;
+
+ g_assert (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (task));
+
+ makecache = ide_autotools_build_system_get_makecache_finish (self, result, &error);
+
+ if (!makecache)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ file = g_task_get_task_data (task);
+ g_assert (G_IS_FILE (file));
+
+ ide_makecache_get_file_flags_async (makecache,
+ file,
+ g_task_get_cancellable (task),
+ ide_autotools_build_system__get_file_flags_cb,
+ g_object_ref (task));
+}
+
+static void
+ide_autotools_build_system_get_build_flags_async (IdeBuildSystem *build_system,
+ IdeFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeAutotoolsBuildSystem *self = (IdeAutotoolsBuildSystem *)build_system;
+ g_autoptr(GTask) task = NULL;
+ GFile *gfile;
+
+ g_assert (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (self));
+ g_assert (IDE_IS_FILE (file));
+
+ gfile = ide_file_get_file (file);
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_task_data (task, g_object_ref (gfile), g_object_unref);
+
+ ide_autotools_build_system_get_makecache_async (self,
+ cancellable,
+ ide_autotools_build_system__makecache_cb,
+ g_object_ref (task));
+}
+
+static gchar **
+ide_autotools_build_system_get_build_flags_finish (IdeBuildSystem *build_system,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_assert (IDE_IS_AUTOTOOLS_BUILD_SYSTEM (build_system));
+ g_assert (G_IS_TASK (task));
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static void
ide_autotools_build_system_finalize (GObject *object)
{
IdeAutotoolsBuildSystemPrivate *priv;
@@ -203,6 +525,7 @@ ide_autotools_build_system_finalize (GObject *object)
priv = ide_autotools_build_system_get_instance_private (system);
g_clear_pointer (&priv->tarball_name, g_free);
+ g_clear_pointer (&priv->makecache_tasks, g_ptr_array_unref);
G_OBJECT_CLASS (ide_autotools_build_system_parent_class)->finalize (object);
}
@@ -228,21 +551,6 @@ ide_autotools_build_system_get_property (GObject *object,
}
static void
-ide_autotools_build_system_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- //IdeAutotoolsBuildSystem *self = IDE_AUTOTOOLS_BUILD_SYSTEM (object);
-
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
ide_autotools_build_system_class_init (IdeAutotoolsBuildSystemClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -250,9 +558,10 @@ ide_autotools_build_system_class_init (IdeAutotoolsBuildSystemClass *klass)
object_class->finalize = ide_autotools_build_system_finalize;
object_class->get_property = ide_autotools_build_system_get_property;
- object_class->set_property = ide_autotools_build_system_set_property;
build_system_class->get_builder = ide_autotools_build_system_get_builder;
+ build_system_class->get_build_flags_async = ide_autotools_build_system_get_build_flags_async;
+ build_system_class->get_build_flags_finish = ide_autotools_build_system_get_build_flags_finish;
gParamSpecs [PROP_TARBALL_NAME] =
g_param_spec_string ("tarball-name",
@@ -267,6 +576,9 @@ ide_autotools_build_system_class_init (IdeAutotoolsBuildSystemClass *klass)
static void
ide_autotools_build_system_init (IdeAutotoolsBuildSystem *self)
{
+ IdeAutotoolsBuildSystemPrivate *priv = ide_autotools_build_system_get_instance_private (self);
+
+ priv->makecache_tasks = g_ptr_array_new ();
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]