[anjuta] build-basic-autotools: Move build functions in a separate file
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] build-basic-autotools: Move build functions in a separate file
- Date: Fri, 17 Jun 2011 19:18:12 +0000 (UTC)
commit 49ee44b1b52494b6e1358bb0e3fea2a66f6709a2
Author: SÃbastien Granjoux <seb sfo free fr>
Date: Wed Jun 15 22:55:59 2011 +0200
build-basic-autotools: Move build functions in a separate file
plugins/build-basic-autotools/Makefile.am | 2 +
plugins/build-basic-autotools/build.c | 997 +++++++++++++++++++++++++++++
plugins/build-basic-autotools/build.h | 105 +++
plugins/build-basic-autotools/plugin.c | 987 +----------------------------
plugins/build-basic-autotools/plugin.h | 16 +
5 files changed, 1142 insertions(+), 965 deletions(-)
---
diff --git a/plugins/build-basic-autotools/Makefile.am b/plugins/build-basic-autotools/Makefile.am
index afde7dc..c55204a 100644
--- a/plugins/build-basic-autotools/Makefile.am
+++ b/plugins/build-basic-autotools/Makefile.am
@@ -44,6 +44,8 @@ libanjuta_build_basic_autotools_la_SOURCES = \
plugin.h \
executer.c \
executer.h \
+ build.c \
+ build.h \
build-options.c \
build-options.h \
configuration-list.c \
diff --git a/plugins/build-basic-autotools/build.c b/plugins/build-basic-autotools/build.c
new file mode 100644
index 0000000..e3805b3
--- /dev/null
+++ b/plugins/build-basic-autotools/build.c
@@ -0,0 +1,997 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ build.c
+ Copyright (C) 2000 Naba Kumar
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include <config.h>
+
+#include "build.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <libanjuta/interfaces/ianjuta-project-manager.h>
+#include <libanjuta/interfaces/ianjuta-language.h>
+
+#include "program.h"
+#include "build-options.h"
+
+/* Types
+ *---------------------------------------------------------------------------*/
+
+typedef struct
+{
+ gchar *args;
+ GFile *file;
+ BuildFunc func;
+} BuildConfigureAndBuild;
+
+/* Constants
+ *---------------------------------------------------------------------------*/
+
+#define PREF_INSTALL_ROOT "build-install-root"
+#define PREF_INSTALL_ROOT_COMMAND "build-install-root-command"
+
+#define DEFAULT_COMMAND_COMPILE "make"
+#define DEFAULT_COMMAND_BUILD "make"
+#define DEFAULT_COMMAND_IS_BUILT "make -q"
+#define DEFAULT_COMMAND_BUILD_TARBALL "make dist"
+#define DEFAULT_COMMAND_INSTALL "make install"
+#define DEFAULT_COMMAND_CONFIGURE "configure"
+#define DEFAULT_COMMAND_GENERATE "autogen.sh"
+#define DEFAULT_COMMAND_CLEAN "make clean"
+#define DEFAULT_COMMAND_DISTCLEAN "make distclean"
+#define DEFAULT_COMMAND_AUTORECONF "autoreconf -i --force"
+
+#define CHOOSE_COMMAND(plugin,command) \
+ ((plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) ? \
+ (plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) \
+ : \
+ (DEFAULT_COMMAND_##command))
+
+/* Helper functions
+ *---------------------------------------------------------------------------*/
+
+gboolean
+directory_has_makefile_am (BasicAutotoolsPlugin *bb_plugin, GFile *dir)
+{
+ GFile *file;
+ gboolean exists;
+
+ /* We need configure.ac or configure.in too */
+ if (bb_plugin->project_root_dir == NULL) return FALSE;
+
+ exists = TRUE;
+ file = g_file_get_child (bb_plugin->project_root_dir, "configure.ac");
+ if (!g_file_query_exists (file, NULL))
+ {
+ g_object_unref (file);
+ file = g_file_get_child (bb_plugin->project_root_dir, "configure.in");
+ if (!g_file_query_exists (file, NULL))
+ {
+ exists = FALSE;
+ }
+ }
+ g_object_unref (file);
+
+ /* Check for Makefile.am or GNUmakefile.am */
+ file = g_file_get_child (dir, "Makefile.am");
+ if (!g_file_query_exists (file, NULL))
+ {
+ g_object_unref (file);
+ file = g_file_get_child (dir, "GNUmakefile.am");
+ if (!g_file_query_exists (file, NULL))
+ {
+ exists = FALSE;
+ }
+ }
+ g_object_unref (file);
+
+ return exists;
+}
+
+gboolean
+directory_has_makefile (GFile *dir)
+{
+ GFile *file;
+ gboolean exists;
+
+ exists = TRUE;
+ file = g_file_get_child (dir, "Makefile");
+ if (!g_file_query_exists (file, NULL))
+ {
+ g_object_unref (file);
+ file = g_file_get_child (dir, "makefile");
+ if (!g_file_query_exists (file, NULL))
+ {
+ g_object_unref (file);
+ file = g_file_get_child (dir, "MAKEFILE");
+ if (!g_file_query_exists (file, NULL))
+ {
+ exists = FALSE;
+ }
+ }
+ }
+ g_object_unref (file);
+
+ return exists;
+}
+
+static gboolean
+directory_has_file (GFile *dir, const gchar *filename)
+{
+ GFile *file;
+ gboolean exists;
+
+ file = g_file_get_child (dir, filename);
+ exists = g_file_query_exists (file, NULL);
+ g_object_unref (file);
+
+ return exists;
+}
+
+static gchar*
+shell_quotef (const gchar *format,...)
+{
+ va_list args;
+ gchar *str;
+ gchar *quoted_str;
+
+ va_start (args, format);
+ str = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ quoted_str = g_shell_quote (str);
+ g_free (str);
+
+ return quoted_str;
+}
+
+
+/* Return build path from a source directory */
+static GFile *
+build_file_from_directory (BasicAutotoolsPlugin *plugin, GFile *directory)
+{
+ GFile *build_file;
+
+ if ((plugin->project_root_dir != NULL) &&
+ (plugin->project_build_dir != NULL) &&
+ !g_file_has_prefix (directory, plugin->project_build_dir) &&
+ g_file_has_prefix (directory, plugin->project_root_dir))
+ {
+ gchar *relative;
+
+ relative = g_file_get_relative_path (plugin->project_root_dir, directory);
+ build_file = g_file_resolve_relative_path (plugin->project_build_dir, relative);
+ g_free (relative);
+ }
+ else if ((plugin->project_root_dir != NULL) &&
+ (plugin->project_build_dir != NULL) &&
+ g_file_equal (directory, plugin->project_root_dir))
+ {
+ build_file = g_object_ref (plugin->project_build_dir);
+ }
+ else
+ {
+ build_file = g_object_ref (directory);
+ }
+
+ return build_file;
+}
+
+/* Return build path and target from a GFile */
+GFile *
+build_file_from_file (BasicAutotoolsPlugin *plugin, GFile *file, gchar **target)
+{
+
+ if (target != NULL) *target = NULL;
+
+ if (file == NULL)
+ {
+ /* Use project root directory */
+ return build_file_from_directory (plugin, plugin->project_root_dir);
+ }
+ else if (g_file_query_file_type (file, 0, NULL) == G_FILE_TYPE_DIRECTORY)
+ {
+ return build_file_from_directory (plugin, file);
+ }
+ else
+ {
+ GFile *parent = NULL;
+ GFile *build_file;
+ IAnjutaProjectManager* projman;
+
+ projman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+ IAnjutaProjectManager,
+ NULL);
+
+ if (projman != NULL)
+ {
+ /* Use the project manager to find the group file */
+ GFile *child;
+
+ for (child = g_object_ref (file); child != NULL;)
+ {
+ GFile *group;
+ AnjutaProjectNodeType type;
+
+ type = ianjuta_project_manager_get_target_type (projman, child, NULL);
+ if (type == ANJUTA_PROJECT_GROUP) break;
+ group = ianjuta_project_manager_get_parent (projman, child, NULL);
+ g_object_unref (child);
+ child = group;
+ }
+ parent = child;
+ }
+
+ if (parent == NULL)
+ {
+ /* Fallback use parent directory */
+ parent = g_file_get_parent (file);
+ }
+
+ if (parent != NULL)
+ {
+ if (target != NULL) *target = g_file_get_relative_path (parent, file);
+ build_file = build_file_from_directory (plugin, parent);
+ g_object_unref (parent);
+
+ return build_file;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+}
+
+/* Save & Build
+ *---------------------------------------------------------------------------*/
+
+static BuildContext*
+build_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
+ gboolean with_view, GError **err)
+{
+ BuildContext *context;
+ gboolean ok;
+
+ context = build_get_context (bplugin, prog->work_dir, with_view);
+
+ build_set_command_in_context (context, prog);
+ ok = build_execute_command_in_context (context, err);
+
+ if (ok)
+ {
+ return context;
+ }
+ else
+ {
+ build_context_destroy (context);
+
+ return NULL;
+ }
+}
+
+static BuildContext*
+build_save_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
+ gboolean with_view, GError **err)
+{
+ BuildContext *context;
+
+ context = build_get_context (bplugin, prog->work_dir, with_view);
+
+ build_set_command_in_context (context, prog);
+ if (!build_save_and_execute_command_in_context (context, err))
+ {
+ build_context_destroy (context);
+ context = NULL;
+ }
+
+ return context;
+}
+
+static void
+build_execute_after_command (GObject *sender,
+ IAnjutaBuilderHandle handle,
+ GError *error,
+ gpointer user_data)
+{
+ BuildProgram *prog = (BuildProgram *)user_data;
+ BuildContext *context = (BuildContext *)handle;
+
+ /* Try next command even if the first one fail (make distclean return an error) */
+ if ((error == NULL) || (error->code != IANJUTA_BUILDER_ABORTED))
+ {
+ build_set_command_in_context (context, prog);
+ build_execute_command_in_context (context, NULL);
+ }
+ else
+ {
+ build_program_free (prog);
+ }
+}
+
+static BuildContext*
+build_save_distclean_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
+ gboolean with_view, GError **err)
+{
+ BuildContext *context;
+ gchar *root_path;
+ gboolean same;
+
+ context = build_get_context (bplugin, prog->work_dir, with_view);
+ root_path = g_file_get_path (bplugin->project_root_dir);
+ same = strcmp (prog->work_dir, root_path) != 0;
+ g_free (root_path);
+
+ if (!same && directory_has_file (bplugin->project_root_dir, "config.status"))
+ {
+ BuildProgram *new_prog;
+
+ // Need to run make clean before
+ if (!anjuta_util_dialog_boolean_question (GTK_WINDOW (ANJUTA_PLUGIN (bplugin)->shell), _("Before using this new configuration, the default one needs to be removed. Do you want to do that ?"), NULL))
+ {
+ if (err)
+ *err = g_error_new (ianjuta_builder_error_quark (),
+ IANJUTA_BUILDER_CANCELED,
+ _("Command canceled by user"));
+
+ return NULL;
+ }
+ new_prog = build_program_new_with_command (bplugin->project_root_dir,
+ "%s",
+ CHOOSE_COMMAND (bplugin, DISTCLEAN));
+ build_program_set_callback (new_prog, build_execute_after_command, prog);
+ prog = new_prog;
+ }
+
+ build_set_command_in_context (context, prog);
+
+ build_save_and_execute_command_in_context (context, NULL);
+
+ return context;
+}
+
+
+/* Build commands
+ *---------------------------------------------------------------------------*/
+
+BuildContext*
+build_build_file_or_dir (BasicAutotoolsPlugin *plugin,
+ GFile *file,
+ IAnjutaBuilderCallback callback, gpointer user_data,
+ GError **err)
+{
+ GFile *build_dir;
+ gchar *target;
+ BuildProgram *prog;
+ BuildContext *context;
+
+ build_dir = build_file_from_file (plugin, file, &target);
+ prog = build_program_new_with_command (build_dir,
+ "%s %s",
+ CHOOSE_COMMAND (plugin, BUILD),
+ target ? target : "");
+ build_program_set_callback (prog, callback, user_data);
+
+ context = build_save_and_execute_command (plugin, prog, TRUE, err);
+ g_free (target);
+ g_object_unref (build_dir);
+
+ return context;
+}
+
+
+
+BuildContext*
+build_is_file_built (BasicAutotoolsPlugin *plugin, GFile *file,
+ IAnjutaBuilderCallback callback, gpointer user_data,
+ GError **err)
+{
+ GFile *build_dir;
+ gchar *target;
+ BuildProgram *prog;
+ BuildContext *context;
+
+ build_dir = build_file_from_file (plugin, file, &target);
+ prog = build_program_new_with_command (build_dir,
+ "%s %s",
+ CHOOSE_COMMAND (plugin, IS_BUILT),
+ target ? target : "");
+ build_program_set_callback (prog, callback, user_data);
+
+ context = build_save_and_execute_command (plugin, prog, FALSE, err);
+
+ g_free (target);
+ g_object_unref (build_dir);
+
+ return context;
+}
+
+
+
+static gchar*
+get_root_install_command(BasicAutotoolsPlugin *bplugin)
+{
+ GSettings* settings = bplugin->settings;
+ if (g_settings_get_boolean (settings, PREF_INSTALL_ROOT))
+ {
+ gchar* command = g_settings_get_string (settings, PREF_INSTALL_ROOT_COMMAND);
+ return command;
+ }
+ else
+ return g_strdup("");
+}
+
+BuildContext*
+build_install_dir (BasicAutotoolsPlugin *plugin, GFile *dir,
+ IAnjutaBuilderCallback callback, gpointer user_data,
+ GError **err)
+{
+ BuildContext *context;
+ gchar* root = get_root_install_command(plugin);
+ GFile *build_dir;
+ BuildProgram *prog;
+ GString *command;
+
+ if ((root != NULL) && (*root != '\0'))
+ {
+ gchar *first = root;
+ gchar *ptr = root;
+
+ /* Replace %s or %q by respectively, the install command or the
+ * quoted install command. % character can be escaped by using two %. */
+ command = g_string_new (NULL);
+ while (*ptr)
+ {
+ if (*ptr++ == '%')
+ {
+ if (*ptr == 's')
+ {
+ /* Not quoted command */
+ g_string_append_len (command, first, ptr - 1 - first);
+ g_string_append (command, CHOOSE_COMMAND (plugin, INSTALL));
+ first = ptr + 1;
+ }
+ else if (*ptr == 'q')
+ {
+ /* quoted command */
+ gchar *quoted;
+
+ quoted = g_shell_quote (CHOOSE_COMMAND (plugin, INSTALL));
+ g_string_append_len (command, first, ptr - 1 - first);
+ g_string_append (command, quoted);
+ g_free (quoted);
+ first = ptr + 1;
+ }
+ else if (*ptr == '%')
+ {
+ /* escaped % */
+ g_string_append_len (command, first, ptr - 1 - first);
+ first = ptr;
+ }
+ ptr++;
+ }
+ }
+ g_string_append (command, first);
+ }
+ else
+ {
+ command = g_string_new (CHOOSE_COMMAND (plugin, INSTALL));
+ }
+
+ build_dir = build_file_from_file (plugin, dir, NULL);
+ prog = build_program_new_with_command (build_dir,
+ "%s",
+ command->str);
+ build_program_set_callback (prog, callback, user_data);
+
+ context = build_save_and_execute_command (plugin, prog, TRUE, err);
+
+ g_string_free (command, TRUE);
+ g_object_unref (build_dir);
+ g_free (root);
+
+ return context;
+}
+
+
+
+BuildContext*
+build_clean_dir (BasicAutotoolsPlugin *plugin, GFile *file,
+ GError **err)
+{
+ BuildContext *context;
+ GFile *build_dir;
+
+ build_dir = build_file_from_file (plugin, file, NULL);
+ context = build_execute_command (plugin,
+ build_program_new_with_command (build_dir,
+ "%s",
+ CHOOSE_COMMAND (plugin, CLEAN)),
+ TRUE, err);
+ g_object_unref (build_dir);
+
+ return context;
+}
+
+
+
+static void
+build_remove_build_dir (GObject *sender,
+ IAnjutaBuilderHandle context,
+ GError *error,
+ gpointer user_data)
+{
+ /* FIXME: Should we remove build dir on distclean ? */
+}
+
+BuildContext*
+build_distclean (BasicAutotoolsPlugin *plugin)
+{
+ BuildContext *context;
+ BuildProgram *prog;
+
+ prog = build_program_new_with_command (plugin->project_build_dir,
+ "%s",
+ CHOOSE_COMMAND (plugin, DISTCLEAN));
+ build_program_set_callback (prog, build_remove_build_dir, plugin);
+
+ context = build_execute_command (plugin, prog, TRUE, NULL);
+
+ return context;
+}
+
+
+
+BuildContext*
+build_tarball (BasicAutotoolsPlugin *plugin)
+{
+ BuildContext *context;
+
+ context = build_save_and_execute_command (plugin,
+ build_program_new_with_command (plugin->project_build_dir,
+ "%s",
+ CHOOSE_COMMAND (plugin, BUILD_TARBALL)),
+ TRUE, NULL);
+
+ return context;
+}
+
+BuildContext*
+build_compile_file (BasicAutotoolsPlugin *plugin, GFile *file)
+{
+ BuildContext *context = NULL;
+ GFile *target = NULL;
+ gboolean ret;
+ IAnjutaProjectManager* projman;
+
+ g_return_val_if_fail (file != NULL, FALSE);
+ ret = FALSE;
+
+ projman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+ IAnjutaProjectManager,
+ NULL);
+ if (projman != NULL)
+ {
+ /* Use the project manager to find the object file */
+ target = ianjuta_project_manager_get_parent (projman, file, NULL);
+ if (target != NULL)
+ {
+ if (ianjuta_project_manager_get_target_type (projman, target, NULL) != ANJUTA_PROJECT_OBJECT)
+ {
+ g_object_unref (target);
+ target = NULL;
+ }
+ }
+ }
+ else
+ {
+ /* Use language plugin trying to find an object file */
+ IAnjutaLanguage* langman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+ IAnjutaLanguage,
+ NULL);
+
+ if (langman != NULL)
+ {
+ GFileInfo* file_info;
+
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+ if (file_info)
+ {
+ gint id = ianjuta_language_get_from_mime_type (langman,
+ g_file_info_get_content_type (file_info),
+ NULL);
+ if (id > 0)
+ {
+ const gchar *obj_ext = ianjuta_language_get_make_target (langman, id, NULL);
+ gchar *basename;
+ gchar *ext;
+ gchar *targetname;
+ GFile *parent;
+
+ basename = g_file_get_basename (file);
+ ext = strrchr (basename, '.');
+ if ((ext != NULL) && (ext != basename)) *ext = '\0';
+ targetname = g_strconcat (basename, obj_ext, NULL);
+ g_free (basename);
+ parent = g_file_get_parent (file);
+ target = g_file_get_child (parent, targetname);
+ g_object_unref (parent);
+ g_free (targetname);
+ }
+ }
+ g_object_unref (file_info);
+ }
+ }
+
+ if (target != NULL)
+ {
+ /* If file has no extension, take it as target itself */
+ BuildProgram *prog;
+ GFile *build_dir;
+ gchar *target_name;
+
+ /* Find target directory */
+ build_dir = build_file_from_file (plugin, target, &target_name);
+
+ prog = build_program_new_with_command (build_dir, "%s %s",
+ CHOOSE_COMMAND(plugin, COMPILE),
+ (target_name == NULL) ? "" : target_name);
+ g_free (target_name);
+ g_object_unref (build_dir);
+ context = build_save_and_execute_command (plugin, prog, TRUE, NULL);
+ ret = TRUE;
+ g_object_unref (target);
+ }
+
+ if (ret == FALSE)
+ {
+ /* FIXME: Prompt the user to create a Makefile with a wizard
+ (if there is no Makefile in the directory) or to add a target
+ rule in the above hash table, eg. editing the preferences, if
+ there is target extension defined for that file extension.
+ */
+ GtkWindow *window;
+ gchar *filename;
+
+ filename = g_file_get_path (file);
+ window = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);
+ anjuta_util_dialog_error (window, _("Cannot compile \"%s\": No compile rule defined for this file type."), filename);
+ g_free (filename);
+ }
+
+ return context;
+}
+
+
+void
+build_project_configured (GObject *sender,
+ IAnjutaBuilderHandle handle,
+ GError *error,
+ gpointer user_data)
+{
+ BuildConfigureAndBuild *pack = (BuildConfigureAndBuild *)user_data;
+
+ if (error == NULL)
+ {
+ BuildContext *context = (BuildContext *)handle;
+ BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)(context == NULL ? (void *)sender : (void *)build_context_get_plugin (context));
+ GValue *value;
+ gchar *uri;
+
+ /* FIXME: check if build directory correspond, configuration could have changed */
+ value = g_new0 (GValue, 1);
+ g_value_init (value, G_TYPE_STRING);
+
+ uri = build_configuration_list_get_build_uri (plugin->configurations, build_configuration_list_get_selected (plugin->configurations));
+ g_value_set_string (value, uri);
+ g_free (uri);
+
+ anjuta_shell_add_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_BUILDER_ROOT_URI, value, NULL);
+
+ build_update_configuration_menu (plugin);
+
+ /* Call build function if necessary */
+ if ((pack) && (pack->func != NULL)) pack->func (plugin, pack->file, NULL, NULL, NULL);
+ }
+
+ if (pack)
+ {
+ g_free (pack->args);
+ g_object_unref (pack->file);
+ g_free (pack);
+ }
+}
+
+BuildContext*
+build_configure_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
+ BuildFunc func, GFile *file)
+{
+ BuildContext *context;
+ BuildProgram *prog;
+ BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
+ gchar *quote;
+ gchar *root_path;
+
+ root_path = g_file_get_path (plugin->project_root_dir);
+ quote = shell_quotef ("%s%s%s",
+ root_path,
+ G_DIR_SEPARATOR_S,
+ CHOOSE_COMMAND (plugin, CONFIGURE));
+
+ prog = build_program_new_with_command (dir,
+ "%s %s",
+ quote,
+ args);
+ g_free (quote);
+ g_free (root_path);
+ pack->args = NULL;
+ pack->func = func;
+ pack->file = g_object_ref (file);
+ build_program_set_callback (prog, build_project_configured, pack);
+
+ context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
+
+ return context;
+}
+
+
+
+static void
+build_configure_after_autogen (GObject *sender,
+ IAnjutaBuilderHandle handle,
+ GError *error,
+ gpointer user_data)
+{
+ BuildConfigureAndBuild *pack = (BuildConfigureAndBuild *)user_data;
+
+ if (error == NULL)
+ {
+ BuildContext *context = (BuildContext *)handle;
+ BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)build_context_get_plugin (context);
+ struct stat conf_stat, log_stat;
+ gchar *root_path;
+ gchar *filename;
+ gboolean has_configure;
+
+ root_path = g_file_get_path (plugin->project_root_dir);
+ filename = g_build_filename (root_path, "configure", NULL);
+ has_configure = stat (filename, &conf_stat) == 0;
+ g_free (filename);
+ g_free (root_path);
+
+ if (has_configure)
+ {
+ gboolean older;
+
+ filename = g_build_filename (build_context_get_work_dir (context), "config.status", NULL);
+ older =(stat (filename, &log_stat) != 0) || (log_stat.st_mtime < conf_stat.st_mtime);
+ g_free (filename);
+
+ if (older)
+ {
+ /* configure has not be run, run it */
+ BuildProgram *prog;
+ gchar *quote;
+ GFile *work_file;
+
+ quote = shell_quotef ("%s%s%s",
+ plugin->project_root_dir,
+ G_DIR_SEPARATOR_S,
+ CHOOSE_COMMAND (plugin, CONFIGURE));
+
+ work_file = g_file_new_for_path (build_context_get_work_dir (context));
+ prog = build_program_new_with_command (work_file,
+ "%s %s",
+ quote,
+ pack != NULL ? pack->args : NULL);
+ g_object_unref (work_file);
+ g_free (quote);
+ build_program_set_callback (prog, build_project_configured, pack);
+
+ build_set_command_in_context (context, prog);
+ build_execute_command_in_context (context, NULL);
+ }
+ else
+ {
+ /* run next command if needed */
+ build_project_configured (sender, handle, NULL, pack);
+ }
+
+ return;
+ }
+ anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), _("Cannot configure project: Missing configure script in %s."), plugin->project_root_dir);
+ }
+
+ if (pack)
+ {
+ g_free (pack->args);
+ g_object_unref (pack->file);
+ g_free (pack);
+ }
+}
+
+BuildContext*
+build_generate_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
+ BuildFunc func, GFile *file)
+{
+ BuildContext *context;
+ BuildProgram *prog;
+ BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
+
+ if (directory_has_file (plugin->project_root_dir, "autogen.sh"))
+ {
+ gchar *quote;
+
+ quote = shell_quotef ("%s%s%s",
+ plugin->project_root_dir,
+ G_DIR_SEPARATOR_S,
+ CHOOSE_COMMAND (plugin, GENERATE));
+ prog = build_program_new_with_command (dir,
+ "%s %s",
+ quote,
+ args);
+ g_free (quote);
+ }
+ else
+ {
+ prog = build_program_new_with_command (dir,
+ "%s %s",
+ CHOOSE_COMMAND (plugin, AUTORECONF),
+ args);
+ }
+ pack->args = g_strdup (args);
+ pack->func = func;
+ pack->file = g_object_ref (file);
+ build_program_set_callback (prog, build_configure_after_autogen, pack);
+
+ context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
+
+ return context;
+}
+
+void
+build_configure_dialog (BasicAutotoolsPlugin *plugin, BuildFunc func, GFile *file)
+{
+ GtkWindow *parent;
+ gboolean run_autogen = FALSE;
+ const gchar *project_root;
+ GValue value = {0,};
+ const gchar *old_config_name;
+
+ run_autogen = !directory_has_file (plugin->project_root_dir, "configure");
+
+ anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, &value, NULL);
+
+ /* In case, a project is not loaded */
+ if (!G_VALUE_HOLDS_STRING (&value)) return;
+
+ project_root = g_value_get_string (&value);
+ parent = GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell);
+
+ old_config_name = build_configuration_get_name (build_configuration_list_get_selected (plugin->configurations));
+ if (build_dialog_configure (parent, project_root, plugin->configurations, &run_autogen))
+ {
+ BuildConfiguration *config;
+ BuildContext* context;
+ GFile *build_file;
+ gchar *build_uri;
+ const gchar *args;
+
+ config = build_configuration_list_get_selected (plugin->configurations);
+ build_uri = build_configuration_list_get_build_uri (plugin->configurations, config);
+ build_file = g_file_new_for_uri (build_uri);
+ g_free (build_uri);
+
+ args = build_configuration_get_args (config);
+
+ if (run_autogen)
+ {
+ context = build_generate_dir (plugin, build_file, args, func, file);
+ }
+ else
+ {
+ context = build_configure_dir (plugin, build_file, args, func, file);
+ }
+ g_object_unref (build_file);
+
+ if (context == NULL)
+ {
+ /* Restore previous configuration */
+ build_configuration_list_select (plugin->configurations, old_config_name);
+ }
+ }
+
+}
+
+/* Run configure if needed and then the build command */
+void
+build_configure_and_build (BasicAutotoolsPlugin *plugin, BuildFunc func, GFile *file)
+{
+ GFile *build_dir;
+ gboolean has_makefile;
+ gboolean has_makefile_am;
+
+ /* Get build directory and check for makefiles */
+ build_dir = build_file_from_file (plugin, file, NULL);
+ has_makefile = directory_has_makefile (build_dir);
+ has_makefile_am = directory_has_makefile_am (plugin, build_dir);
+ g_object_unref (build_dir);
+
+ if (has_makefile)
+ {
+ /* Some build functions have less arguments but
+ * it is not a problem in C */
+ func (plugin, file, NULL, NULL, NULL);
+ }
+ else if (has_makefile_am && (plugin->project_root_dir != NULL))
+ {
+ /* Run configure first */
+ build_configure_dialog (plugin, func, file);
+ }
+}
+
+/* Configuration commands
+ *---------------------------------------------------------------------------*/
+
+GList*
+build_list_configuration (BasicAutotoolsPlugin *plugin)
+{
+ BuildConfiguration *cfg;
+ GList *list = NULL;
+
+ for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
+ {
+ const gchar *name = build_configuration_get_name (cfg);
+
+ if (name != NULL) list = g_list_prepend (list, (gpointer)name);
+ }
+
+ return list;
+}
+
+const gchar*
+build_get_uri_configuration (BasicAutotoolsPlugin *plugin, const gchar *uri)
+{
+ BuildConfiguration *cfg;
+ BuildConfiguration *uri_cfg = NULL;
+ gsize uri_len = 0;
+
+ /* Check all configurations as other configuration directories are
+ * normally child of default configuration directory */
+ for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
+ {
+ const gchar *root = build_configuration_list_get_build_uri (plugin->configurations, cfg);
+ gsize len = root != NULL ? strlen (root) : 0;
+
+ if ((len > uri_len) && (strncmp (uri, root, len) == 0))
+ {
+ uri_cfg = cfg;
+ uri_len = len;
+ }
+ }
+
+ return uri_len == 0 ? NULL : build_configuration_get_name (uri_cfg);
+}
+
diff --git a/plugins/build-basic-autotools/build.h b/plugins/build-basic-autotools/build.h
new file mode 100644
index 0000000..94cd385
--- /dev/null
+++ b/plugins/build-basic-autotools/build.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ build.h
+ Copyright (C) 2000 Naba Kumar
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __BUILD_H__
+#define __BUILD_H__
+
+#include <glib.h>
+
+
+#include <libanjuta/interfaces/ianjuta-builder.h>
+
+#include "plugin.h"
+
+
+GFile * build_file_from_file (BasicAutotoolsPlugin *plugin, GFile *file, gchar **target);
+gboolean directory_has_makefile (GFile *dir);
+gboolean directory_has_makefile_am (BasicAutotoolsPlugin *bb_plugin, GFile *dir);
+
+
+/* Build function type */
+typedef BuildContext* (*BuildFunc) (BasicAutotoolsPlugin *plugin, GFile *file,
+ IAnjutaBuilderCallback callback, gpointer user_data,
+ GError **err);
+
+BuildContext* build_build_file_or_dir (BasicAutotoolsPlugin *plugin,
+ GFile *file,
+ IAnjutaBuilderCallback callback,
+ gpointer user_data,
+ GError **err);
+
+BuildContext* build_is_file_built (BasicAutotoolsPlugin *plugin,
+ GFile *file,
+ IAnjutaBuilderCallback callback,
+ gpointer user_data,
+ GError **err);
+
+BuildContext* build_install_dir (BasicAutotoolsPlugin *plugin,
+ GFile *dir,
+ IAnjutaBuilderCallback callback,
+ gpointer user_data,
+ GError **err);
+
+BuildContext* build_clean_dir (BasicAutotoolsPlugin *plugin,
+ GFile *file,
+ GError **err);
+
+BuildContext* build_distclean (BasicAutotoolsPlugin *plugin);
+
+BuildContext* build_tarball (BasicAutotoolsPlugin *plugin);
+
+BuildContext* build_compile_file (BasicAutotoolsPlugin *plugin,
+ GFile *file);
+
+BuildContext* build_configure_dir (BasicAutotoolsPlugin *plugin,
+ GFile *dir,
+ const gchar *args,
+ BuildFunc func,
+ GFile *file);
+
+BuildContext* build_generate_dir (BasicAutotoolsPlugin *plugin,
+ GFile *dir,
+ const gchar *args,
+ BuildFunc func,
+ GFile *file);
+
+void build_project_configured (GObject *sender,
+ IAnjutaBuilderHandle handle,
+ GError *error,
+ gpointer user_data);
+
+void build_configure_and_build (BasicAutotoolsPlugin *plugin,
+ BuildFunc func,
+ GFile *file);
+
+
+void build_configure_dialog (BasicAutotoolsPlugin *plugin, BuildFunc func, GFile *file);
+
+
+GList* build_list_configuration (BasicAutotoolsPlugin *plugin);
+const gchar* build_get_uri_configuration (BasicAutotoolsPlugin *plugin, const gchar *uri);
+
+
+
+
+
+
+
+#endif
diff --git a/plugins/build-basic-autotools/plugin.c b/plugins/build-basic-autotools/plugin.c
index 4c701c4..259ea1f 100644
--- a/plugins/build-basic-autotools/plugin.c
+++ b/plugins/build-basic-autotools/plugin.c
@@ -48,6 +48,7 @@
#include "build-options.h"
#include "executer.h"
#include "program.h"
+#include "build.h"
#include <sys/wait.h>
#if defined(__FreeBSD__)
@@ -62,8 +63,6 @@
#define MAX_BUILD_PANES 3
#define PREF_SCHEMA "org.gnome.anjuta.build"
#define PREF_INDICATORS_AUTOMATIC "build-indicators-automatic"
-#define PREF_INSTALL_ROOT "build-install-root"
-#define PREF_INSTALL_ROOT_COMMAND "build-install-root-command"
#define PREF_PARALLEL_MAKE "build-parallel-make"
#define PREF_PARALLEL_MAKE_JOB "build-parallel-make-job"
#define PREF_TRANSLATE_MESSAGE "build-translate-message"
@@ -76,23 +75,6 @@
#define PARALLEL_MAKE_CHECK "preferences_toggle:bool:0:0:build-parallel-make"
#define PARALLEL_MAKE_SPIN "preferences_spin:int:1:0:build-parallel-make-job"
-#define DEFAULT_COMMAND_COMPILE "make"
-#define DEFAULT_COMMAND_BUILD "make"
-#define DEFAULT_COMMAND_IS_BUILT "make -q"
-#define DEFAULT_COMMAND_BUILD_TARBALL "make dist"
-#define DEFAULT_COMMAND_INSTALL "make install"
-#define DEFAULT_COMMAND_CONFIGURE "configure"
-#define DEFAULT_COMMAND_GENERATE "autogen.sh"
-#define DEFAULT_COMMAND_CLEAN "make clean"
-#define DEFAULT_COMMAND_DISTCLEAN "make distclean"
-#define DEFAULT_COMMAND_AUTORECONF "autoreconf -i --force"
-
-#define CHOOSE_COMMAND(plugin,command) \
- ((plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) ? \
- (plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) \
- : \
- (DEFAULT_COMMAND_##command))
-
static gpointer parent_class;
typedef struct
@@ -119,7 +101,7 @@ typedef struct
} BuildIndicatorLocation;
/* Command processing */
-typedef struct
+struct _BuildContext
{
AnjutaPlugin *plugin;
@@ -142,23 +124,10 @@ typedef struct
/* Saved files */
gint file_saved;
-} BuildContext;
-
-/* Build function type */
-typedef BuildContext* (*BuildFunc) (BasicAutotoolsPlugin *plugin, GFile *file,
- IAnjutaBuilderCallback callback, gpointer user_data,
- GError **err);
-
-typedef struct
-{
- gchar *args;
- GFile *file;
- BuildFunc func;
-} BuildConfigureAndBuild;
+};
/* Declarations */
static void update_project_ui (BasicAutotoolsPlugin *bb_plugin);
-static void update_configuration_menu (BasicAutotoolsPlugin *plugin);
static GList *patterns_list = NULL;
@@ -190,84 +159,6 @@ static void on_root_check_toggled(GtkWidget* toggle_button, GtkWidget* entry)
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button)));
}
-static gboolean
-directory_has_makefile_am (BasicAutotoolsPlugin *bb_plugin, GFile *dir)
-{
- GFile *file;
- gboolean exists;
-
- /* We need configure.ac or configure.in too */
- if (bb_plugin->project_root_dir == NULL) return FALSE;
-
- exists = TRUE;
- file = g_file_get_child (bb_plugin->project_root_dir, "configure.ac");
- if (!g_file_query_exists (file, NULL))
- {
- g_object_unref (file);
- file = g_file_get_child (bb_plugin->project_root_dir, "configure.in");
- if (!g_file_query_exists (file, NULL))
- {
- exists = FALSE;
- }
- }
- g_object_unref (file);
-
- /* Check for Makefile.am or GNUmakefile.am */
- file = g_file_get_child (dir, "Makefile.am");
- if (!g_file_query_exists (file, NULL))
- {
- g_object_unref (file);
- file = g_file_get_child (dir, "GNUmakefile.am");
- if (!g_file_query_exists (file, NULL))
- {
- exists = FALSE;
- }
- }
- g_object_unref (file);
-
- return exists;
-}
-
-static gboolean
-directory_has_makefile (GFile *dir)
-{
- GFile *file;
- gboolean exists;
-
- exists = TRUE;
- file = g_file_get_child (dir, "Makefile");
- if (!g_file_query_exists (file, NULL))
- {
- g_object_unref (file);
- file = g_file_get_child (dir, "makefile");
- if (!g_file_query_exists (file, NULL))
- {
- g_object_unref (file);
- file = g_file_get_child (dir, "MAKEFILE");
- if (!g_file_query_exists (file, NULL))
- {
- exists = FALSE;
- }
- }
- }
- g_object_unref (file);
-
- return exists;
-}
-
-static gboolean
-directory_has_file (GFile *dir, const gchar *filename)
-{
- GFile *file;
- gboolean exists;
-
- file = g_file_get_child (dir, filename);
- exists = g_file_query_exists (file, NULL);
- g_object_unref (file);
-
- return exists;
-}
-
static gchar*
escape_label (const gchar *str)
{
@@ -298,23 +189,6 @@ escape_label (const gchar *str)
return g_string_free (ret, FALSE);
}
-static gchar*
-shell_quotef (const gchar *format,...)
-{
- va_list args;
- gchar *str;
- gchar *quoted_str;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- va_end (args);
-
- quoted_str = g_shell_quote (str);
- g_free (str);
-
- return quoted_str;
-}
-
/* Indicator locations reported by the build */
static BuildIndicatorLocation*
@@ -447,6 +321,18 @@ build_context_get_dir (BuildContext *context, const gchar *key)
return dir_stack->data;
}
+const gchar *
+build_context_get_work_dir (BuildContext* context)
+{
+ return context->program->work_dir;
+}
+
+AnjutaPlugin *
+build_context_get_plugin (BuildContext* context)
+{
+ return context->plugin;
+}
+
static void
build_context_cancel (BuildContext *context)
{
@@ -537,7 +423,7 @@ build_context_destroy_view (BuildContext *context)
return TRUE;
}
-static void
+void
build_context_destroy (BuildContext *context)
{
if (build_context_destroy_command (context))
@@ -1279,7 +1165,7 @@ build_get_context_with_message(BasicAutotoolsPlugin *plugin, const gchar *dir)
return context;
}
-static BuildContext*
+BuildContext*
build_get_context (BasicAutotoolsPlugin *plugin, const gchar *dir,
gboolean with_view)
{
@@ -1331,14 +1217,14 @@ build_get_context (BasicAutotoolsPlugin *plugin, const gchar *dir,
return context;
}
-static void
+void
build_set_command_in_context (BuildContext* context, BuildProgram *prog)
{
context->program = prog;
context->used = TRUE;
}
-static gboolean
+gboolean
build_execute_command_in_context (BuildContext* context, GError **err)
{
GSettings* settings = ANJUTA_PLUGIN_BASIC_AUTOTOOLS(context->plugin)->settings;
@@ -1420,7 +1306,7 @@ build_delayed_execute_command (IAnjutaFileSavable *savable, GFile *file, gpointe
}
}
-static gboolean
+gboolean
build_save_and_execute_command_in_context (BuildContext* context, GError **err)
{
IAnjutaDocumentManager *docman;
@@ -1455,208 +1341,6 @@ build_save_and_execute_command_in_context (BuildContext* context, GError **err)
return TRUE;
}
-/* Return build path from a source directory */
-static GFile *
-build_file_from_directory (BasicAutotoolsPlugin *plugin, GFile *directory)
-{
- GFile *build_file;
-
- if ((plugin->project_root_dir != NULL) &&
- (plugin->project_build_dir != NULL) &&
- !g_file_has_prefix (directory, plugin->project_build_dir) &&
- g_file_has_prefix (directory, plugin->project_root_dir))
- {
- gchar *relative;
-
- relative = g_file_get_relative_path (plugin->project_root_dir, directory);
- build_file = g_file_resolve_relative_path (plugin->project_build_dir, relative);
- g_free (relative);
- }
- else if ((plugin->project_root_dir != NULL) &&
- (plugin->project_build_dir != NULL) &&
- g_file_equal (directory, plugin->project_root_dir))
- {
- build_file = g_object_ref (plugin->project_build_dir);
- }
- else
- {
- build_file = g_object_ref (directory);
- }
-
- return build_file;
-}
-
-/* Return build path and target from a GFile */
-static GFile *
-build_file_from_file (BasicAutotoolsPlugin *plugin, GFile *file, gchar **target)
-{
-
- if (target != NULL) *target = NULL;
-
- if (file == NULL)
- {
- /* Use project root directory */
- return build_file_from_directory (plugin, plugin->project_root_dir);
- }
- else if (g_file_query_file_type (file, 0, NULL) == G_FILE_TYPE_DIRECTORY)
- {
- return build_file_from_directory (plugin, file);
- }
- else
- {
- GFile *parent = NULL;
- GFile *build_file;
- IAnjutaProjectManager* projman;
-
- projman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
- IAnjutaProjectManager,
- NULL);
-
- if (projman != NULL)
- {
- /* Use the project manager to find the group file */
- GFile *child;
-
- for (child = g_object_ref (file); child != NULL;)
- {
- GFile *group;
- AnjutaProjectNodeType type;
-
- type = ianjuta_project_manager_get_target_type (projman, child, NULL);
- if (type == ANJUTA_PROJECT_GROUP) break;
- group = ianjuta_project_manager_get_parent (projman, child, NULL);
- g_object_unref (child);
- child = group;
- }
- parent = child;
- }
-
- if (parent == NULL)
- {
- /* Fallback use parent directory */
- parent = g_file_get_parent (file);
- }
-
- if (parent != NULL)
- {
- if (target != NULL) *target = g_file_get_relative_path (parent, file);
- build_file = build_file_from_directory (plugin, parent);
- g_object_unref (parent);
-
- return build_file;
- }
- else
- {
- return NULL;
- }
- }
-}
-
-
-static BuildContext*
-build_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
- gboolean with_view, GError **err)
-{
- BuildContext *context;
- gboolean ok;
-
- context = build_get_context (bplugin, prog->work_dir, with_view);
-
- build_set_command_in_context (context, prog);
- ok = build_execute_command_in_context (context, err);
-
- if (ok)
- {
- return context;
- }
- else
- {
- build_context_destroy (context);
-
- return NULL;
- }
-}
-
-static BuildContext*
-build_save_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
- gboolean with_view, GError **err)
-{
- BuildContext *context;
-
- context = build_get_context (bplugin, prog->work_dir, with_view);
-
- build_set_command_in_context (context, prog);
- if (!build_save_and_execute_command_in_context (context, err))
- {
- build_context_destroy (context);
- context = NULL;
- }
-
- return context;
-}
-
-static void
-build_execute_after_command (GObject *sender,
- IAnjutaBuilderHandle handle,
- GError *error,
- gpointer user_data)
-{
- BuildProgram *prog = (BuildProgram *)user_data;
- BuildContext *context = (BuildContext *)handle;
-
- /* Try next command even if the first one fail (make distclean return an error) */
- if ((error == NULL) || (error->code != IANJUTA_BUILDER_ABORTED))
- {
- build_set_command_in_context (context, prog);
- build_execute_command_in_context (context, NULL);
- }
- else
- {
- build_program_free (prog);
- }
-}
-
-static BuildContext*
-build_save_distclean_and_execute_command (BasicAutotoolsPlugin* bplugin, BuildProgram *prog,
- gboolean with_view, GError **err)
-{
- BuildContext *context;
- gchar *root_path;
- gboolean same;
-
- context = build_get_context (bplugin, prog->work_dir, with_view);
- root_path = g_file_get_path (bplugin->project_root_dir);
- same = strcmp (prog->work_dir, root_path) != 0;
- g_free (root_path);
-
- if (!same && directory_has_file (bplugin->project_root_dir, "config.status"))
- {
- BuildProgram *new_prog;
-
- // Need to run make clean before
- if (!anjuta_util_dialog_boolean_question (GTK_WINDOW (ANJUTA_PLUGIN (bplugin)->shell), _("Before using this new configuration, the default one needs to be removed. Do you want to do that ?"), NULL))
- {
- if (err)
- *err = g_error_new (ianjuta_builder_error_quark (),
- IANJUTA_BUILDER_CANCELED,
- _("Command canceled by user"));
-
- return NULL;
- }
- new_prog = build_program_new_with_command (bplugin->project_root_dir,
- "%s",
- CHOOSE_COMMAND (bplugin, DISTCLEAN));
- build_program_set_callback (new_prog, build_execute_after_command, prog);
- prog = new_prog;
- }
-
- build_set_command_in_context (context, prog);
-
- build_save_and_execute_command_in_context (context, NULL);
-
- return context;
-}
-
static void
build_cancel_command (BasicAutotoolsPlugin* bplugin, BuildContext *context,
GError **err)
@@ -1678,633 +1362,6 @@ build_cancel_command (BasicAutotoolsPlugin* bplugin, BuildContext *context,
g_return_if_reached ();
}
-/* Build commands
- *---------------------------------------------------------------------------*/
-
-static BuildContext*
-build_build_file_or_dir (BasicAutotoolsPlugin *plugin,
- GFile *file,
- IAnjutaBuilderCallback callback, gpointer user_data,
- GError **err)
-{
- GFile *build_dir;
- gchar *target;
- BuildProgram *prog;
- BuildContext *context;
-
- build_dir = build_file_from_file (plugin, file, &target);
- prog = build_program_new_with_command (build_dir,
- "%s %s",
- CHOOSE_COMMAND (plugin, BUILD),
- target ? target : "");
- build_program_set_callback (prog, callback, user_data);
-
- context = build_save_and_execute_command (plugin, prog, TRUE, err);
- g_free (target);
- g_object_unref (build_dir);
-
- return context;
-}
-
-
-
-static BuildContext*
-build_is_file_built (BasicAutotoolsPlugin *plugin, GFile *file,
- IAnjutaBuilderCallback callback, gpointer user_data,
- GError **err)
-{
- GFile *build_dir;
- gchar *target;
- BuildProgram *prog;
- BuildContext *context;
-
- build_dir = build_file_from_file (plugin, file, &target);
- prog = build_program_new_with_command (build_dir,
- "%s %s",
- CHOOSE_COMMAND (plugin, IS_BUILT),
- target ? target : "");
- build_program_set_callback (prog, callback, user_data);
-
- context = build_save_and_execute_command (plugin, prog, FALSE, err);
-
- g_free (target);
- g_object_unref (build_dir);
-
- return context;
-}
-
-
-
-static gchar*
-get_root_install_command(BasicAutotoolsPlugin *bplugin)
-{
- GSettings* settings = bplugin->settings;
- if (g_settings_get_boolean (settings, PREF_INSTALL_ROOT))
- {
- gchar* command = g_settings_get_string (settings, PREF_INSTALL_ROOT_COMMAND);
- return command;
- }
- else
- return g_strdup("");
-}
-
-static BuildContext*
-build_install_dir (BasicAutotoolsPlugin *plugin, GFile *dir,
- IAnjutaBuilderCallback callback, gpointer user_data,
- GError **err)
-{
- BuildContext *context;
- gchar* root = get_root_install_command(plugin);
- GFile *build_dir;
- BuildProgram *prog;
- GString *command;
-
- if ((root != NULL) && (*root != '\0'))
- {
- gchar *first = root;
- gchar *ptr = root;
-
- /* Replace %s or %q by respectively, the install command or the
- * quoted install command. % character can be escaped by using two %. */
- command = g_string_new (NULL);
- while (*ptr)
- {
- if (*ptr++ == '%')
- {
- if (*ptr == 's')
- {
- /* Not quoted command */
- g_string_append_len (command, first, ptr - 1 - first);
- g_string_append (command, CHOOSE_COMMAND (plugin, INSTALL));
- first = ptr + 1;
- }
- else if (*ptr == 'q')
- {
- /* quoted command */
- gchar *quoted;
-
- quoted = g_shell_quote (CHOOSE_COMMAND (plugin, INSTALL));
- g_string_append_len (command, first, ptr - 1 - first);
- g_string_append (command, quoted);
- g_free (quoted);
- first = ptr + 1;
- }
- else if (*ptr == '%')
- {
- /* escaped % */
- g_string_append_len (command, first, ptr - 1 - first);
- first = ptr;
- }
- ptr++;
- }
- }
- g_string_append (command, first);
- }
- else
- {
- command = g_string_new (CHOOSE_COMMAND (plugin, INSTALL));
- }
-
- build_dir = build_file_from_file (plugin, dir, NULL);
- prog = build_program_new_with_command (build_dir,
- "%s",
- command->str);
- build_program_set_callback (prog, callback, user_data);
-
- context = build_save_and_execute_command (plugin, prog, TRUE, err);
-
- g_string_free (command, TRUE);
- g_object_unref (build_dir);
- g_free (root);
-
- return context;
-}
-
-
-
-static BuildContext*
-build_clean_dir (BasicAutotoolsPlugin *plugin, GFile *file,
- GError **err)
-{
- BuildContext *context;
- GFile *build_dir;
-
- build_dir = build_file_from_file (plugin, file, NULL);
- context = build_execute_command (plugin,
- build_program_new_with_command (build_dir,
- "%s",
- CHOOSE_COMMAND (plugin, CLEAN)),
- TRUE, err);
- g_object_unref (build_dir);
-
- return context;
-}
-
-
-
-static void
-build_remove_build_dir (GObject *sender,
- IAnjutaBuilderHandle context,
- GError *error,
- gpointer user_data)
-{
- /* FIXME: Should we remove build dir on distclean ? */
-}
-
-static BuildContext*
-build_distclean (BasicAutotoolsPlugin *plugin)
-{
- BuildContext *context;
- BuildProgram *prog;
-
- prog = build_program_new_with_command (plugin->project_build_dir,
- "%s",
- CHOOSE_COMMAND (plugin, DISTCLEAN));
- build_program_set_callback (prog, build_remove_build_dir, plugin);
-
- context = build_execute_command (plugin, prog, TRUE, NULL);
-
- return context;
-}
-
-
-
-static BuildContext*
-build_tarball (BasicAutotoolsPlugin *plugin)
-{
- BuildContext *context;
-
- context = build_save_and_execute_command (plugin,
- build_program_new_with_command (plugin->project_build_dir,
- "%s",
- CHOOSE_COMMAND (plugin, BUILD_TARBALL)),
- TRUE, NULL);
-
- return context;
-}
-
-static BuildContext*
-build_compile_file (BasicAutotoolsPlugin *plugin, GFile *file)
-{
- BuildContext *context = NULL;
- GFile *target = NULL;
- gboolean ret;
- IAnjutaProjectManager* projman;
-
- g_return_val_if_fail (file != NULL, FALSE);
- ret = FALSE;
-
- projman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
- IAnjutaProjectManager,
- NULL);
- if (projman != NULL)
- {
- /* Use the project manager to find the object file */
- target = ianjuta_project_manager_get_parent (projman, file, NULL);
- if (target != NULL)
- {
- if (ianjuta_project_manager_get_target_type (projman, target, NULL) != ANJUTA_PROJECT_OBJECT)
- {
- g_object_unref (target);
- target = NULL;
- }
- }
- }
- else
- {
- /* Use language plugin trying to find an object file */
- IAnjutaLanguage* langman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
- IAnjutaLanguage,
- NULL);
-
- if (langman != NULL)
- {
- GFileInfo* file_info;
-
- file_info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- G_FILE_QUERY_INFO_NONE,
- NULL,
- NULL);
- if (file_info)
- {
- gint id = ianjuta_language_get_from_mime_type (langman,
- g_file_info_get_content_type (file_info),
- NULL);
- if (id > 0)
- {
- const gchar *obj_ext = ianjuta_language_get_make_target (langman, id, NULL);
- gchar *basename;
- gchar *ext;
- gchar *targetname;
- GFile *parent;
-
- basename = g_file_get_basename (file);
- ext = strrchr (basename, '.');
- if ((ext != NULL) && (ext != basename)) *ext = '\0';
- targetname = g_strconcat (basename, obj_ext, NULL);
- g_free (basename);
- parent = g_file_get_parent (file);
- target = g_file_get_child (parent, targetname);
- g_object_unref (parent);
- g_free (targetname);
- }
- }
- g_object_unref (file_info);
- }
- }
-
- if (target != NULL)
- {
- /* If file has no extension, take it as target itself */
- BuildProgram *prog;
- GFile *build_dir;
- gchar *target_name;
-
- /* Find target directory */
- build_dir = build_file_from_file (plugin, target, &target_name);
-
- prog = build_program_new_with_command (build_dir, "%s %s",
- CHOOSE_COMMAND(plugin, COMPILE),
- (target_name == NULL) ? "" : target_name);
- g_free (target_name);
- g_object_unref (build_dir);
- context = build_save_and_execute_command (plugin, prog, TRUE, NULL);
- ret = TRUE;
- g_object_unref (target);
- }
-
- if (ret == FALSE)
- {
- /* FIXME: Prompt the user to create a Makefile with a wizard
- (if there is no Makefile in the directory) or to add a target
- rule in the above hash table, eg. editing the preferences, if
- there is target extension defined for that file extension.
- */
- GtkWindow *window;
- gchar *filename;
-
- filename = g_file_get_path (file);
- window = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);
- anjuta_util_dialog_error (window, _("Cannot compile \"%s\": No compile rule defined for this file type."), filename);
- g_free (filename);
- }
-
- return context;
-}
-
-
-
-static void
-build_project_configured (GObject *sender,
- IAnjutaBuilderHandle handle,
- GError *error,
- gpointer user_data)
-{
- BuildConfigureAndBuild *pack = (BuildConfigureAndBuild *)user_data;
-
- if (error == NULL)
- {
- BuildContext *context = (BuildContext *)handle;
- BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)(context == NULL ? (void *)sender : (void *)context->plugin);
- GValue *value;
- gchar *uri;
-
- /* FIXME: check if build directory correspond, configuration could have changed */
- value = g_new0 (GValue, 1);
- g_value_init (value, G_TYPE_STRING);
-
- uri = build_configuration_list_get_build_uri (plugin->configurations, build_configuration_list_get_selected (plugin->configurations));
- g_value_set_string (value, uri);
- g_free (uri);
-
- anjuta_shell_add_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_BUILDER_ROOT_URI, value, NULL);
-
- update_configuration_menu (plugin);
-
- /* Call build function if necessary */
- if ((pack) && (pack->func != NULL)) pack->func (plugin, pack->file, NULL, NULL, NULL);
- }
-
- if (pack)
- {
- g_free (pack->args);
- g_object_unref (pack->file);
- g_free (pack);
- }
-}
-
-static BuildContext*
-build_configure_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
- BuildFunc func, GFile *file)
-{
- BuildContext *context;
- BuildProgram *prog;
- BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
- gchar *quote;
- gchar *root_path;
-
- root_path = g_file_get_path (plugin->project_root_dir);
- quote = shell_quotef ("%s%s%s",
- root_path,
- G_DIR_SEPARATOR_S,
- CHOOSE_COMMAND (plugin, CONFIGURE));
-
- prog = build_program_new_with_command (dir,
- "%s %s",
- quote,
- args);
- g_free (quote);
- g_free (root_path);
- pack->args = NULL;
- pack->func = func;
- pack->file = g_object_ref (file);
- build_program_set_callback (prog, build_project_configured, pack);
-
- context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
-
- return context;
-}
-
-
-
-static void
-build_configure_after_autogen (GObject *sender,
- IAnjutaBuilderHandle handle,
- GError *error,
- gpointer user_data)
-{
- BuildConfigureAndBuild *pack = (BuildConfigureAndBuild *)user_data;
-
- if (error == NULL)
- {
- BuildContext *context = (BuildContext *)handle;
- BasicAutotoolsPlugin *plugin = (BasicAutotoolsPlugin *)context->plugin;
- struct stat conf_stat, log_stat;
- gchar *root_path;
- gchar *filename;
- gboolean has_configure;
-
- root_path = g_file_get_path (plugin->project_root_dir);
- filename = g_build_filename (root_path, "configure", NULL);
- has_configure = stat (filename, &conf_stat) == 0;
- g_free (filename);
- g_free (root_path);
-
- if (has_configure)
- {
- gboolean older;
-
- filename = g_build_filename (context->program->work_dir, "config.status", NULL);
- older =(stat (filename, &log_stat) != 0) || (log_stat.st_mtime < conf_stat.st_mtime);
- g_free (filename);
-
- if (older)
- {
- /* configure has not be run, run it */
- BuildProgram *prog;
- gchar *quote;
- GFile *work_file;
-
- quote = shell_quotef ("%s%s%s",
- plugin->project_root_dir,
- G_DIR_SEPARATOR_S,
- CHOOSE_COMMAND (plugin, CONFIGURE));
-
- work_file = g_file_new_for_path (context->program->work_dir);
- prog = build_program_new_with_command (work_file,
- "%s %s",
- quote,
- pack != NULL ? pack->args : NULL);
- g_object_unref (work_file);
- g_free (quote);
- build_program_set_callback (prog, build_project_configured, pack);
-
- build_set_command_in_context (context, prog);
- build_execute_command_in_context (context, NULL);
- }
- else
- {
- /* run next command if needed */
- build_project_configured (sender, handle, NULL, pack);
- }
-
- return;
- }
- anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), _("Cannot configure project: Missing configure script in %s."), plugin->project_root_dir);
- }
-
- if (pack)
- {
- g_free (pack->args);
- g_object_unref (pack->file);
- g_free (pack);
- }
-}
-
-static BuildContext*
-build_generate_dir (BasicAutotoolsPlugin *plugin, GFile *dir, const gchar *args,
- BuildFunc func, GFile *file)
-{
- BuildContext *context;
- BuildProgram *prog;
- BuildConfigureAndBuild *pack = g_new0 (BuildConfigureAndBuild, 1);
-
- if (directory_has_file (plugin->project_root_dir, "autogen.sh"))
- {
- gchar *quote;
-
- quote = shell_quotef ("%s%s%s",
- plugin->project_root_dir,
- G_DIR_SEPARATOR_S,
- CHOOSE_COMMAND (plugin, GENERATE));
- prog = build_program_new_with_command (dir,
- "%s %s",
- quote,
- args);
- g_free (quote);
- }
- else
- {
- prog = build_program_new_with_command (dir,
- "%s %s",
- CHOOSE_COMMAND (plugin, AUTORECONF),
- args);
- }
- pack->args = g_strdup (args);
- pack->func = func;
- pack->file = g_object_ref (file);
- build_program_set_callback (prog, build_configure_after_autogen, pack);
-
- context = build_save_distclean_and_execute_command (plugin, prog, TRUE, NULL);
-
- return context;
-}
-
-static void
-build_configure_dialog (BasicAutotoolsPlugin *plugin, BuildFunc func, GFile *file)
-{
- GtkWindow *parent;
- gboolean run_autogen = FALSE;
- const gchar *project_root;
- GValue value = {0,};
- const gchar *old_config_name;
-
- run_autogen = !directory_has_file (plugin->project_root_dir, "configure");
-
- anjuta_shell_get_value (ANJUTA_PLUGIN (plugin)->shell, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, &value, NULL);
-
- /* In case, a project is not loaded */
- if (!G_VALUE_HOLDS_STRING (&value)) return;
-
- project_root = g_value_get_string (&value);
- parent = GTK_WINDOW (ANJUTA_PLUGIN(plugin)->shell);
-
- old_config_name = build_configuration_get_name (build_configuration_list_get_selected (plugin->configurations));
- if (build_dialog_configure (parent, project_root, plugin->configurations, &run_autogen))
- {
- BuildConfiguration *config;
- BuildContext* context;
- GFile *build_file;
- gchar *build_uri;
- const gchar *args;
-
- config = build_configuration_list_get_selected (plugin->configurations);
- build_uri = build_configuration_list_get_build_uri (plugin->configurations, config);
- build_file = g_file_new_for_uri (build_uri);
- g_free (build_uri);
-
- args = build_configuration_get_args (config);
-
- if (run_autogen)
- {
- context = build_generate_dir (plugin, build_file, args, func, file);
- }
- else
- {
- context = build_configure_dir (plugin, build_file, args, func, file);
- }
- g_object_unref (build_file);
-
- if (context == NULL)
- {
- /* Restore previous configuration */
- build_configuration_list_select (plugin->configurations, old_config_name);
- }
- }
-
-}
-
-/* Run configure if needed and then the build command */
-static void
-build_configure_and_build (BasicAutotoolsPlugin *plugin, BuildFunc func, GFile *file)
-{
- GFile *build_dir;
- gboolean has_makefile;
- gboolean has_makefile_am;
-
- /* Get build directory and check for makefiles */
- build_dir = build_file_from_file (plugin, file, NULL);
- has_makefile = directory_has_makefile (build_dir);
- has_makefile_am = directory_has_makefile_am (plugin, build_dir);
- g_object_unref (build_dir);
-
- if (has_makefile)
- {
- /* Some build functions have less arguments but
- * it is not a problem in C */
- func (plugin, file, NULL, NULL, NULL);
- }
- else if (has_makefile_am && (plugin->project_root_dir != NULL))
- {
- /* Run configure first */
- build_configure_dialog (plugin, func, file);
- }
-}
-
-/* Configuration commands
- *---------------------------------------------------------------------------*/
-
-static GList*
-build_list_configuration (BasicAutotoolsPlugin *plugin)
-{
- BuildConfiguration *cfg;
- GList *list = NULL;
-
- for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
- {
- const gchar *name = build_configuration_get_name (cfg);
-
- if (name != NULL) list = g_list_prepend (list, (gpointer)name);
- }
-
- return list;
-}
-
-static const gchar*
-build_get_uri_configuration (BasicAutotoolsPlugin *plugin, const gchar *uri)
-{
- BuildConfiguration *cfg;
- BuildConfiguration *uri_cfg = NULL;
- gsize uri_len = 0;
-
- /* Check all configurations as other configuration directories are
- * normally child of default configuration directory */
- for (cfg = build_configuration_list_get_first (plugin->configurations); cfg != NULL; cfg = build_configuration_next (cfg))
- {
- const gchar *root = build_configuration_list_get_build_uri (plugin->configurations, cfg);
- gsize len = root != NULL ? strlen (root) : 0;
-
- if ((len > uri_len) && (strncmp (uri, root, len) == 0))
- {
- uri_cfg = cfg;
- uri_len = len;
- }
- }
-
- return uri_len == 0 ? NULL : build_configuration_get_name (uri_cfg);
-}
-
/* User actions
*---------------------------------------------------------------------------*/
@@ -2768,8 +1825,8 @@ update_project_ui (BasicAutotoolsPlugin *bb_plugin)
update_module_ui (bb_plugin);
}
-static void
-update_configuration_menu (BasicAutotoolsPlugin *plugin)
+void
+build_update_configuration_menu (BasicAutotoolsPlugin *plugin)
{
GtkWidget *submenu = NULL;
BuildConfiguration *cfg;
diff --git a/plugins/build-basic-autotools/plugin.h b/plugins/build-basic-autotools/plugin.h
index 3669dc7..8a029e1 100644
--- a/plugins/build-basic-autotools/plugin.h
+++ b/plugins/build-basic-autotools/plugin.h
@@ -23,8 +23,10 @@
#include <libanjuta/anjuta-plugin.h>
#include <libanjuta/interfaces/ianjuta-buildable.h>
+#include <libanjuta/interfaces/ianjuta-editor.h>
#include "configuration-list.h"
+#include "program.h"
#define BUILDER_FILE PACKAGE_DATA_DIR "/glade/anjuta-build-basic-autotools-plugin.ui"
@@ -88,4 +90,18 @@ struct _BasicAutotoolsPluginClass{
AnjutaPluginClass parent_class;
};
+typedef struct _BuildContext BuildContext;
+
+BuildContext* build_get_context (BasicAutotoolsPlugin *plugin, const gchar *dir, gboolean with_view);
+void build_context_destroy (BuildContext *context);
+
+void build_set_command_in_context (BuildContext* context, BuildProgram *prog);
+gboolean build_execute_command_in_context (BuildContext* context, GError **err);
+gboolean build_save_and_execute_command_in_context (BuildContext* context, GError **err);
+const gchar *build_context_get_work_dir (BuildContext* context);
+AnjutaPlugin *build_context_get_plugin (BuildContext* context);
+
+
+void build_update_configuration_menu (BasicAutotoolsPlugin *plugin);
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]