[gnome-builder] cmake: port cmake plugin to C
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] cmake: port cmake plugin to C
- Date: Mon, 23 Oct 2017 21:16:43 +0000 (UTC)
commit 9d685dae24dc9bbadc6ec21e5e04c22f636c55d2
Author: Martin Blanchard <tchaik gmx com>
Date: Mon Oct 23 16:03:06 2017 +0200
cmake: port cmake plugin to C
Rewrite the build system plugin in statically typed language and try
to properly implement async APIs:
* Build flags extraction is done using IdeCompileCommands and thus
should be availabe right after configure, no need for running a build.
* Targets extraction isn't implemented yet. Best option would be to
switch to a cmake-server based implementation. Still looking for a
cheap bypass...
* Async initialisation.
This new version is heavily based on the meson plugin code.
https://bugzilla.gnome.org/show_bug.cgi?id=751761
src/plugins/cmake/cmake-plugin.c | 30 +
src/plugins/cmake/cmake.gresource.xml | 6 +
src/plugins/cmake/cmake.plugin | 9 +-
src/plugins/cmake/cmake_plugin.py | 151 ------
src/plugins/cmake/gbp-cmake-build-system.c | 727 ++++++++++++++++++++++++++
src/plugins/cmake/gbp-cmake-build-system.h | 30 +
src/plugins/cmake/gbp-cmake-build-target.c | 105 ++++
src/plugins/cmake/gbp-cmake-build-target.h | 34 ++
src/plugins/cmake/gbp-cmake-pipeline-addin.c | 218 ++++++++
src/plugins/cmake/gbp-cmake-pipeline-addin.h | 30 +
src/plugins/cmake/meson.build | 25 +-
11 files changed, 1201 insertions(+), 164 deletions(-)
---
diff --git a/src/plugins/cmake/cmake-plugin.c b/src/plugins/cmake/cmake-plugin.c
new file mode 100644
index 0000000..a4eae84
--- /dev/null
+++ b/src/plugins/cmake/cmake-plugin.c
@@ -0,0 +1,30 @@
+/* cmake-plugin.c
+ *
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libpeas/peas.h>
+#include <ide.h>
+
+#include "gbp-cmake-build-system.h"
+#include "gbp-cmake-pipeline-addin.h"
+
+void
+gbp_cmake_register_types (PeasObjectModule *module)
+{
+ peas_object_module_register_extension_type (module, IDE_TYPE_BUILD_PIPELINE_ADDIN,
GBP_TYPE_CMAKE_PIPELINE_ADDIN);
+ peas_object_module_register_extension_type (module, IDE_TYPE_BUILD_SYSTEM, GBP_TYPE_CMAKE_BUILD_SYSTEM);
+}
diff --git a/src/plugins/cmake/cmake.gresource.xml b/src/plugins/cmake/cmake.gresource.xml
new file mode 100644
index 0000000..13ed9b0
--- /dev/null
+++ b/src/plugins/cmake/cmake.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/builder/plugins">
+ <file>cmake.plugin</file>
+ </gresource>
+</gresources>
diff --git a/src/plugins/cmake/cmake.plugin b/src/plugins/cmake/cmake.plugin
index 6588d36..e668d2c 100644
--- a/src/plugins/cmake/cmake.plugin
+++ b/src/plugins/cmake/cmake.plugin
@@ -1,11 +1,10 @@
[Plugin]
-Module=cmake_plugin
-Loader=python3
+Module=cmake-plugin
Name=CMake
Description=Provides integration with the CMake build system
-Authors=Christian Hergert <chergert redhat com>
-Copyright=Copyright © 2016 Christian Hergert
+Authors=Martin Blanchard <tchaik gmx com>
+Copyright=Copyright © 2016 Martin Blanchard
Builtin=true
-Hidden=false
X-Project-File-Filter-Pattern=CMakeLists.txt
X-Project-File-Filter-Name=CMake Project (CMakeLists.txt)
+Embedded=gbp_cmake_register_types
diff --git a/src/plugins/cmake/gbp-cmake-build-system.c b/src/plugins/cmake/gbp-cmake-build-system.c
new file mode 100644
index 0000000..2755bf8
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-build-system.c
@@ -0,0 +1,727 @@
+/* gbp-cmake-build-system.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-cmake-build-system"
+
+#include <glib/gi18n.h>
+
+#include "gbp-cmake-build-system.h"
+#include "gbp-cmake-build-target.h"
+
+struct _GbpCMakeBuildSystem
+{
+ IdeObject parent_instance;
+
+ GFile *project_file;
+ IdeCompileCommands *compile_commands;
+ GFileMonitor *monitor;
+};
+
+static void async_initable_iface_init (GAsyncInitableIface *iface);
+static void build_system_iface_init (IdeBuildSystemInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GbpCMakeBuildSystem, gbp_cmake_build_system, IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_BUILD_SYSTEM, build_system_iface_init))
+
+enum {
+ PROP_0,
+ PROP_PROJECT_FILE,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+gbp_cmake_build_system_commands_file_changed (GbpCMakeBuildSystem *self,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event,
+ GFileMonitor *monitor)
+{
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (!file || G_IS_FILE (file));
+ g_assert (!other_file || G_IS_FILE (other_file));
+ g_assert (G_IS_FILE_MONITOR (monitor));
+
+ g_clear_object (&self->compile_commands);
+
+ g_file_monitor_cancel (monitor);
+ g_clear_object (&self->monitor);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_cmake_build_system_monitor_commands_file (GbpCMakeBuildSystem *self,
+ GFile *file)
+{
+ g_autoptr(GFileMonitor) monitor = NULL;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_FILE (file));
+
+ monitor = g_file_monitor_file (file,
+ G_FILE_MONITOR_NONE,
+ NULL,
+ NULL);
+
+ g_signal_connect_object (monitor,
+ "changed",
+ G_CALLBACK (gbp_cmake_build_system_commands_file_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_set_object (&self->monitor, monitor);
+}
+
+static void
+gbp_cmake_build_system_ensure_config_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeBuildManager *build_manager = (IdeBuildManager *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (IDE_IS_BUILD_MANAGER (build_manager));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ if (!ide_build_manager_execute_finish (build_manager, result, &error))
+ g_task_return_error (task, g_steal_pointer (&error));
+ else
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
+gbp_cmake_build_system_ensure_config_async (GbpCMakeBuildSystem *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ IdeBuildManager *build_manager;
+ IdeContext *context;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gbp_cmake_build_system_ensure_config_async);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ build_manager = ide_context_get_build_manager (context);
+
+ ide_build_manager_execute_async (build_manager,
+ IDE_BUILD_PHASE_CONFIGURE,
+ cancellable,
+ gbp_cmake_build_system_ensure_config_cb,
+ g_steal_pointer (&task));
+}
+
+static gboolean
+gbp_cmake_build_system_ensure_config_finish (GbpCMakeBuildSystem *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (result));
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+gbp_cmake_build_system_load_commands_load_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeCompileCommands *compile_commands = (IdeCompileCommands *)object;
+ GbpCMakeBuildSystem *self;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (IDE_IS_COMPILE_COMMANDS (compile_commands));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ self = g_task_get_source_object (task);
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+
+ if (!ide_compile_commands_load_finish (compile_commands, result, &error))
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ g_set_object (&self->compile_commands, compile_commands);
+
+ g_task_return_pointer (task, g_object_ref (compile_commands), g_object_unref);
+}
+
+static void
+gbp_cmake_build_system_load_commands_config_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)object;
+ g_autoptr(IdeCompileCommands) compile_commands = NULL;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GFileMonitor) monitor = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GFile) file = NULL;
+ g_autofree gchar *path = NULL;
+ IdeBuildManager *build_manager;
+ IdeBuildPipeline *pipeline;
+ GCancellable *cancellable;
+ IdeContext *context;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ if (!gbp_cmake_build_system_ensure_config_finish (self, result, &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);
+
+ if (pipeline == NULL)
+ {
+ /* Unlikely, but possible */
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No build pipeline is available");
+ return;
+ }
+
+ path = ide_build_pipeline_build_builddir_path (pipeline, "compile_commands.json", NULL);
+
+ if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
+ {
+ /* Unlikely, but possible */
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "Failed to locate compile_commands.json");
+ return;
+ }
+
+ compile_commands = ide_compile_commands_new ();
+ file = g_file_new_for_path (path);
+ cancellable = g_task_get_cancellable (task);
+
+ ide_compile_commands_load_async (compile_commands,
+ file,
+ cancellable,
+ gbp_cmake_build_system_load_commands_load_cb,
+ g_steal_pointer (&task));
+
+ gbp_cmake_build_system_monitor_commands_file (self, file);
+}
+
+static void
+gbp_cmake_build_system_load_commands_async (GbpCMakeBuildSystem *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ IdeBuildManager *build_manager;
+ IdeBuildPipeline *pipeline;
+ IdeContext *context;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gbp_cmake_build_system_load_commands_async);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+
+ /*
+ * If we've already load the compile commands database, use it and
+ * short circuit as early as we can to avoid progressing the build
+ * pipeline unnecessarily.
+ */
+
+ if (self->compile_commands != NULL)
+ {
+ g_task_return_pointer (task,
+ g_object_ref (self->compile_commands),
+ g_object_unref);
+ return;
+ }
+
+ /*
+ * If the build pipeline has been previously configured, we might
+ * already have a "compile_commands.json" file in the build directory
+ * that we can reuse.
+ */
+
+ 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_autofree gchar *path = NULL;
+
+ path = ide_build_pipeline_build_builddir_path (pipeline, "compile_commands.json", NULL);
+
+ if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
+ {
+ g_autoptr(IdeCompileCommands) compile_commands = NULL;
+ g_autoptr(GFile) file = NULL;
+
+ compile_commands = ide_compile_commands_new ();
+ file = g_file_new_for_path (path);
+
+ ide_compile_commands_load_async (compile_commands,
+ file,
+ cancellable,
+ gbp_cmake_build_system_load_commands_load_cb,
+ g_steal_pointer (&task));
+
+ gbp_cmake_build_system_monitor_commands_file (self, file);
+
+ return;
+ }
+ }
+
+ /*
+ * It looks like we need to ensure the build pipeline advances to the the
+ * CONFIGURE phase so that cmake has generated a new compile_commands.json
+ * that we can load.
+ */
+
+ gbp_cmake_build_system_ensure_config_async (self,
+ cancellable,
+ gbp_cmake_build_system_load_commands_config_cb,
+ g_steal_pointer (&task));
+}
+
+static IdeCompileCommands *
+gbp_cmake_build_system_load_commands_finish (GbpCMakeBuildSystem *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (result));
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
+gbp_cmake_build_system_finalize (GObject *object)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)object;
+
+ g_clear_object (&self->project_file);
+ g_clear_object (&self->compile_commands);
+ g_clear_object (&self->monitor);
+
+ G_OBJECT_CLASS (gbp_cmake_build_system_parent_class)->finalize (object);
+}
+
+static void
+gbp_cmake_build_system_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpCMakeBuildSystem *self = GBP_CMAKE_BUILD_SYSTEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_PROJECT_FILE:
+ g_value_set_object (value, self->project_file);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gbp_cmake_build_system_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GbpCMakeBuildSystem *self = GBP_CMAKE_BUILD_SYSTEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_PROJECT_FILE:
+ self->project_file = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gbp_cmake_build_system_class_init (GbpCMakeBuildSystemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gbp_cmake_build_system_finalize;
+ object_class->get_property = gbp_cmake_build_system_get_property;
+ object_class->set_property = gbp_cmake_build_system_set_property;
+
+ properties [PROP_PROJECT_FILE] =
+ g_param_spec_object ("project-file",
+ "Project File",
+ "The primary CMakeLists.txt for the project",
+ G_TYPE_FILE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gbp_cmake_build_system_init (GbpCMakeBuildSystem *self)
+{
+}
+
+static gchar *
+gbp_cmake_build_system_get_id (IdeBuildSystem *build_system)
+{
+ return g_strdup ("cmake");
+}
+
+static gchar *
+gbp_cmake_build_system_get_display_name (IdeBuildSystem *build_system)
+{
+ return g_strdup (_("CMake"));
+}
+
+static gint
+gbp_cmake_build_system_get_priority (IdeBuildSystem *build_system)
+{
+ return 100;
+}
+
+static void
+gbp_cmake_build_system_get_build_flags_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)object;
+ g_autoptr(IdeCompileCommands) compile_commands = NULL;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GFile) directory = NULL;
+ g_auto(GStrv) build_flags = NULL;
+ GFile *file;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ compile_commands = gbp_cmake_build_system_load_commands_finish (self, result, &error);
+
+ if (compile_commands == NULL)
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ file = g_task_get_task_data (task);
+ g_assert (G_IS_FILE (file));
+
+ build_flags = ide_compile_commands_lookup (compile_commands, file, &directory, &error);
+
+ if (build_flags == NULL)
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
+ }
+
+ g_task_return_pointer (task, g_steal_pointer (&build_flags), (GDestroyNotify)g_strfreev);
+}
+
+static void
+gbp_cmake_build_system_get_build_flags_async (IdeBuildSystem *build_system,
+ IdeFile *file,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)build_system;
+ g_autoptr(GTask) task = NULL;
+ GFile *gfile;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (IDE_IS_FILE (file));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ gfile = ide_file_get_file (file);
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+ g_task_set_source_tag (task, gbp_cmake_build_system_get_build_flags_async);
+ g_task_set_task_data (task, g_object_ref (gfile), g_object_unref);
+
+ gbp_cmake_build_system_load_commands_async (self,
+ cancellable,
+ gbp_cmake_build_system_get_build_flags_cb,
+ g_steal_pointer (&task));
+
+ IDE_EXIT;
+}
+
+static gchar **
+gbp_cmake_build_system_get_build_flags_finish (IdeBuildSystem *build_system,
+ GAsyncResult *result,
+ GError **error)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)build_system;
+ gchar **build_flags;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (result));
+
+ build_flags = g_task_propagate_pointer (G_TASK (result), error);
+
+ IDE_RETURN (build_flags);
+}
+
+static void
+gbp_cmake_build_system_get_build_targets_async (IdeBuildSystem *build_system,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)build_system;
+ g_autoptr(GTask) task = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+ g_task_set_source_tag (task, gbp_cmake_build_system_get_build_targets_async);
+
+ /* Not implemented yet, still looking for the best option... */
+ g_task_return_error (task,
+ g_error_new (G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "Extracting targets from CMake projects isn't supported yet…"));
+
+ IDE_EXIT;
+}
+
+static GPtrArray *
+gbp_cmake_build_system_get_build_targets_finish (IdeBuildSystem *build_system,
+ GAsyncResult *result,
+ GError **error)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)build_system;
+ GPtrArray *build_targets;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (result));
+
+ build_targets = g_task_propagate_pointer (G_TASK (result), error);
+
+#ifdef IDE_ENABLE_TRACE
+ if (build_targets != NULL)
+ {
+ IDE_TRACE_MSG ("Discovered %u targets", build_targets->len);
+
+ for (guint i = 0; i < build_targets->len; i++)
+ {
+ IdeBuildTarget *target = g_ptr_array_index (build_targets, i);
+ g_autofree gchar *name = NULL;
+
+ g_assert (GBP_IS_CMAKE_BUILD_TARGET (target));
+ g_assert (IDE_IS_BUILD_TARGET (target));
+
+ name = ide_build_target_get_name (target);
+ IDE_TRACE_MSG ("[%u]: %s", i, name);
+ }
+ }
+#endif
+
+ IDE_RETURN (build_targets);
+}
+
+static void
+build_system_iface_init (IdeBuildSystemInterface *iface)
+{
+ iface->get_id = gbp_cmake_build_system_get_id;
+ iface->get_display_name = gbp_cmake_build_system_get_display_name;
+ iface->get_priority = gbp_cmake_build_system_get_priority;
+ iface->get_build_flags_async = gbp_cmake_build_system_get_build_flags_async;
+ iface->get_build_flags_finish = gbp_cmake_build_system_get_build_flags_finish;
+ iface->get_build_targets_async = gbp_cmake_build_system_get_build_targets_async;
+ iface->get_build_targets_finish = gbp_cmake_build_system_get_build_targets_finish;
+}
+
+static void
+gbp_cmake_build_system_notify_pipeline (GbpCMakeBuildSystem *self,
+ GParamSpec *pspec,
+ IdeBuildManager *build_manager)
+{
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (pspec != NULL);
+ g_assert (IDE_IS_BUILD_MANAGER (build_manager));
+
+ /*
+ * We need to regenerate compile commands when the build pipeline
+ * changes so that we get the updated commands.
+ */
+ g_clear_object (&self->compile_commands);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_cmake_build_system_init_worker (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GFile *project_file = task_data;
+ g_autofree gchar *name = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (source_object));
+ g_assert (G_IS_FILE (project_file));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ name = g_file_get_basename (project_file);
+
+ if (ide_str_equal0 (name, "CMakeLists.txt"))
+ {
+ g_task_return_pointer (task, g_object_ref (project_file), g_object_unref);
+ IDE_EXIT;
+ }
+
+ if (g_file_query_file_type (project_file, 0, cancellable) == G_FILE_TYPE_DIRECTORY)
+ {
+ g_autoptr(GFile) cmake_file = g_file_get_child (project_file, "CMakeLists.txt");
+
+ if (g_file_query_exists (cmake_file, cancellable))
+ {
+ g_task_return_pointer (task, g_object_ref (cmake_file), g_object_unref);
+ IDE_EXIT;
+ }
+ }
+
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "%s is not supported by the cmake plugin",
+ name);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_cmake_build_system_init_async (GAsyncInitable *initable,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)initable;
+ g_autoptr(GTask) task = NULL;
+ IdeBuildManager *build_manager;
+ IdeContext *context;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_FILE (self->project_file));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ g_assert (IDE_IS_CONTEXT (context));
+
+ build_manager = ide_context_get_build_manager (context);
+ g_assert (IDE_IS_BUILD_MANAGER (build_manager));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gbp_cmake_build_system_init_async);
+ g_task_set_priority (task, io_priority);
+ g_task_set_task_data (task, g_object_ref (self->project_file), g_object_unref);
+
+ /*
+ * We want to be notified of any changes to the current build manager.
+ * This will let us invalidate our compile_commands.json when it changes.
+ */
+ g_signal_connect_object (build_manager,
+ "notify::pipeline",
+ G_CALLBACK (gbp_cmake_build_system_notify_pipeline),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_task_run_in_thread (task, gbp_cmake_build_system_init_worker);
+
+ IDE_EXIT;
+}
+
+static gboolean
+gbp_cmake_build_system_init_finish (GAsyncInitable *initable,
+ GAsyncResult *result,
+ GError **error)
+{
+ GbpCMakeBuildSystem *self = (GbpCMakeBuildSystem *)initable;
+ g_autoptr(GFile) project_file = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_BUILD_SYSTEM (self));
+ g_assert (G_IS_TASK (result));
+
+ project_file = g_task_propagate_pointer (G_TASK (result), error);
+ if (g_set_object (&self->project_file, project_file))
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PROJECT_FILE]);
+
+ IDE_RETURN (project_file != NULL);
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *iface)
+{
+ iface->init_async = gbp_cmake_build_system_init_async;
+ iface->init_finish = gbp_cmake_build_system_init_finish;
+}
diff --git a/src/plugins/cmake/gbp-cmake-build-system.h b/src/plugins/cmake/gbp-cmake-build-system.h
new file mode 100644
index 0000000..7aad12d
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-build-system.h
@@ -0,0 +1,30 @@
+/* gbp-cmake-build-system.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_CMAKE_BUILD_SYSTEM (gbp_cmake_build_system_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpCMakeBuildSystem, gbp_cmake_build_system, GBP, CMAKE_BUILD_SYSTEM, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/cmake/gbp-cmake-build-target.c b/src/plugins/cmake/gbp-cmake-build-target.c
new file mode 100644
index 0000000..e52eba5
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-build-target.c
@@ -0,0 +1,105 @@
+/* gbp-cmake-build-target.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-cmake-build-target"
+
+#include "gbp-cmake-build-target.h"
+
+struct _GbpCMakeBuildTarget
+{
+ IdeObject parent_instance;
+
+ GFile *install_directory;
+ gchar *name;
+};
+
+static GFile *
+gbp_cmake_build_target_get_install_directory (IdeBuildTarget *build_target)
+{
+ GbpCMakeBuildTarget *self = (GbpCMakeBuildTarget *)build_target;
+
+ g_assert (GBP_IS_CMAKE_BUILD_TARGET (self));
+
+ return self->install_directory ? g_object_ref (self->install_directory) : NULL;
+}
+
+static gchar *
+gbp_cmake_build_target_get_name (IdeBuildTarget *build_target)
+{
+ GbpCMakeBuildTarget *self = (GbpCMakeBuildTarget *)build_target;
+
+ g_assert (GBP_IS_CMAKE_BUILD_TARGET (self));
+
+ return self->name ? g_strdup (self->name) : NULL;
+}
+
+static void
+build_target_iface_init (IdeBuildTargetInterface *iface)
+{
+ iface->get_install_directory = gbp_cmake_build_target_get_install_directory;
+ iface->get_name = gbp_cmake_build_target_get_name;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GbpCMakeBuildTarget, gbp_cmake_build_target, IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_BUILD_TARGET, build_target_iface_init))
+
+static void
+gbp_cmake_build_target_finalize (GObject *object)
+{
+ GbpCMakeBuildTarget *self = (GbpCMakeBuildTarget *)object;
+
+ g_clear_object (&self->install_directory);
+ g_clear_pointer (&self->name, g_free);
+
+ G_OBJECT_CLASS (gbp_cmake_build_target_parent_class)->finalize (object);
+}
+
+static void
+gbp_cmake_build_target_class_init (GbpCMakeBuildTargetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gbp_cmake_build_target_finalize;
+}
+
+static void
+gbp_cmake_build_target_init (GbpCMakeBuildTarget *self)
+{
+}
+
+IdeBuildTarget *
+gbp_cmake_build_target_new (IdeContext *context,
+ GFile *install_directory,
+ gchar *name)
+{
+ GbpCMakeBuildTarget *self;
+
+ g_return_val_if_fail (!context || IDE_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (G_IS_FILE (install_directory), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ self = g_object_new (GBP_TYPE_CMAKE_BUILD_TARGET,
+ "context", context,
+ NULL);
+
+ g_set_object (&self->install_directory, install_directory);
+ self->name = g_strdup (name);
+
+ return IDE_BUILD_TARGET (self);
+}
diff --git a/src/plugins/cmake/gbp-cmake-build-target.h b/src/plugins/cmake/gbp-cmake-build-target.h
new file mode 100644
index 0000000..662a0b1
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-build-target.h
@@ -0,0 +1,34 @@
+/* gbp-cmake-build-target.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_CMAKE_BUILD_TARGET (gbp_cmake_build_target_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpCMakeBuildTarget, gbp_cmake_build_target, GBP, CMAKE_BUILD_TARGET, IdeObject)
+
+IdeBuildTarget *gbp_cmake_build_target_new (IdeContext *context,
+ GFile *install_directory,
+ gchar *name);
+
+G_END_DECLS
diff --git a/src/plugins/cmake/gbp-cmake-pipeline-addin.c b/src/plugins/cmake/gbp-cmake-pipeline-addin.c
new file mode 100644
index 0000000..316e86f
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-pipeline-addin.c
@@ -0,0 +1,218 @@
+/* gbp-cmake-pipeline-addin.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-cmake-pipeline-addin"
+
+#include "gbp-cmake-build-system.h"
+#include "gbp-cmake-pipeline-addin.h"
+
+struct _GbpCMakePipelineAddin
+{
+ IdeObject parent_instance;
+};
+
+static const gchar *ninja_names[] = { "ninja-build", "ninja" };
+
+static void build_pipeline_addin_iface_init (IdeBuildPipelineAddinInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GbpCMakePipelineAddin, gbp_cmake_pipeline_addin, IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_BUILD_PIPELINE_ADDIN,
build_pipeline_addin_iface_init))
+
+static void
+gbp_cmake_pipeline_addin_class_init (GbpCMakePipelineAddinClass *klass)
+{
+}
+
+static void
+gbp_cmake_pipeline_addin_init (GbpCMakePipelineAddin *self)
+{
+}
+
+static void
+gbp_cmake_pipeline_addin_stage_query_cb (IdeBuildStage *stage,
+ IdeBuildPipeline *pipeline,
+ GCancellable *cancellable)
+{
+ g_assert (IDE_IS_BUILD_STAGE (stage));
+ g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ /* Defer to ninja to determine completed status */
+ ide_build_stage_set_completed (stage, FALSE);
+}
+
+static void
+gbp_cmake_pipeline_addin_load (IdeBuildPipelineAddin *addin,
+ IdeBuildPipeline *pipeline)
+{
+ GbpCMakePipelineAddin *self = (GbpCMakePipelineAddin *)addin;
+ g_autoptr(IdeSubprocessLauncher) configure_launcher = NULL;
+ g_autoptr(IdeSubprocessLauncher) build_launcher = NULL;
+ g_autoptr(IdeSubprocessLauncher) install_launcher = NULL;
+ g_autoptr(IdeSubprocessLauncher) clean_launcher = NULL;
+ g_autoptr(IdeBuildStage) configure_stage = NULL;
+ g_autoptr(IdeBuildStage) build_stage = NULL;
+ g_autoptr(IdeBuildStage) install_stage = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autofree gchar *prefix_option = NULL;
+ g_autofree gchar *build_ninja = NULL;
+ IdeBuildSystem *build_system;
+ IdeConfiguration *configuration;
+ IdeContext *context;
+ IdeRuntime *runtime;
+ const gchar *ninja = NULL;
+ const gchar *config_opts;
+ const gchar *prefix;
+ const gchar *srcdir;
+ guint id;
+ gint parallelism;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_CMAKE_PIPELINE_ADDIN (self));
+ g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+
+ build_system = ide_context_get_build_system (context);
+ if (!GBP_IS_CMAKE_BUILD_SYSTEM (build_system))
+ IDE_GOTO (failure);
+
+ configuration = ide_build_pipeline_get_configuration (pipeline);
+ runtime = ide_build_pipeline_get_runtime (pipeline);
+ srcdir = ide_build_pipeline_get_srcdir (pipeline);
+
+ g_assert (IDE_IS_CONFIGURATION (configuration));
+ g_assert (IDE_IS_RUNTIME (runtime));
+ g_assert (srcdir != NULL);
+
+ for (guint i = 0; i < G_N_ELEMENTS (ninja_names); i++)
+ {
+ if (ide_runtime_contains_program_in_path (runtime, ninja_names[i], NULL))
+ {
+ ninja = ninja_names[i];
+ break;
+ }
+ }
+
+ if (ninja == NULL)
+ {
+ g_debug ("Failed to locate ninja. CMake building is disabled.");
+ IDE_EXIT;
+ }
+
+ if (NULL == (configure_launcher = ide_build_pipeline_create_launcher (pipeline, &error)) ||
+ NULL == (build_launcher = ide_build_pipeline_create_launcher (pipeline, &error)) ||
+ NULL == (clean_launcher = ide_build_pipeline_create_launcher (pipeline, &error)) ||
+ NULL == (install_launcher = ide_build_pipeline_create_launcher (pipeline, &error)))
+ IDE_GOTO (failure);
+
+ prefix = ide_configuration_get_prefix (configuration);
+ config_opts = ide_configuration_get_config_opts (configuration);
+ parallelism = ide_configuration_get_parallelism (configuration);
+
+ /* Setup our configure stage. */
+
+ prefix_option = g_strdup_printf ("-DCMAKE_INSTALL_PREFIX=%s", prefix);
+
+ ide_subprocess_launcher_push_argv (configure_launcher, "cmake");
+ ide_subprocess_launcher_push_argv (configure_launcher, "-G");
+ ide_subprocess_launcher_push_argv (configure_launcher, "Ninja");
+ ide_subprocess_launcher_push_argv (configure_launcher, ".");
+ ide_subprocess_launcher_push_argv (configure_launcher, srcdir);
+ ide_subprocess_launcher_push_argv (configure_launcher, "-DCMAKE_EXPORT_COMPILE_COMMANDS=1");
+ ide_subprocess_launcher_push_argv (configure_launcher, "-DCMAKE_BUILD_TYPE=RelWithDebInfo");
+ ide_subprocess_launcher_push_argv (configure_launcher, prefix_option);
+
+ if (!ide_str_empty0 (config_opts))
+ {
+ g_auto(GStrv) argv = NULL;
+ gint argc;
+
+ if (!g_shell_parse_argv (config_opts, &argc, &argv, &error))
+ IDE_GOTO (failure);
+
+ ide_subprocess_launcher_push_args (configure_launcher, (const gchar * const *)argv);
+ }
+
+ configure_stage = ide_build_stage_launcher_new (context, configure_launcher);
+
+ build_ninja = ide_build_pipeline_build_builddir_path (pipeline, "build.ninja", NULL);
+ if (g_file_test (build_ninja, G_FILE_TEST_IS_REGULAR))
+ ide_build_stage_set_completed (configure_stage, TRUE);
+
+ id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_CONFIGURE, 0, configure_stage);
+ ide_build_pipeline_addin_track (addin, id);
+
+ /* Setup our build stage */
+
+ ide_subprocess_launcher_push_argv (build_launcher, ninja);
+ ide_subprocess_launcher_push_argv (clean_launcher, ninja);
+
+ if (parallelism > 0)
+ {
+ g_autofree gchar *j = g_strdup_printf ("-j%u", parallelism);
+
+ ide_subprocess_launcher_push_argv (build_launcher, j);
+ ide_subprocess_launcher_push_argv (clean_launcher, j);
+ }
+
+ ide_subprocess_launcher_push_argv (clean_launcher, "clean");
+
+ build_stage = ide_build_stage_launcher_new (context, build_launcher);
+
+ ide_build_stage_launcher_set_clean_launcher (IDE_BUILD_STAGE_LAUNCHER (build_stage), clean_launcher);
+ ide_build_stage_set_check_stdout (build_stage, TRUE);
+
+ g_signal_connect (build_stage,
+ "query",
+ G_CALLBACK (gbp_cmake_pipeline_addin_stage_query_cb),
+ NULL);
+
+ id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_BUILD, 0, build_stage);
+ ide_build_pipeline_addin_track (addin, id);
+
+ /* Setup our install stage */
+
+ ide_subprocess_launcher_push_argv (install_launcher, ninja);
+ ide_subprocess_launcher_push_argv (install_launcher, "install");
+
+ install_stage = ide_build_stage_launcher_new (context, install_launcher);
+
+ g_signal_connect (install_stage,
+ "query",
+ G_CALLBACK (gbp_cmake_pipeline_addin_stage_query_cb),
+ NULL);
+
+ id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_INSTALL, 0, install_stage);
+ ide_build_pipeline_addin_track (addin, id);
+
+ IDE_EXIT;
+
+failure:
+ if (error != NULL)
+ g_warning ("Failed to setup cmake build pipeline: %s", error->message);
+}
+
+static void
+build_pipeline_addin_iface_init (IdeBuildPipelineAddinInterface *iface)
+{
+ iface->load = gbp_cmake_pipeline_addin_load;
+}
+
diff --git a/src/plugins/cmake/gbp-cmake-pipeline-addin.h b/src/plugins/cmake/gbp-cmake-pipeline-addin.h
new file mode 100644
index 0000000..b0a55c5
--- /dev/null
+++ b/src/plugins/cmake/gbp-cmake-pipeline-addin.h
@@ -0,0 +1,30 @@
+/* gbp-cmake-pipeline-addin.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ * Copyright (C) 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_CMAKE_PIPELINE_ADDIN (gbp_cmake_pipeline_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpCMakePipelineAddin, gbp_cmake_pipeline_addin, GBP, CMAKE_PIPELINE_ADDIN, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/cmake/meson.build b/src/plugins/cmake/meson.build
index 559066d..97ae3a2 100644
--- a/src/plugins/cmake/meson.build
+++ b/src/plugins/cmake/meson.build
@@ -1,13 +1,22 @@
if get_option('with_cmake')
-install_data('cmake_plugin.py', install_dir: plugindir)
-
-configure_file(
- input: 'cmake.plugin',
- output: 'cmake.plugin',
- configuration: configuration_data(),
- install: true,
- install_dir: plugindir,
+cmake_resources = gnome.compile_resources(
+ 'gbp-cmake-resources',
+ 'cmake.gresource.xml',
+ c_name: 'gbp_cmake',
)
+cmake_sources = [
+ 'cmake-plugin.c',
+ 'gbp-cmake-build-system.c',
+ 'gbp-cmake-build-system.h',
+ 'gbp-cmake-build-target.c',
+ 'gbp-cmake-build-target.h',
+ 'gbp-cmake-pipeline-addin.c',
+ 'gbp-cmake-pipeline-addin.h',
+]
+
+gnome_builder_plugins_sources += files(cmake_sources)
+gnome_builder_plugins_sources += cmake_resources[0]
+
endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]