1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2000 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include <libanjuta/interfaces/ianjuta-project-manager.h>
30 #include <libanjuta/interfaces/ianjuta-language.h>
31 #include <libanjuta/anjuta-utils.h>
34 #include "build-options.h"
37 *---------------------------------------------------------------------------*/
44 IAnjutaBuilderCallback callback
;
46 } BuildConfigureAndBuild
;
49 *---------------------------------------------------------------------------*/
51 #define PREF_INSTALL_ROOT "install-root"
52 #define PREF_INSTALL_ROOT_COMMAND "install-root-command"
54 #define DEFAULT_COMMAND_COMPILE "make"
55 #define DEFAULT_COMMAND_BUILD "make"
56 #define DEFAULT_COMMAND_IS_BUILT "make -q"
57 #define DEFAULT_COMMAND_BUILD_TARBALL "make dist"
58 #define DEFAULT_COMMAND_INSTALL "make install"
59 #define DEFAULT_COMMAND_CONFIGURE "configure"
60 #define DEFAULT_COMMAND_GENERATE "autogen.sh"
61 #define DEFAULT_COMMAND_CLEAN "make clean"
62 #define DEFAULT_COMMAND_DISTCLEAN "make distclean"
63 #define DEFAULT_COMMAND_CHECK "make check"
64 #define DEFAULT_COMMAND_AUTORECONF "autoreconf -i --force"
66 #define RUN_PROGRAM_URI "run_program_uri"
68 #define CHOOSE_COMMAND(plugin,command) \
69 ((plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) ? \
70 (plugin->commands[(IANJUTA_BUILDABLE_COMMAND_##command)]) \
72 (DEFAULT_COMMAND_##command))
75 *---------------------------------------------------------------------------*/
77 /* Normalize a file to use project directory if it is a child */
79 normalize_project_file (GFile
*file
, GFile
*root
)
87 path
= g_file_get_path (root
);
88 root_path
= anjuta_util_get_real_path (path
);
91 path
= g_file_get_path (file
);
92 file_path
= anjuta_util_get_real_path (path
);
95 if ((file_path
!= NULL
) && (root_path
!= NULL
))
97 for (i
= 0; (file_path
[i
] == root_path
[i
]) && (file_path
[i
] != '\0') && (root_path
[i
] != '\0'); i
++);
98 if ((root_path
[i
] == '\0') && (file_path
[i
] == '\0'))
100 new_file
= g_object_ref (root
);
102 else if ((root_path
[i
] == '\0') && (file_path
[i
] == G_DIR_SEPARATOR
))
104 new_file
= g_file_resolve_relative_path (root
, &file_path
[i
+ 1]);
108 new_file
= g_object_ref (file
);
113 new_file
= g_object_ref (file
);
123 directory_has_makefile_am (BasicAutotoolsPlugin
*bb_plugin
, GFile
*dir
)
128 /* We need configure.ac or configure.in too */
129 if (bb_plugin
->project_root_dir
== NULL
) return FALSE
;
132 file
= g_file_get_child (bb_plugin
->project_root_dir
, "configure.ac");
133 if (!g_file_query_exists (file
, NULL
))
135 g_object_unref (file
);
136 file
= g_file_get_child (bb_plugin
->project_root_dir
, "configure.in");
137 if (!g_file_query_exists (file
, NULL
))
142 g_object_unref (file
);
144 /* Check for Makefile.am or GNUmakefile.am */
145 if (g_file_has_prefix (dir
, bb_plugin
->project_build_dir
))
147 /* Check for Makefile.am in source directory not build directory */
151 relative
= g_file_get_relative_path (bb_plugin
->project_build_dir
, dir
);
152 src_dir
= g_file_get_child (bb_plugin
->project_root_dir
, relative
);
153 file
= g_file_get_child (src_dir
, "Makefile.am");
154 g_object_unref (src_dir
);
157 else if (g_file_equal (dir
, bb_plugin
->project_build_dir
))
159 file
= g_file_get_child (bb_plugin
->project_root_dir
, "Makefile.am");
163 file
= g_file_get_child (dir
, "Makefile.am");
166 if (!g_file_query_exists (file
, NULL
))
168 g_object_unref (file
);
169 file
= g_file_get_child (dir
, "GNUmakefile.am");
170 if (!g_file_query_exists (file
, NULL
))
175 g_object_unref (file
);
181 directory_has_makefile (GFile
*dir
)
187 file
= g_file_get_child (dir
, "Makefile");
188 if (!g_file_query_exists (file
, NULL
))
190 g_object_unref (file
);
191 file
= g_file_get_child (dir
, "makefile");
192 if (!g_file_query_exists (file
, NULL
))
194 g_object_unref (file
);
195 file
= g_file_get_child (dir
, "MAKEFILE");
196 if (!g_file_query_exists (file
, NULL
))
202 g_object_unref (file
);
208 directory_has_file (GFile
*dir
, const gchar
*filename
)
213 file
= g_file_get_child (dir
, filename
);
214 exists
= g_file_query_exists (file
, NULL
);
215 g_object_unref (file
);
221 shell_quotef (const gchar
*format
,...)
227 va_start (args
, format
);
228 str
= g_strdup_vprintf (format
, args
);
231 quoted_str
= g_shell_quote (str
);
237 /* Get target relative to current configuration if existing or NULL if the current
238 * target is not relative to the current configuration */
240 get_configuration_relative_target (BasicAutotoolsPlugin
*plugin
)
242 gchar
*relative_target
= NULL
;
245 anjuta_shell_get (ANJUTA_PLUGIN (plugin
)->shell
, RUN_PROGRAM_URI
, G_TYPE_STRING
, &uri
, NULL
);
251 target
= g_file_new_for_uri (uri
);
252 file
= build_configuration_list_get_build_file (plugin
->configurations
, build_configuration_list_get_selected (plugin
->configurations
));
253 relative_target
= g_file_get_relative_path (file
, target
);
254 g_object_unref (file
);
255 g_object_unref (target
);
259 return relative_target
;
262 /* Set target relative to current configuration if relative_target is not NULL*/
264 set_configuration_relative_target (BasicAutotoolsPlugin
*plugin
, const gchar
* relative_target
)
266 if (relative_target
!= NULL
)
273 file
= build_configuration_list_get_build_file (plugin
->configurations
, build_configuration_list_get_selected (plugin
->configurations
));
274 target
= g_file_get_child (file
, relative_target
);
275 uri
= g_file_get_uri (target
);
276 g_value_init (&value
, G_TYPE_STRING
);
277 g_value_set_static_string (&value
, uri
);
278 anjuta_shell_add_value (ANJUTA_PLUGIN (plugin
)->shell
, RUN_PROGRAM_URI
, &value
, NULL
);
279 g_value_unset (&value
);
280 g_object_unref (target
);
281 g_object_unref (file
);
286 /* Return FALSE if Makefile is missing and we have both a Makefile.am and a project
287 * open, meaning that we need to configure the project to get a Makefile */
289 is_configured (BasicAutotoolsPlugin
*plugin
, GFile
*file
)
292 gboolean has_makefile
;
293 gboolean has_makefile_am
;
295 /* Get build directory and check for makefiles */
296 build_dir
= build_file_from_file (plugin
, file
, NULL
);
297 has_makefile
= directory_has_makefile (build_dir
);
298 has_makefile_am
= directory_has_makefile_am (plugin
, build_dir
);
299 g_object_unref (build_dir
);
301 return has_makefile
|| !has_makefile_am
|| (plugin
->project_root_dir
== NULL
);
304 /* Return build path from a source directory */
306 build_file_from_directory (BasicAutotoolsPlugin
*plugin
, GFile
*directory
)
310 if ((plugin
->project_root_dir
== NULL
) || (plugin
->project_build_dir
== NULL
))
312 /* No change if there is no project or no build directory */
313 build_file
= g_object_ref (directory
);
315 else if (g_file_has_prefix (directory
, plugin
->project_build_dir
) || g_file_equal (directory
, plugin
->project_build_dir
))
317 /* No change, already in build directory */
318 build_file
= g_object_ref (directory
);
320 else if (g_file_equal (directory
, plugin
->project_root_dir
))
322 /* Use build directory instead of source directory */
323 build_file
= g_object_ref (plugin
->project_build_dir
);
325 else if (g_file_has_prefix (directory
, plugin
->project_root_dir
))
327 /* Get corresponding file in build directory */
330 relative
= g_file_get_relative_path (plugin
->project_root_dir
, directory
);
331 build_file
= g_file_resolve_relative_path (plugin
->project_build_dir
, relative
);
336 /* File outside the project directory */
337 build_file
= g_object_ref (directory
);
343 /* Return build path and target from a GFile */
345 build_file_from_file (BasicAutotoolsPlugin
*plugin
, GFile
*file
, gchar
**target
)
348 if (target
!= NULL
) *target
= NULL
;
352 /* Use project root directory */
353 return build_file_from_directory (plugin
, plugin
->project_root_dir
);
355 else if (g_file_query_file_type (file
, 0, NULL
) == G_FILE_TYPE_DIRECTORY
)
357 return build_file_from_directory (plugin
, file
);
361 GFile
*parent
= NULL
;
363 IAnjutaProjectManager
* projman
;
365 projman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
366 IAnjutaProjectManager
,
371 /* Use the project manager to find the group file */
374 for (child
= normalize_project_file (file
, plugin
->project_root_dir
); child
!= NULL
;)
377 AnjutaProjectNodeType type
;
379 type
= ianjuta_project_manager_get_target_type (projman
, child
, NULL
);
380 if (type
== ANJUTA_PROJECT_GROUP
) break;
381 group
= ianjuta_project_manager_get_parent (projman
, child
, NULL
);
382 g_object_unref (child
);
390 /* Fallback use parent directory */
391 parent
= g_file_get_parent (file
);
396 if (target
!= NULL
) *target
= g_file_get_relative_path (parent
, file
);
397 build_file
= build_file_from_directory (plugin
, parent
);
398 g_object_unref (parent
);
410 build_object_from_file (BasicAutotoolsPlugin
*plugin
, GFile
*file
)
412 GFile
*object
= NULL
;
413 IAnjutaProjectManager
* projman
;
415 /* Check that the GFile is a regular file */
416 if ((file
== NULL
) || (g_file_query_file_type (file
, 0, NULL
) == G_FILE_TYPE_DIRECTORY
))
421 projman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
422 IAnjutaProjectManager
,
424 if ((projman
!= NULL
) && ianjuta_project_manager_is_open (projman
, NULL
))
426 /* Use the project manager to find the object file */
429 norm_file
= normalize_project_file (file
, plugin
->project_root_dir
);
430 object
= ianjuta_project_manager_get_parent (projman
, norm_file
, NULL
);
433 if (ianjuta_project_manager_get_target_type (projman
, object
, NULL
) != ANJUTA_PROJECT_OBJECT
)
435 g_object_unref (object
);
439 g_object_unref (norm_file
);
443 /* Use language plugin trying to find an object file */
444 IAnjutaLanguage
* langman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin
)->shell
,
450 GFileInfo
* file_info
;
452 file_info
= g_file_query_info (file
,
453 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
,
454 G_FILE_QUERY_INFO_NONE
,
459 gint id
= ianjuta_language_get_from_mime_type (langman
,
460 g_file_info_get_content_type (file_info
),
464 const gchar
*obj_ext
= ianjuta_language_get_make_target (langman
, id
, NULL
);
470 basename
= g_file_get_basename (file
);
471 ext
= strrchr (basename
, '.');
472 if ((ext
!= NULL
) && (ext
!= basename
)) *ext
= '\0';
473 targetname
= g_strconcat (basename
, obj_ext
, NULL
);
475 parent
= g_file_get_parent (file
);
476 object
= g_file_get_child (parent
, targetname
);
477 g_object_unref (parent
);
481 g_object_unref (file_info
);
489 *---------------------------------------------------------------------------*/
492 build_execute_command (BasicAutotoolsPlugin
* bplugin
, BuildProgram
*prog
,
493 gboolean with_view
, GError
**err
)
495 BuildContext
*context
;
498 context
= build_get_context (bplugin
, prog
->work_dir
, with_view
, FALSE
);
500 build_set_command_in_context (context
, prog
);
501 ok
= build_execute_command_in_context (context
, err
);
509 build_context_destroy (context
);
516 build_save_and_execute_command (BasicAutotoolsPlugin
* bplugin
, BuildProgram
*prog
,
517 gboolean with_view
, gboolean check_password
, GError
**err
)
519 BuildContext
*context
;
521 context
= build_get_context (bplugin
, prog
->work_dir
, with_view
, check_password
);
523 build_set_command_in_context (context
, prog
);
524 if (!build_save_and_execute_command_in_context (context
, err
))
526 build_context_destroy (context
);
534 build_execute_after_command (GObject
*sender
,
535 IAnjutaBuilderHandle handle
,
539 BuildProgram
*prog
= (BuildProgram
*)user_data
;
540 BuildContext
*context
= (BuildContext
*)handle
;
542 /* Try next command even if the first one fail (make distclean return an error) */
543 if ((error
== NULL
) || (error
->code
!= IANJUTA_BUILDER_ABORTED
))
545 build_set_command_in_context (context
, prog
);
546 build_execute_command_in_context (context
, NULL
);
550 build_program_free (prog
);
555 build_save_distclean_and_execute_command (BasicAutotoolsPlugin
* bplugin
, BuildProgram
*prog
,
556 gboolean with_view
, GError
**err
)
558 BuildContext
*context
;
561 BuildConfiguration
*config
;
564 context
= build_get_context (bplugin
, prog
->work_dir
, with_view
, FALSE
);
565 root_path
= g_file_get_path (bplugin
->project_root_dir
);
566 same
= strcmp (prog
->work_dir
, root_path
) == 0;
569 config
= build_configuration_list_get_selected (bplugin
->configurations
);
570 vars
= build_configuration_get_variables (config
);
572 if (!same
&& directory_has_file (bplugin
->project_root_dir
, "config.status"))
574 BuildProgram
*new_prog
;
576 // Need to run make clean before
577 if (!anjuta_util_dialog_boolean_question (GTK_WINDOW (ANJUTA_PLUGIN (bplugin
)->shell
), FALSE
,
578 _("Before using this new configuration, the default one needs to be removed. Do you want to do that?"), NULL
))
581 *err
= g_error_new (ianjuta_builder_error_quark (),
582 IANJUTA_BUILDER_CANCELED
,
583 _("Command canceled by user"));
587 new_prog
= build_program_new_with_command (bplugin
->project_root_dir
,
589 CHOOSE_COMMAND (bplugin
, DISTCLEAN
));
590 build_program_set_callback (new_prog
, build_execute_after_command
, prog
);
593 build_program_add_env_list (prog
, vars
);
595 build_set_command_in_context (context
, prog
);
597 build_save_and_execute_command_in_context (context
, NULL
);
604 *---------------------------------------------------------------------------*/
607 build_build_file_or_dir (BasicAutotoolsPlugin
*plugin
,
609 IAnjutaBuilderCallback callback
, gpointer user_data
,
615 BuildContext
*context
;
616 BuildConfiguration
*config
;
619 config
= build_configuration_list_get_selected (plugin
->configurations
);
620 vars
= build_configuration_get_variables (config
);
622 build_dir
= build_file_from_file (plugin
, file
, &target
);
623 prog
= build_program_new_with_command (build_dir
,
625 CHOOSE_COMMAND (plugin
, BUILD
),
626 target
? target
: "");
627 build_program_set_callback (prog
, callback
, user_data
);
628 build_program_add_env_list (prog
, vars
);
630 context
= build_save_and_execute_command (plugin
, prog
, TRUE
, FALSE
, err
);
632 g_object_unref (build_dir
);
640 build_is_file_built (BasicAutotoolsPlugin
*plugin
, GFile
*file
,
641 IAnjutaBuilderCallback callback
, gpointer user_data
,
647 BuildContext
*context
;
648 BuildConfiguration
*config
;
652 config
= build_configuration_list_get_selected (plugin
->configurations
);
659 vars
= build_configuration_get_variables (config
);
661 build_dir
= build_file_from_file (plugin
, file
, &target
);
662 prog
= build_program_new_with_command (build_dir
,
664 CHOOSE_COMMAND (plugin
, IS_BUILT
),
665 target
? target
: "");
666 build_program_set_callback (prog
, callback
, user_data
);
667 build_program_add_env_list (prog
, vars
);
669 context
= build_save_and_execute_command (plugin
, prog
, FALSE
, FALSE
, err
);
672 g_object_unref (build_dir
);
680 get_root_install_command(BasicAutotoolsPlugin
*bplugin
)
682 GSettings
* settings
= bplugin
->settings
;
683 if (g_settings_get_boolean (settings
, PREF_INSTALL_ROOT
))
685 gchar
* command
= g_settings_get_string (settings
, PREF_INSTALL_ROOT_COMMAND
);
693 build_install_dir (BasicAutotoolsPlugin
*plugin
, GFile
*dir
,
694 IAnjutaBuilderCallback callback
, gpointer user_data
,
697 BuildContext
*context
;
698 gchar
* root
= get_root_install_command(plugin
);
699 gboolean use_root
= FALSE
;
703 BuildConfiguration
*config
;
706 if ((root
!= NULL
) && (*root
!= '\0'))
711 /* Replace %s or %q by respectively, the install command or the
712 * quoted install command. % character can be escaped by using two %. */
713 command
= g_string_new (NULL
);
720 /* Not quoted command */
721 g_string_append_len (command
, first
, ptr
- 1 - first
);
722 g_string_append (command
, CHOOSE_COMMAND (plugin
, INSTALL
));
725 else if (*ptr
== 'q')
730 quoted
= g_shell_quote (CHOOSE_COMMAND (plugin
, INSTALL
));
731 g_string_append_len (command
, first
, ptr
- 1 - first
);
732 g_string_append (command
, quoted
);
736 else if (*ptr
== '%')
739 g_string_append_len (command
, first
, ptr
- 1 - first
);
745 g_string_append (command
, first
);
750 command
= g_string_new (CHOOSE_COMMAND (plugin
, INSTALL
));
754 config
= build_configuration_list_get_selected (plugin
->configurations
);
755 vars
= build_configuration_get_variables (config
);
757 build_dir
= build_file_from_file (plugin
, dir
, NULL
);
758 prog
= build_program_new_with_command (build_dir
,
761 build_program_set_callback (prog
, callback
, user_data
);
762 build_program_add_env_list (prog
, vars
);
764 context
= build_save_and_execute_command (plugin
, prog
, TRUE
, use_root
, err
);
766 g_string_free (command
, TRUE
);
767 g_object_unref (build_dir
);
776 build_clean_dir (BasicAutotoolsPlugin
*plugin
, GFile
*dir
,
779 BuildContext
*context
= NULL
;
782 BuildConfiguration
*config
;
785 if (is_configured (plugin
, dir
))
787 config
= build_configuration_list_get_selected (plugin
->configurations
);
788 vars
= build_configuration_get_variables (config
);
790 build_dir
= build_file_from_file (plugin
, dir
, NULL
);
792 prog
= build_program_new_with_command (build_dir
,
794 CHOOSE_COMMAND (plugin
, CLEAN
)),
795 build_program_add_env_list (prog
, vars
);
797 context
= build_execute_command (plugin
, prog
, TRUE
, err
);
798 g_object_unref (build_dir
);
805 build_check_dir (BasicAutotoolsPlugin
*plugin
, GFile
*dir
,
806 IAnjutaBuilderCallback callback
, gpointer user_data
,
809 BuildContext
*context
= NULL
;
812 BuildConfiguration
*config
;
815 config
= build_configuration_list_get_selected (plugin
->configurations
);
816 vars
= build_configuration_get_variables (config
);
818 build_dir
= build_file_from_file (plugin
, dir
, NULL
);
820 prog
= build_program_new_with_command (build_dir
,
822 CHOOSE_COMMAND (plugin
, CHECK
)),
823 build_program_set_callback (prog
, callback
, user_data
);
824 build_program_add_env_list (prog
, vars
);
826 context
= build_execute_command (plugin
, prog
, TRUE
, err
);
827 g_object_unref (build_dir
);
833 build_remove_build_dir (GObject
*sender
,
834 IAnjutaBuilderHandle context
,
838 /* FIXME: Should we remove build dir on distclean ? */
842 build_distclean (BasicAutotoolsPlugin
*plugin
)
844 BuildContext
*context
;
846 BuildConfiguration
*config
;
850 config
= build_configuration_list_get_selected (plugin
->configurations
);
851 vars
= build_configuration_get_variables (config
);
853 prog
= build_program_new_with_command (plugin
->project_build_dir
,
855 CHOOSE_COMMAND (plugin
, DISTCLEAN
));
856 build_program_set_callback (prog
, build_remove_build_dir
, plugin
);
857 build_program_add_env_list (prog
, vars
);
859 context
= build_execute_command (plugin
, prog
, TRUE
, NULL
);
867 build_tarball (BasicAutotoolsPlugin
*plugin
)
869 BuildContext
*context
;
871 BuildConfiguration
*config
;
874 config
= build_configuration_list_get_selected (plugin
->configurations
);
875 vars
= build_configuration_get_variables (config
);
877 prog
= build_program_new_with_command (plugin
->project_build_dir
,
879 CHOOSE_COMMAND (plugin
, BUILD_TARBALL
)),
880 build_program_add_env_list (prog
, vars
);
882 context
= build_save_and_execute_command (plugin
, prog
, TRUE
, FALSE
, NULL
);
888 build_compile_file (BasicAutotoolsPlugin
*plugin
, GFile
*file
)
890 BuildContext
*context
= NULL
;
895 g_return_val_if_fail (file
!= NULL
, FALSE
);
897 object
= build_object_from_file (plugin
, file
);
901 BuildConfiguration
*config
;
904 config
= build_configuration_list_get_selected (plugin
->configurations
);
905 vars
= build_configuration_get_variables (config
);
907 /* Find target directory */
908 build_dir
= build_file_from_file (plugin
, object
, &target_name
);
910 prog
= build_program_new_with_command (build_dir
, "%s %s",
911 CHOOSE_COMMAND(plugin
, COMPILE
),
912 (target_name
== NULL
) ? "" : target_name
);
913 g_free (target_name
);
914 g_object_unref (build_dir
);
916 build_program_add_env_list (prog
, vars
);
918 context
= build_save_and_execute_command (plugin
, prog
, TRUE
, FALSE
, NULL
);
919 g_object_unref (object
);
923 /* FIXME: Prompt the user to create a Makefile with a wizard
924 (if there is no Makefile in the directory) or to add a target
925 rule in the above hash table, eg. editing the preferences, if
926 there is target extension defined for that file extension.
931 filename
= g_file_get_path (file
);
932 window
= GTK_WINDOW (ANJUTA_PLUGIN (plugin
)->shell
);
933 anjuta_util_dialog_error (window
, _("Cannot compile \"%s\": No compile rule defined for this file type."), filename
);
942 build_project_configured (GObject
*sender
,
943 IAnjutaBuilderHandle handle
,
947 BuildConfigureAndBuild
*pack
= (BuildConfigureAndBuild
*)user_data
;
951 BuildContext
*context
= (BuildContext
*)handle
;
952 BasicAutotoolsPlugin
*plugin
= (BasicAutotoolsPlugin
*)(context
== NULL
? (void *)sender
: (void *)build_context_get_plugin (context
));
955 /* FIXME: check if build directory correspond, configuration could have changed */
957 file
= build_configuration_list_get_build_file (plugin
->configurations
, build_configuration_list_get_selected (plugin
->configurations
));
960 GValue value
= G_VALUE_INIT
;
963 uri
= g_file_get_uri (file
);
964 g_value_init (&value
, G_TYPE_STRING
);
965 g_value_set_string (&value
, uri
);
967 g_object_unref (file
);
969 anjuta_shell_add_value (ANJUTA_PLUGIN (plugin
)->shell
, IANJUTA_BUILDER_ROOT_URI
, &value
, NULL
);
970 g_value_unset (&value
);
972 /* Call build function if necessary */
973 if ((pack
) && (pack
->func
!= NULL
)) pack
->func (plugin
, pack
->file
, pack
->callback
, pack
->user_data
, NULL
);
976 anjuta_shell_remove_value (ANJUTA_PLUGIN (plugin
)->shell
, IANJUTA_BUILDER_ROOT_URI
, NULL
);
978 build_update_configuration_menu (plugin
);
984 if (pack
->file
!= NULL
) g_object_unref (pack
->file
);
990 build_configure_dir (BasicAutotoolsPlugin
*plugin
, GFile
*dir
, const gchar
*args
,
991 BuildFunc func
, GFile
*file
,
992 IAnjutaBuilderCallback callback
, gpointer user_data
, GError
**error
)
994 BuildContext
*context
;
996 BuildConfiguration
*config
;
998 BuildConfigureAndBuild
*pack
= g_new0 (BuildConfigureAndBuild
, 1);
1002 config
= build_configuration_list_get_selected (plugin
->configurations
);
1003 vars
= build_configuration_get_variables (config
);
1005 // Make sure the build directory is here
1006 g_file_make_directory_with_parents (dir
, NULL
, NULL
);
1008 root_path
= g_file_get_path (plugin
->project_root_dir
);
1009 quote
= shell_quotef ("%s%s%s",
1012 CHOOSE_COMMAND (plugin
, CONFIGURE
));
1014 prog
= build_program_new_with_command (dir
,
1023 pack
->file
= (file
!= NULL
) ? g_object_ref (file
) : NULL
;
1024 pack
->callback
= callback
;
1025 pack
->user_data
= user_data
;
1026 build_program_set_callback (prog
, build_project_configured
, pack
);
1027 build_program_add_env_list (prog
, vars
);
1029 context
= build_save_distclean_and_execute_command (plugin
, prog
, TRUE
, NULL
);
1037 build_configure_after_autogen (GObject
*sender
,
1038 IAnjutaBuilderHandle handle
,
1042 BuildConfigureAndBuild
*pack
= (BuildConfigureAndBuild
*)user_data
;
1046 BuildContext
*context
= (BuildContext
*)handle
;
1047 BuildConfiguration
*config
;
1049 BasicAutotoolsPlugin
*plugin
= (BasicAutotoolsPlugin
*)build_context_get_plugin (context
);
1050 struct stat conf_stat
, log_stat
;
1053 gboolean has_configure
;
1055 root_path
= g_file_get_path (plugin
->project_root_dir
);
1056 filename
= g_build_filename (root_path
, "configure", NULL
);
1057 has_configure
= stat (filename
, &conf_stat
) == 0;
1064 config
= build_configuration_list_get_selected (plugin
->configurations
);
1065 vars
= build_configuration_get_variables (config
);
1067 filename
= g_build_filename (build_context_get_work_dir (context
), "config.status", NULL
);
1068 older
=(stat (filename
, &log_stat
) != 0) || (log_stat
.st_mtime
< conf_stat
.st_mtime
);
1073 /* configure has not be run, run it */
1078 quote
= shell_quotef ("%s%s%s",
1081 CHOOSE_COMMAND (plugin
, CONFIGURE
));
1083 work_file
= g_file_new_for_path (build_context_get_work_dir (context
));
1084 prog
= build_program_new_with_command (work_file
,
1087 pack
!= NULL
? pack
->args
: NULL
);
1088 g_object_unref (work_file
);
1090 build_program_set_callback (prog
, build_project_configured
, pack
);
1091 build_program_add_env_list (prog
, vars
);
1093 build_set_command_in_context (context
, prog
);
1094 build_execute_command_in_context (context
, NULL
);
1098 /* run next command if needed */
1099 build_project_configured (sender
, handle
, NULL
, pack
);
1107 anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin
)->shell
), _("Cannot configure project: Missing configure script in %s."), root_path
);
1114 g_free (pack
->args
);
1115 if (pack
->file
!= NULL
) g_object_unref (pack
->file
);
1121 build_generate_dir (BasicAutotoolsPlugin
*plugin
, GFile
*dir
, const gchar
*args
,
1122 BuildFunc func
, GFile
*file
,
1123 IAnjutaBuilderCallback callback
, gpointer user_data
, GError
**error
)
1125 BuildContext
*context
;
1127 BuildConfiguration
*config
;
1129 BuildConfigureAndBuild
*pack
= g_new0 (BuildConfigureAndBuild
, 1);
1132 config
= build_configuration_list_get_selected (plugin
->configurations
);
1133 vars
= build_configuration_get_variables (config
);
1135 // Make sure the build directory is here
1136 g_file_make_directory_with_parents (dir
, NULL
, NULL
);
1138 if (directory_has_file (plugin
->project_root_dir
, "autogen.sh"))
1141 gchar
*root_path
= g_file_get_path (plugin
->project_root_dir
);
1143 quote
= shell_quotef ("%s%s%s",
1146 CHOOSE_COMMAND (plugin
, GENERATE
));
1147 prog
= build_program_new_with_command (dir
,
1156 prog
= build_program_new_with_command (dir
,
1158 CHOOSE_COMMAND (plugin
, AUTORECONF
),
1161 pack
->args
= g_strdup (args
);
1163 pack
->file
= (file
!= NULL
) ? g_object_ref (file
) : NULL
;
1164 pack
->callback
= callback
;
1165 pack
->user_data
= user_data
;
1166 build_program_set_callback (prog
, build_configure_after_autogen
, pack
);
1167 build_program_add_env_list (prog
, vars
);
1169 context
= build_save_distclean_and_execute_command (plugin
, prog
, TRUE
, NULL
);
1175 build_configure_dialog (BasicAutotoolsPlugin
*plugin
, BuildFunc func
, GFile
*file
, IAnjutaBuilderCallback callback
, gpointer user_data
, GError
**error
)
1178 gboolean run_autogen
= FALSE
;
1179 const gchar
*project_root
;
1180 GValue value
= {0,};
1181 const gchar
*old_config_name
;
1182 gchar
*relative_target
;
1183 BuildContext
* context
= NULL
;
1185 run_autogen
= !directory_has_file (plugin
->project_root_dir
, "configure");
1187 anjuta_shell_get_value (ANJUTA_PLUGIN (plugin
)->shell
, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
, &value
, NULL
);
1189 /* In case, a project is not loaded */
1190 if (!G_VALUE_HOLDS_STRING (&value
)) return NULL
;
1192 project_root
= g_value_get_string (&value
);
1193 parent
= GTK_WINDOW (ANJUTA_PLUGIN(plugin
)->shell
);
1195 old_config_name
= build_configuration_get_name (build_configuration_list_get_selected (plugin
->configurations
));
1196 relative_target
= get_configuration_relative_target (plugin
);
1197 if (build_dialog_configure (parent
, project_root
, plugin
->configurations
, &run_autogen
))
1199 BuildConfiguration
*config
;
1203 config
= build_configuration_list_get_selected (plugin
->configurations
);
1204 build_file
= build_configuration_list_get_build_file (plugin
->configurations
, config
);
1206 args
= build_configuration_get_args (config
);
1210 context
= build_generate_dir (plugin
, build_file
, args
, func
, file
, callback
, user_data
, error
);
1214 context
= build_configure_dir (plugin
, build_file
, args
, func
, file
, callback
, user_data
, error
);
1216 g_object_unref (build_file
);
1218 if (context
== NULL
)
1220 /* Restore previous configuration */
1221 build_configuration_list_select (plugin
->configurations
, old_config_name
);
1225 set_configuration_relative_target (plugin
, relative_target
);
1228 g_free (relative_target
);
1233 /* Run configure if needed and then the build command */
1235 build_configure_and_build (BasicAutotoolsPlugin
*plugin
, BuildFunc func
, GFile
*file
, IAnjutaBuilderCallback callback
, gpointer user_data
, GError
**error
)
1237 if (!is_configured (plugin
, file
))
1239 /* Run configure first */
1240 return build_configure_dialog (plugin
, func
, file
, callback
, user_data
, error
);
1244 /* Some build functions have less arguments but
1245 * it is not a problem in C */
1246 return func (plugin
, file
, callback
, user_data
, error
);
1250 /* Configuration commands
1251 *---------------------------------------------------------------------------*/
1254 build_list_configuration (BasicAutotoolsPlugin
*plugin
)
1256 BuildConfiguration
*cfg
;
1259 for (cfg
= build_configuration_list_get_first (plugin
->configurations
); cfg
!= NULL
; cfg
= build_configuration_next (cfg
))
1261 const gchar
*name
= build_configuration_get_name (cfg
);
1263 if (name
!= NULL
) list
= g_list_prepend (list
, (gpointer
)name
);
1270 build_get_uri_configuration (BasicAutotoolsPlugin
*plugin
, const gchar
*uri
)
1272 BuildConfiguration
*cfg
;
1273 BuildConfiguration
*uri_cfg
= NULL
;
1274 GFile
*file
= g_file_new_for_uri (uri
);
1276 /* Check all configurations as other configuration directories are
1277 * normally child of default configuration directory */
1278 for (cfg
= build_configuration_list_get_first (plugin
->configurations
); cfg
!= NULL
; cfg
= build_configuration_next (cfg
))
1280 GFile
*root
= build_configuration_list_get_build_file (plugin
->configurations
, cfg
);
1282 if ((root
!= NULL
) && g_file_has_prefix (file
, root
)) uri_cfg
= cfg
;
1284 g_object_unref (file
);
1286 return uri_cfg
!= NULL
? build_configuration_get_name (uri_cfg
) : NULL
;