diff --git a/doc/help/howto/index.rst b/doc/help/howto/index.rst index 4a7ebe5c436ff8821394c48dfee5ee0f70b31bb0..ebe0a3518bf84834a3c70951b46b8b415cc89e1e 100644 --- a/doc/help/howto/index.rst +++ b/doc/help/howto/index.rst @@ -17,3 +17,4 @@ Contents jump_to_definition search_for_symbol rust_integration + sysroot diff --git a/doc/help/howto/sysroot.rst b/doc/help/howto/sysroot.rst new file mode 100644 index 0000000000000000000000000000000000000000..bec71f9c41806fc950bce40b5676347ee82ac8cd --- /dev/null +++ b/doc/help/howto/sysroot.rst @@ -0,0 +1,24 @@ +#################### +Use a Custom Sysroot +#################### + +If you need to use a custom sysroot. You can configure a new target in `Preferences->SDKs`. + +There are four fields to fill: + +- Name: The name of your choice describing this sysroot. +- Arch: The architecture targeted by the sysroot. +- Sysroot path: The absolute path on your filesystem leading to the sysroot. +- Additional pkg-config path: (optional) A colon separated list of absolute path leading to pkg-config folders of the sysroot. + +.. note:: By default pkg-config will search in /lib/pkgconfig and /usr/lib/pkgconfig but some systems are installing them in different directories (for instance a x86_64 Debian-based system will require /usr/lib/x86_64-linux-gnu/pkgconfig when a RPM-based system will use /usr/lib64/pkgconfig). + +The configuration will be stored in ~/.config/gnome-builder/sysroot/general.conf using a simple key-value format: + +.. code-block:: cfg + + [Sysroot 0] + Name=My Sysroot 😎 + Arch=x86_64 + Path=/path/to/my_sysroot + PkgConfigPath=/path/to/my_sysroot/usr/lib/x86_64-linux-gnu/pkgconfig diff --git a/meson_options.txt b/meson_options.txt index aa0e00f5ca00b0e4e523c62aa0096fdfce1c235f..03e386b060cb74e8b7ab58fca527a2206613ddee 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -71,6 +71,7 @@ option('with_support', type: 'boolean') option('with_symbol_tree', type: 'boolean') option('with_sysmon', type: 'boolean') option('with_sysprof', type: 'boolean') +option('with_sysroot', type: 'boolean') option('with_todo', type: 'boolean') option('with_vala_pack', type: 'boolean') option('with_valgrind', type: 'boolean') diff --git a/src/plugins/meson.build b/src/plugins/meson.build index d97d7e3734841402c4249446d1a217eab97bac9a..b37ea3fac357cca24daa67ffd0e422cf372da479 100644 --- a/src/plugins/meson.build +++ b/src/plugins/meson.build @@ -65,6 +65,7 @@ subdir('support') subdir('symbol-tree') subdir('sysmon') subdir('sysprof') +subdir('sysroot') subdir('terminal') subdir('todo') subdir('vala-pack') @@ -141,6 +142,7 @@ status += [ 'Symbol Tree ........... : @0@'.format(get_option('with_symbol_tree')), 'System Monitor ........ : @0@'.format(get_option('with_sysmon')), 'Sysprof Profiler ...... : @0@'.format(get_option('with_sysprof')), + 'Sysroot ...... : @0@'.format(get_option('with_sysroot')), 'Todo .................. : @0@'.format(get_option('with_todo')), 'Vala Language Pack .... : @0@'.format(get_option('with_vala_pack')), 'Valgrind .............. : @0@'.format(get_option('with_valgrind')), diff --git a/src/plugins/sysroot/gbp-sysroot-manager.c b/src/plugins/sysroot/gbp-sysroot-manager.c new file mode 100644 index 0000000000000000000000000000000000000000..dbc0d7bf006873a69912648167a5500cc64b23b8 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-manager.c @@ -0,0 +1,502 @@ +/* gbp-sysroot-manager.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-manager" +#define BASIC_LIBDIRS "/usr/lib/pkgconfig:/usr/share/pkgconfig" + +#include "gbp-sysroot-manager.h" + +struct _GbpSysrootManager +{ + GObject parent_instance; + GKeyFile *key_file; +}; + +G_DEFINE_TYPE (GbpSysrootManager, gbp_sysroot_manager, G_TYPE_OBJECT) + +enum { + TARGET_MODIFIED, + TARGET_NAME_CHANGED, + TARGET_ARCH_CHANGED, + N_SIGNALS +}; + +static guint signals [N_SIGNALS]; + +static gchar * +sysroot_manager_get_path (void) +{ + g_autofree gchar *directory_path = NULL; + g_autofree gchar *conf_file = NULL; + + directory_path = g_build_filename (g_get_user_config_dir (), + ide_get_program_name (), + "sysroot", + NULL); + + g_mkdir_with_parents (directory_path, 0750); + conf_file = g_build_filename (directory_path, "general.conf", NULL); + return g_steal_pointer (&conf_file); +} + +/** + * sysroot_manager_find_additional_pkgconfig_paths: + * + * Returns a colon-separated list of additional pkgconfig paths + * + * Returns: (transfer full) (nullable): additional guessed paths + */ +static gchar * +sysroot_manager_find_additional_pkgconfig_paths (GbpSysrootManager *self, + const gchar *target) +{ + g_autofree gchar *path = NULL; + g_autofree gchar *lib64_path = NULL; + g_autofree gchar *libmultiarch_path = NULL; + g_autofree gchar *returned_paths = NULL; + + g_assert (GBP_IS_SYSROOT_MANAGER (self)); + g_assert (self->key_file != NULL); + g_assert (target != NULL); + + path = gbp_sysroot_manager_get_target_path (self, target); + lib64_path = g_build_path (G_DIR_SEPARATOR_S, path, "usr", "lib64", "pkgconfig", NULL); + libmultiarch_path = g_build_path (G_DIR_SEPARATOR_S, path, "usr", "lib", "pkg-config.multiarch", NULL); + + if (g_file_test (lib64_path, G_FILE_TEST_EXISTS)) + { + returned_paths = lib64_path; + } + + if (g_file_test (libmultiarch_path, G_FILE_TEST_EXISTS)) + { + g_autoptr(GFileInputStream) file_stream = NULL; + g_autoptr(GFile) multiarch_file = g_file_new_for_path (libmultiarch_path); + g_autoptr(GError) file_error = NULL; + + file_stream = g_file_read (multiarch_file, NULL, &file_error); + if (file_error == NULL) + { + g_autoptr(GDataInputStream) data_stream = NULL; + g_autofree gchar *line = NULL; + + data_stream = g_data_input_stream_new (G_INPUT_STREAM (file_stream)); + while ((line = (gchar *)g_data_input_stream_read_line_utf8 (data_stream, NULL, NULL, &file_error)) != NULL) + { + g_autofree gchar *multiarch_path = NULL; + + if (file_error != NULL) + { + g_critical ("Error while reading \"%s\": %s", libmultiarch_path, file_error->message); + break; + } + + multiarch_path = g_build_path (G_DIR_SEPARATOR_S, path, "usr", "lib", line, "pkgconfig", NULL); + returned_paths = g_strjoin (":", multiarch_path, returned_paths, NULL); + } + } + else + g_critical ("Unable to read \"%s\": %s", libmultiarch_path, file_error->message); + } + + return g_strdup (returned_paths); +} + +static void +sysroot_manager_save (GbpSysrootManager *self) +{ + g_autofree gchar *conf_file = NULL; + g_autoptr(GError) error = NULL; + + g_assert (GBP_IS_SYSROOT_MANAGER (self)); + g_assert (self->key_file != NULL); + + conf_file = sysroot_manager_get_path (); + + if (!g_key_file_save_to_file (self->key_file, conf_file, &error)) + g_critical ("Error loading the sysroot configuration: %s", error->message); +} + +/** + * gbp_sysroot_manager_get_default: + * + * Returns the default #GbpSysrootManager instance. + * + * Returns: (transfer none): the common sysroot manager + */ +GbpSysrootManager * +gbp_sysroot_manager_get_default (void) +{ + static GbpSysrootManager *instance; + if (instance == NULL) + { + instance = g_object_new (GBP_TYPE_SYSROOT_MANAGER, NULL); + } + + return instance; +} + +/** + * gbp_sysroot_manager_create_target: + * @self: a #GbpSysrootManager + * + * This creates a new target and initializes its fields to the default parameters. + * + * Returns: (transfer full): the unique identifier of the new target + */ +gchar * +gbp_sysroot_manager_create_target (GbpSysrootManager *self) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + + for (guint i = 0; i < UINT_MAX; i++) + { + gchar *result; + g_autoptr(GString) sysroot_name = g_string_new (NULL); + + g_string_printf (sysroot_name, "Sysroot %u", i); + result = sysroot_name->str; + if (!g_key_file_has_group (self->key_file, result)) + { + g_key_file_set_string (self->key_file, result, "Name", result); + g_key_file_set_string (self->key_file, result, "Path", "/"); + sysroot_manager_save (self); + g_signal_emit (self, signals[TARGET_MODIFIED], 0, result, GBP_SYSROOT_MANAGER_TARGET_CREATED); + return g_string_free (g_steal_pointer (&sysroot_name), FALSE); + } + } + + return NULL; +} + +void +gbp_sysroot_manager_remove_target (GbpSysrootManager *self, + const gchar *target) +{ + g_autoptr(GError) error = NULL; + + g_return_if_fail (GBP_IS_SYSROOT_MANAGER (self)); + g_return_if_fail (self->key_file != NULL); + g_return_if_fail (target != NULL); + + g_key_file_remove_group (self->key_file, target, &error); + if (error) + g_critical ("Error removing target \"%s\": %s", target, error->message); + + g_signal_emit (self, signals[TARGET_MODIFIED], 0, target, GBP_SYSROOT_MANAGER_TARGET_REMOVED); + sysroot_manager_save (self); +} + +/** + * gbp_sysroot_manager_set_target_name: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * @name: the displayable name of the target + * + * Sets the displayable name of the target. + */ +void +gbp_sysroot_manager_set_target_name (GbpSysrootManager *self, + const gchar *target, + const gchar *name) +{ + g_return_if_fail (GBP_IS_SYSROOT_MANAGER (self)); + g_return_if_fail (self->key_file != NULL); + g_return_if_fail (target != NULL); + + g_key_file_set_string (self->key_file, target, "Name", name); + g_signal_emit (self, signals[TARGET_MODIFIED], 0, target, GBP_SYSROOT_MANAGER_TARGET_CHANGED); + g_signal_emit (self, signals[TARGET_NAME_CHANGED], 0, target, name); + sysroot_manager_save (self); +} + +/** + * gbp_sysroot_manager_get_target_name: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * + * Gets the displayable name of the target. + * + * Returns: (transfer full): the name of the target to display. + */ +gchar * +gbp_sysroot_manager_get_target_name (GbpSysrootManager *self, + const gchar *target) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + g_return_val_if_fail (target != NULL, NULL); + + return g_key_file_get_string (self->key_file, target, "Name", NULL); +} + +/** + * gbp_sysroot_manager_set_target_arch: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * @name: the architecture of the target + * + * Sets the architecture of the target. + */ +void +gbp_sysroot_manager_set_target_arch (GbpSysrootManager *self, + const gchar *target, + const gchar *arch) +{ + g_return_if_fail (GBP_IS_SYSROOT_MANAGER (self)); + g_return_if_fail (self->key_file != NULL); + g_return_if_fail (target != NULL); + + g_key_file_set_string (self->key_file, target, "Arch", arch); + g_signal_emit (self, signals[TARGET_MODIFIED], 0, target, GBP_SYSROOT_MANAGER_TARGET_CHANGED); + g_signal_emit (self, signals[TARGET_ARCH_CHANGED], 0, target, arch); + sysroot_manager_save (self); +} + +/** + * gbp_sysroot_manager_get_target_arch: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * + * Gets the architecture of the target. + * + * Returns: (transfer full): the architecture of the target. + */ +gchar * +gbp_sysroot_manager_get_target_arch (GbpSysrootManager *self, + const gchar *target) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + g_return_val_if_fail (target != NULL, NULL); + + return g_key_file_get_string (self->key_file, target, "Arch", NULL); +} + +/** + * gbp_sysroot_manager_set_target_path: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * @path: the sysroot path of the target + * + * Sets the sysroot path of the target. + */ +void +gbp_sysroot_manager_set_target_path (GbpSysrootManager *self, + const gchar *target, + const gchar *path) +{ + g_autofree gchar *current_path = NULL; + g_autofree gchar *current_pkgconfigs = NULL; + + g_return_if_fail (GBP_IS_SYSROOT_MANAGER (self)); + g_return_if_fail (self->key_file != NULL); + g_return_if_fail (target != NULL); + g_return_if_fail (path != NULL); + + current_path = gbp_sysroot_manager_get_target_path (self, target); + g_key_file_set_string (self->key_file, target, "Path", path); + g_signal_emit (self, signals[TARGET_MODIFIED], 0, target, GBP_SYSROOT_MANAGER_TARGET_CHANGED); + sysroot_manager_save (self); + + current_pkgconfigs = gbp_sysroot_manager_get_target_pkg_config_path (self, target); + if (current_pkgconfigs == NULL || g_strcmp0 (current_pkgconfigs, "") == 0) + { + g_auto(GStrv) path_parts = NULL; + g_autofree gchar *additional_paths = NULL; + + // Prepend the sysroot path to the BASIC_LIBDIRS values + path_parts = g_strsplit (BASIC_LIBDIRS, ":", 0); + for (gint i = g_strv_length (path_parts) - 1; i >= 0; i--) + { + g_autofree gchar *path_i = NULL; + + path_i = g_build_path (G_DIR_SEPARATOR_S, path, path_parts[i], NULL); + current_pkgconfigs = g_strjoin (":", path_i, current_pkgconfigs, NULL); + } + + additional_paths = sysroot_manager_find_additional_pkgconfig_paths (self, target); + current_pkgconfigs = g_strjoin (":", current_pkgconfigs, additional_paths, NULL); + + gbp_sysroot_manager_set_target_pkg_config_path (self, target, current_pkgconfigs); + } + else + { + g_autoptr(GError) regex_error = NULL; + g_autoptr(GRegex) regex = NULL; + g_autofree gchar *current_path_escaped = NULL; + + current_path_escaped = g_regex_escape_string (current_path, -1); + regex = g_regex_new (current_path_escaped, 0, 0, ®ex_error); + if (regex_error == NULL) + { + current_pkgconfigs = g_regex_replace_literal (regex, current_pkgconfigs, (gssize) -1, 0, path, 0, ®ex_error); + if (regex_error == NULL) + gbp_sysroot_manager_set_target_pkg_config_path (self, target, current_pkgconfigs); + else + g_critical ("Regex error: %s", regex_error->message); + } + else + g_critical ("Regex error: %s", regex_error->message); + } +} + +/** + * gbp_sysroot_manager_get_target_path: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * + * Gets the sysroot path of the target. + * + * Returns: (transfer full): the sysroot path of the target. + */ +gchar * +gbp_sysroot_manager_get_target_path (GbpSysrootManager *self, + const gchar *target) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + g_return_val_if_fail (target != NULL, NULL); + + return g_key_file_get_string (self->key_file, target, "Path", NULL); +} + + +/** + * gbp_sysroot_manager_set_target_pkg_config_path: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * @path: (nullable): the additional Pkg-Config paths of the target or %NULL + * + * Sets the additional Pkg-Config paths of the target. + * It is possible to use several paths by separating them with a colon character. + */ +void +gbp_sysroot_manager_set_target_pkg_config_path (GbpSysrootManager *self, + const gchar *target, + const gchar *path) +{ + g_return_if_fail (GBP_IS_SYSROOT_MANAGER (self)); + g_return_if_fail (self->key_file != NULL); + g_return_if_fail (target != NULL); + + g_key_file_set_string (self->key_file, target, "PkgConfigPath", path); + g_signal_emit (self, signals[TARGET_MODIFIED], 0, target, GBP_SYSROOT_MANAGER_TARGET_CHANGED); + sysroot_manager_save (self); +} + +/** + * gbp_sysroot_manager_get_target_pkg_config_path: + * @self: a #GbpSysrootManager + * @target: the unique identifier of the target + * + * Gets the additional Pkg-Config paths of the target. + * + * This is often used when the target has its libraries in an architecture-specific folder. + * + * Returns: (transfer full) (nullable): the additional paths to pkg-config, using a colon separator. + */ +gchar * +gbp_sysroot_manager_get_target_pkg_config_path (GbpSysrootManager *self, + const gchar *target) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + g_return_val_if_fail (target != NULL, NULL); + + return g_key_file_get_string (self->key_file, target, "PkgConfigPath", NULL); +} + +/** + * gbp_sysroot_manager_list: + * @self: a #GbpSysrootManager + * + * Retrieves the list of all the available sysroot unique identifiers. + * + * Returns: (transfer full) (nullable): the %NULL-terminated list of all the available sysroot + * unique identifiers. + */ +gchar ** +gbp_sysroot_manager_list (GbpSysrootManager *self) +{ + g_return_val_if_fail (GBP_IS_SYSROOT_MANAGER (self), NULL); + g_return_val_if_fail (self->key_file != NULL, NULL); + + return g_key_file_get_groups (self->key_file, NULL); +} + +void +gbp_sysroot_manager_finalize (GObject *object) +{ + GbpSysrootManager *self = GBP_SYSROOT_MANAGER(object); + + g_clear_pointer (&self->key_file, g_key_file_free); + + G_OBJECT_CLASS (gbp_sysroot_manager_parent_class)->finalize (object); +} + +void +gbp_sysroot_manager_class_init (GbpSysrootManagerClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = gbp_sysroot_manager_finalize; + + signals [TARGET_MODIFIED] = + g_signal_new_class_handler ("target-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + NULL, NULL, NULL, NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_INT); + + signals [TARGET_NAME_CHANGED] = + g_signal_new_class_handler ("target-name-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + NULL, NULL, NULL, NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRING); + + signals [TARGET_ARCH_CHANGED] = + g_signal_new_class_handler ("target-arch-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + NULL, NULL, NULL, NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRING); +} + +static void +gbp_sysroot_manager_init (GbpSysrootManager *self) +{ + gchar *conf_file = NULL; + g_autoptr(GError) error = NULL; + + conf_file = sysroot_manager_get_path (); + self->key_file = g_key_file_new (); + g_key_file_load_from_file (self->key_file, conf_file, G_KEY_FILE_KEEP_COMMENTS, &error); + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_critical ("Error loading the sysroot configuration: %s", error->message); +} diff --git a/src/plugins/sysroot/gbp-sysroot-manager.h b/src/plugins/sysroot/gbp-sysroot-manager.h new file mode 100644 index 0000000000000000000000000000000000000000..5da6e30dba77aa2db407dc97061df60f5190932a --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-manager.h @@ -0,0 +1,62 @@ +/* gbp-sysroot-manager.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_MANAGER (gbp_sysroot_manager_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootManager, gbp_sysroot_manager, GBP, SYSROOT_MANAGER, GObject) + +typedef enum { + GBP_SYSROOT_MANAGER_TARGET_CHANGED, + GBP_SYSROOT_MANAGER_TARGET_CREATED, + GBP_SYSROOT_MANAGER_TARGET_REMOVED +} GbpSysrootManagerTargetModificationType; + +GbpSysrootManager *gbp_sysroot_manager_get_default (void); +gchar *gbp_sysroot_manager_create_target (GbpSysrootManager *self); +void gbp_sysroot_manager_remove_target (GbpSysrootManager *self, + const gchar *target); +void gbp_sysroot_manager_set_target_name (GbpSysrootManager *self, + const gchar *target, + const gchar *path); +gchar *gbp_sysroot_manager_get_target_name (GbpSysrootManager *self, + const gchar *target); +void gbp_sysroot_manager_set_target_arch (GbpSysrootManager *self, + const gchar *target, + const gchar *arch); +gchar *gbp_sysroot_manager_get_target_arch (GbpSysrootManager *self, + const gchar *target); +void gbp_sysroot_manager_set_target_path (GbpSysrootManager *self, + const gchar *target, + const gchar *path); +gchar *gbp_sysroot_manager_get_target_path (GbpSysrootManager *self, + const gchar *target); +void gbp_sysroot_manager_set_target_pkg_config_path (GbpSysrootManager *self, + const gchar *target, + const gchar *path); +gchar *gbp_sysroot_manager_get_target_pkg_config_path (GbpSysrootManager *self, + const gchar *target); +gchar **gbp_sysroot_manager_list (GbpSysrootManager *self); + +G_END_DECLS diff --git a/src/plugins/sysroot/gbp-sysroot-preferences-addin.c b/src/plugins/sysroot/gbp-sysroot-preferences-addin.c new file mode 100644 index 0000000000000000000000000000000000000000..607340ab4accc1c00d29b7770d23f7eda3e845bf --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-preferences-addin.c @@ -0,0 +1,205 @@ +/* gbp-sysroot-preferences.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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, eitIher 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-preferences-addin" + +#include + +#include "gbp-sysroot-preferences-addin.h" +#include "gbp-sysroot-preferences-row.h" +#include "gbp-sysroot-manager.h" + +struct _GbpSysrootPreferencesAddin +{ + GObject parent_instance; + + GArray *ids; + DzlPreferences *preferences; +}; + +static void +sysroot_preferences_add_new (GbpSysrootPreferencesAddin *self, + GtkWidget *emitter) +{ + GtkWidget *pref_row = NULL; + guint id = 0; + g_autofree gchar *new_target; + GbpSysrootManager *sysroot_manager = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ADDIN (self)); + g_assert (DZL_IS_PREFERENCES_BIN (emitter)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + new_target = gbp_sysroot_manager_create_target (sysroot_manager); + pref_row = g_object_new (GBP_TYPE_SYSROOT_PREFERENCES_ROW, + "visible", TRUE, + "sysroot-id", new_target, + NULL); + + id = dzl_preferences_add_custom (self->preferences, "sdk", "sysroot", pref_row, "", 1); + g_array_append_val (self->ids, id); + + gbp_sysroot_preferences_row_show_popup (GBP_SYSROOT_PREFERENCES_ROW (pref_row)); +} + +static GtkWidget * +sysroot_preferences_get_add_widget (GbpSysrootPreferencesAddin *self) +{ + GtkWidget *bin = NULL; + GtkWidget *grid = NULL; + GtkWidget *label = NULL; + GtkWidget *subtitle = NULL; + GtkWidget *image = NULL; + + bin = g_object_new (DZL_TYPE_PREFERENCES_BIN, + "visible", TRUE, + NULL); + + grid = g_object_new (GTK_TYPE_GRID, + "visible", TRUE, + NULL); + + label = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "label", _("Add sysroot"), + "xalign", 0.0f, + "hexpand", TRUE, + NULL); + + subtitle = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "label", g_markup_printf_escaped ("%s", _("Define a new sysroot target to build against a different target")), + "use-markup", TRUE, + "xalign", 0.0f, + "hexpand", TRUE, + NULL); + + gtk_style_context_add_class (gtk_widget_get_style_context (subtitle), GTK_STYLE_CLASS_DIM_LABEL); + + image = g_object_new (GTK_TYPE_IMAGE, + "visible", TRUE, + "icon-name", "list-add-symbolic", + "valign", GTK_ALIGN_CENTER, + NULL); + + gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), subtitle, 0, 1, 1, 1); + gtk_grid_attach (GTK_GRID (grid), image, 1, 0, 1, 2); + + gtk_container_add (GTK_CONTAINER (bin), grid); + + g_signal_connect_object (bin, + "preference-activated", + G_CALLBACK (sysroot_preferences_add_new), + self, + G_CONNECT_SWAPPED); + + return bin; +} + +static void +gbp_sysroot_preferences_addin_load (IdePreferencesAddin *addin, + DzlPreferences *preferences) +{ + GbpSysrootPreferencesAddin *self = (GbpSysrootPreferencesAddin *)addin; + GtkWidget *widget = NULL; + GbpSysrootManager *sysroot_manager = NULL; + g_auto(GStrv) sysroots = NULL; + guint sysroots_length = 0; + guint id = 0; + + IDE_ENTRY; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ADDIN (self)); + g_assert (DZL_IS_PREFERENCES (preferences)); + + self->ids = g_array_new (FALSE, FALSE, sizeof (guint)); + self->preferences = preferences; + + dzl_preferences_add_list_group (preferences, "sdk", "sysroot", _("Sysroots"), GTK_SELECTION_NONE, 0); + + widget = sysroot_preferences_get_add_widget (self); + id = dzl_preferences_add_custom (preferences, "sdk", "sysroot", widget, "", 0); + + g_array_append_val (self->ids, id); + + sysroot_manager = gbp_sysroot_manager_get_default (); + sysroots = gbp_sysroot_manager_list (sysroot_manager); + sysroots_length = g_strv_length (sysroots); + for (guint i = 0; i < sysroots_length; i++) + { + GtkWidget *pref_row = g_object_new (GBP_TYPE_SYSROOT_PREFERENCES_ROW, + "visible", TRUE, + "sysroot-id", sysroots[i], + NULL); + + id = dzl_preferences_add_custom (self->preferences, "sdk", "sysroot", pref_row, NULL, i); + g_array_append_val (self->ids, id); + } + + IDE_EXIT; +} + +static void +gbp_sysroot_preferences_addin_unload (IdePreferencesAddin *addin, + DzlPreferences *preferences) +{ + GbpSysrootPreferencesAddin *self = (GbpSysrootPreferencesAddin *)addin; + + IDE_ENTRY; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ADDIN (self)); + g_assert (DZL_IS_PREFERENCES (preferences)); + + /* Clear preferences so reload code doesn't try to + * make forward progress updating items. + */ + self->preferences = NULL; + + for (guint i = 0; i < self->ids->len; i++) + { + guint id = g_array_index (self->ids, guint, i); + + dzl_preferences_remove_id (preferences, id); + } + + g_clear_pointer (&self->ids, g_array_unref); + + IDE_EXIT; +} + +static void +preferences_addin_iface_init (IdePreferencesAddinInterface *iface) +{ + iface->load = gbp_sysroot_preferences_addin_load; + iface->unload = gbp_sysroot_preferences_addin_unload; +} + +G_DEFINE_TYPE_EXTENDED (GbpSysrootPreferencesAddin, gbp_sysroot_preferences_addin, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN, preferences_addin_iface_init)) + +static void +gbp_sysroot_preferences_addin_class_init (GbpSysrootPreferencesAddinClass *klass) +{ +} + +static void +gbp_sysroot_preferences_addin_init (GbpSysrootPreferencesAddin *self) +{ +} diff --git a/src/plugins/sysroot/gbp-sysroot-preferences-addin.h b/src/plugins/sysroot/gbp-sysroot-preferences-addin.h new file mode 100644 index 0000000000000000000000000000000000000000..e8a4072cc3e28576b7dead83e716bc5ce6dc16a5 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-preferences-addin.h @@ -0,0 +1,30 @@ +/* gbp-sysroot-preferences.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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, eitIher 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_PREFERENCES_ADDIN (gbp_sysroot_preferences_addin_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootPreferencesAddin, gbp_sysroot_preferences_addin, GBP, SYSROOT_PREFERENCES_ADDIN, GObject) + +G_END_DECLS diff --git a/src/plugins/sysroot/gbp-sysroot-preferences-row.c b/src/plugins/sysroot/gbp-sysroot-preferences-row.c new file mode 100644 index 0000000000000000000000000000000000000000..e0320cd693f0c744365867601bca172f18ce1593 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-preferences-row.c @@ -0,0 +1,312 @@ +/* gbp-sysroot-preferences-row.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-preferences-row" + +#include "gbp-sysroot-preferences-row.h" +#include "gbp-sysroot-manager.h" + +struct _GbpSysrootPreferencesRow +{ + DzlPreferencesBin parent_instance; + gchar *sysroot_id; + GtkLabel *display_name; + GtkEntry *name_entry; + DzlFileChooserEntry *sysroot_entry; + GtkEntry *pkg_config_entry; + GtkComboBox *arch_combobox; + GtkButton *delete_button; + GtkWidget *popover; +}; + +G_DEFINE_TYPE (GbpSysrootPreferencesRow, gbp_sysroot_preferences_row, DZL_TYPE_PREFERENCES_BIN) + +enum { + PROP_0, + PROP_SYSROOT_ID, + N_PROPS +}; + +static GParamSpec *properties [N_PROPS]; + +static void +sysroot_preferences_row_name_changed (GbpSysrootPreferencesRow *self, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_assert (GTK_IS_ENTRY (user_data)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + gbp_sysroot_manager_set_target_name (sysroot_manager, + self->sysroot_id, + gtk_entry_get_text (GTK_ENTRY (user_data))); +} + +static void +sysroot_preferences_row_sysroot_changed (GbpSysrootPreferencesRow *self, + GParamSpec *pspec, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + g_autofree gchar *sysroot_path = NULL; + GFile *file; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_assert (DZL_IS_FILE_CHOOSER_ENTRY (user_data)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + file = dzl_file_chooser_entry_get_file (DZL_FILE_CHOOSER_ENTRY (user_data)); + sysroot_path = g_file_get_path (file); + gbp_sysroot_manager_set_target_path (sysroot_manager, + self->sysroot_id, + sysroot_path); +} + +static void +sysroot_preferences_row_arch_changed (GbpSysrootPreferencesRow *self, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_assert (GTK_IS_COMBO_BOX (user_data)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + gbp_sysroot_manager_set_target_arch (sysroot_manager, + self->sysroot_id, + gtk_combo_box_get_active_id (GTK_COMBO_BOX (user_data))); +} + +static void +sysroot_preferences_row_pkg_config_changed (GbpSysrootPreferencesRow *self, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_assert (GTK_IS_ENTRY (user_data)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + gbp_sysroot_manager_set_target_pkg_config_path (sysroot_manager, + self->sysroot_id, + gtk_entry_get_text (GTK_ENTRY (user_data))); +} + +static void +sysroot_preferences_row_target_changed (GbpSysrootPreferencesRow *self, + const gchar *target, + GbpSysrootManagerTargetModificationType mod_type, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + g_autofree gchar *value = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_assert (GBP_IS_SYSROOT_MANAGER (user_data)); + + if (mod_type != GBP_SYSROOT_MANAGER_TARGET_CHANGED) + return; + + if (g_strcmp0 (target, self->sysroot_id) != 0) + return; + + sysroot_manager = GBP_SYSROOT_MANAGER (user_data); + value = gbp_sysroot_manager_get_target_pkg_config_path (sysroot_manager, + self->sysroot_id); + if (value != NULL) + gtk_entry_set_text (self->pkg_config_entry, value); +} + +static void +sysroot_preferences_row_clicked (GbpSysrootPreferencesRow *self, + gpointer user_data) +{ + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + + gbp_sysroot_preferences_row_show_popup (self); +} + +static void +sysroot_preferences_delete (GbpSysrootPreferencesRow *self, + gpointer user_data) +{ + GbpSysrootManager *sysroot_manager = NULL; + + g_assert (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + gbp_sysroot_manager_remove_target (sysroot_manager, self->sysroot_id); + + /* The row is wrapped into a GtkListBoxRow that won't be removed when child is destroyed */ + gtk_widget_destroy (gtk_widget_get_parent (GTK_WIDGET (self))); +} + +static void +gbp_sysroot_preferences_row_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GbpSysrootPreferencesRow *self = GBP_SYSROOT_PREFERENCES_ROW (object); + + switch (prop_id) + { + case PROP_SYSROOT_ID: + g_value_set_string (value, self->sysroot_id); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gbp_sysroot_preferences_row_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GbpSysrootPreferencesRow *self = GBP_SYSROOT_PREFERENCES_ROW (object); + + switch (prop_id) + { + case PROP_SYSROOT_ID: + self->sysroot_id = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gbp_sysroot_preferences_row_finalize (GObject *object) +{ + GbpSysrootPreferencesRow *self = (GbpSysrootPreferencesRow *) object; + + g_clear_pointer (&self->sysroot_id, g_free); + + G_OBJECT_CLASS (gbp_sysroot_preferences_row_parent_class)->finalize (object); +} + +/** + * gbp_sysroot_preferences_row_show_popup: + * @self: a #GbpSysrootPreferencesRow + * + * Requests the configuration popover the be shown over the widget. + */ +void +gbp_sysroot_preferences_row_show_popup (GbpSysrootPreferencesRow *self) +{ + g_return_if_fail (GBP_IS_SYSROOT_PREFERENCES_ROW (self)); + g_return_if_fail (GTK_IS_POPOVER (self->popover)); + + gtk_popover_popup (GTK_POPOVER (self->popover)); + gtk_popover_set_modal (GTK_POPOVER (self->popover), TRUE); +} + +static void +gbp_sysroot_preferences_row_constructed (GObject *object) +{ + GbpSysrootManager *sysroot_manager = NULL; + g_autofree gchar *value = NULL; + GbpSysrootPreferencesRow *self = (GbpSysrootPreferencesRow *) object; + + sysroot_manager = gbp_sysroot_manager_get_default (); + gtk_entry_set_text (self->name_entry, + gbp_sysroot_manager_get_target_name (sysroot_manager, self->sysroot_id)); + gtk_combo_box_set_active_id (self->arch_combobox, gbp_sysroot_manager_get_target_arch (sysroot_manager, self->sysroot_id)); + dzl_file_chooser_entry_set_file (self->sysroot_entry, + g_file_new_for_path (gbp_sysroot_manager_get_target_path (sysroot_manager, self->sysroot_id))); + value = gbp_sysroot_manager_get_target_pkg_config_path (sysroot_manager, self->sysroot_id); + if (value != NULL) + gtk_entry_set_text (self->pkg_config_entry, value); + + g_signal_connect_object (self->name_entry, + "changed", + G_CALLBACK (sysroot_preferences_row_name_changed), + self, + G_CONNECT_SWAPPED); + + g_signal_connect_object (self->arch_combobox, + "changed", + G_CALLBACK (sysroot_preferences_row_arch_changed), + self, + G_CONNECT_SWAPPED); + + g_signal_connect_object (self->sysroot_entry, + "notify::file", + G_CALLBACK (sysroot_preferences_row_sysroot_changed), + self, + G_CONNECT_SWAPPED); + + g_signal_connect_object (self->pkg_config_entry, + "changed", + G_CALLBACK (sysroot_preferences_row_pkg_config_changed), + self, + G_CONNECT_SWAPPED); + + g_signal_connect_object (sysroot_manager, + "target-changed", + G_CALLBACK (sysroot_preferences_row_target_changed), + self, + G_CONNECT_SWAPPED); +} + +static void +gbp_sysroot_preferences_row_class_init (GbpSysrootPreferencesRowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gbp_sysroot_preferences_row_finalize; + object_class->get_property = gbp_sysroot_preferences_row_get_property; + object_class->set_property = gbp_sysroot_preferences_row_set_property; + object_class->constructed = gbp_sysroot_preferences_row_constructed; + + properties [PROP_SYSROOT_ID] = + g_param_spec_string ("sysroot-id", + "Sysroot ID", + "Internal id of the sysroot", + NULL, + (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPS, properties); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/plugins/sysroot-plugin/gbp-sysroot-preferences-row.ui"); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, display_name); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, popover); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, name_entry); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, arch_combobox); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, sysroot_entry); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, pkg_config_entry); + gtk_widget_class_bind_template_child (widget_class, GbpSysrootPreferencesRow, delete_button); +} + +static void +gbp_sysroot_preferences_row_init (GbpSysrootPreferencesRow *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + g_signal_connect (self, "preference-activated", G_CALLBACK (sysroot_preferences_row_clicked), NULL); + g_signal_connect_swapped (self->delete_button, "clicked", G_CALLBACK (sysroot_preferences_delete), self); + g_object_bind_property (self->name_entry, "text", self->display_name, "label", 0); +} diff --git a/src/plugins/sysroot/gbp-sysroot-preferences-row.h b/src/plugins/sysroot/gbp-sysroot-preferences-row.h new file mode 100644 index 0000000000000000000000000000000000000000..ac3e08206955bcd689d5d3494f9030cdd58e4837 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-preferences-row.h @@ -0,0 +1,32 @@ +/* gbp-sysroot-preferences-row.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_PREFERENCES_ROW (gbp_sysroot_preferences_row_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootPreferencesRow, gbp_sysroot_preferences_row, GBP, SYSROOT_PREFERENCES_ROW, DzlPreferencesBin) + +void gbp_sysroot_preferences_row_show_popup (GbpSysrootPreferencesRow *self); + +G_END_DECLS diff --git a/src/plugins/sysroot/gbp-sysroot-preferences-row.ui b/src/plugins/sysroot/gbp-sysroot-preferences-row.ui new file mode 100644 index 0000000000000000000000000000000000000000..a97588c345996e2a83bb8bbed3d6601fa76205d6 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-preferences-row.ui @@ -0,0 +1,170 @@ + + + + + + + + + + + i386 + + + x86_64 + + + arm + + + aarch64 + + + + + image + bottom + true + + + horizontal + 12 + 6 + 6 + true + + + true + 1.0 + Name + + + 0 + 0 + + + + + true + true + true + + + 1 + 0 + + + + + true + 1.0 + Architecture + + + 0 + 1 + + + + + true + true + true + arch_liststore + 0 + 0 + 0 + + + 1 + 1 + + + + + true + 1.0 + Sysroot path + + + 0 + 2 + + + + + true + true + true + true + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + + + 1 + 2 + + + + + true + 1.0 + Pkg-config paths + + + 0 + 3 + + + + + true + true + true + + + 1 + 3 + + + + + + Delete + true + true + true + end + + + 0 + 4 + 2 + + + + + + diff --git a/src/plugins/sysroot/gbp-sysroot-runtime-provider.c b/src/plugins/sysroot/gbp-sysroot-runtime-provider.c new file mode 100644 index 0000000000000000000000000000000000000000..5c12447150f41d5d9f93cdf8dc17d6d814c14777 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-runtime-provider.c @@ -0,0 +1,171 @@ +/* gbp-sysroot-runtime-provider.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-runtime-provider" + +#include + +#include "gbp-sysroot-runtime.h" +#include "gbp-sysroot-runtime-provider.h" +#include "gbp-sysroot-manager.h" + +struct _GbpSysrootRuntimeProvider +{ + IdeObject parent_instance; + + GPtrArray *runtimes; + IdeRuntimeManager *runtime_manager; +}; + +static void runtime_provider_iface_init (IdeRuntimeProviderInterface *iface); + +G_DEFINE_TYPE_EXTENDED (GbpSysrootRuntimeProvider, + gbp_sysroot_runtime_provider, + IDE_TYPE_OBJECT, + 0, + G_IMPLEMENT_INTERFACE (IDE_TYPE_RUNTIME_PROVIDER, + runtime_provider_iface_init)) + +static void +sysroot_runtime_provider_remove_target (GbpSysrootRuntimeProvider *self, + const gchar *target) +{ + if (self->runtimes != NULL) + { + for (guint i= 0; i < self->runtimes->len; i++) + { + GbpSysrootRuntime *runtime = g_ptr_array_index (self->runtimes, i); + const gchar *sysroot_id = gbp_sysroot_runtime_get_sysroot_id (runtime); + + if (g_strcmp0 (target, sysroot_id) == 0) + { + ide_runtime_manager_remove (self->runtime_manager, IDE_RUNTIME (runtime)); + return; + } + } + } +} + +static void +sysroot_runtime_provider_add_target (GbpSysrootRuntimeProvider *self, + const gchar *target) +{ + g_autoptr(GbpSysrootRuntime) runtime = NULL; + IdeContext *context = NULL; + + context = ide_object_get_context (IDE_OBJECT (self->runtime_manager)); + runtime = gbp_sysroot_runtime_new (context, target); + + ide_runtime_manager_add (self->runtime_manager, IDE_RUNTIME (runtime)); + g_ptr_array_add (self->runtimes, g_steal_pointer (&runtime)); +} + +static void +sysroot_runtime_provider_target_changed (GbpSysrootRuntimeProvider *self, + const gchar *target, + GbpSysrootManagerTargetModificationType mod_type, + gpointer user_data) +{ + if (mod_type == GBP_SYSROOT_MANAGER_TARGET_CREATED) + sysroot_runtime_provider_add_target (self, target); + else if (mod_type == GBP_SYSROOT_MANAGER_TARGET_REMOVED) + sysroot_runtime_provider_remove_target (self, target); +} + +static void +gbp_sysroot_runtime_provider_class_init (GbpSysrootRuntimeProviderClass *klass) +{ + +} + +static void +gbp_sysroot_runtime_provider_init (GbpSysrootRuntimeProvider *self) +{ + +} + +static void +gbp_sysroot_runtime_provider_load (IdeRuntimeProvider *provider, + IdeRuntimeManager *manager) +{ + GbpSysrootRuntimeProvider *self = (GbpSysrootRuntimeProvider *)provider; + GbpSysrootManager *sysroot_manager = NULL; + g_auto(GStrv) sysroots = NULL; + guint sysroots_length = 0; + + IDE_ENTRY; + + g_assert (GBP_IS_SYSROOT_RUNTIME_PROVIDER (self)); + g_assert (IDE_IS_RUNTIME_MANAGER (manager)); + + self->runtime_manager = manager; + self->runtimes = g_ptr_array_new_with_free_func (g_object_unref); + + sysroot_manager = gbp_sysroot_manager_get_default (); + sysroots = gbp_sysroot_manager_list (sysroot_manager); + sysroots_length = g_strv_length (sysroots); + for (guint i = 0; i < sysroots_length; i++) + { + sysroot_runtime_provider_add_target (self, sysroots[i]); + } + + g_signal_connect_swapped (sysroot_manager, + "target-changed", + G_CALLBACK (sysroot_runtime_provider_target_changed), + self); + + IDE_EXIT; +} + +static void +gbp_sysroot_runtime_provider_unload (IdeRuntimeProvider *provider, + IdeRuntimeManager *manager) +{ + GbpSysrootRuntimeProvider *self = (GbpSysrootRuntimeProvider *)provider; + GbpSysrootManager *sysroot_manager = NULL; + + IDE_ENTRY; + + g_assert (GBP_IS_SYSROOT_RUNTIME_PROVIDER (self)); + g_assert (IDE_IS_RUNTIME_MANAGER (manager)); + + sysroot_manager = gbp_sysroot_manager_get_default (); + g_object_unref (sysroot_manager); + + if (self->runtimes != NULL) + { + for (guint i= 0; i < self->runtimes->len; i++) + { + IdeRuntime *runtime = g_ptr_array_index (self->runtimes, i); + + ide_runtime_manager_remove (manager, runtime); + } + } + + g_clear_pointer (&self->runtimes, g_ptr_array_unref); + + IDE_EXIT; +} + +static void +runtime_provider_iface_init (IdeRuntimeProviderInterface *iface) +{ + iface->load = gbp_sysroot_runtime_provider_load; + iface->unload = gbp_sysroot_runtime_provider_unload; +} diff --git a/src/plugins/sysroot/gbp-sysroot-runtime-provider.h b/src/plugins/sysroot/gbp-sysroot-runtime-provider.h new file mode 100644 index 0000000000000000000000000000000000000000..bb20f477e28197175821ca3426c79b17ae2f2464 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-runtime-provider.h @@ -0,0 +1,30 @@ +/* gbp-sysroot-runtime-provider.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_RUNTIME_PROVIDER (gbp_sysroot_runtime_provider_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootRuntimeProvider, gbp_sysroot_runtime_provider, GBP, SYSROOT_RUNTIME_PROVIDER, IdeObject) + +G_END_DECLS diff --git a/src/plugins/sysroot/gbp-sysroot-runtime.c b/src/plugins/sysroot/gbp-sysroot-runtime.c new file mode 100644 index 0000000000000000000000000000000000000000..dc9d7fb1e6af6ee43d25c22d0d67f391188612d0 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-runtime.c @@ -0,0 +1,219 @@ +/* gbp-sysroot-runtime.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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, eitIher 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-runtime" + +#include "config.h" + +#include "gbp-sysroot-runtime.h" +#include "gbp-sysroot-manager.h" +#include "gbp-sysroot-subprocess-launcher.h" + +// This is a list of common libdirs to use +#define RUNTIME_PREFIX "sysroot:" + +struct _GbpSysrootRuntime +{ + IdeRuntime parent_instance; +}; + +G_DEFINE_TYPE (GbpSysrootRuntime, gbp_sysroot_runtime, IDE_TYPE_RUNTIME) + +GbpSysrootRuntime * +gbp_sysroot_runtime_new (IdeContext *context, + const gchar *sysroot_id) +{ + g_autoptr(IdeRuntime) runtime = NULL; + g_autofree gchar *built_id = NULL; + + g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL); + g_return_val_if_fail (sysroot_id != NULL, NULL); + + built_id = g_strconcat (RUNTIME_PREFIX, sysroot_id, NULL); + runtime = g_object_new (GBP_TYPE_SYSROOT_RUNTIME, + "id", g_steal_pointer (&built_id), + "context", context, + "display-name", "", + NULL); + return g_steal_pointer (&runtime); +} + +/** + * gbp_sysroot_runtime_get_sysroot_id: + * @self: a #GbpSysrootRuntime + * + * Gets the associated unique identifier of the sysroot target. + * + * Returns: (transfer none): the unique identifier of the sysroot target. + */ +const gchar * +gbp_sysroot_runtime_get_sysroot_id (GbpSysrootRuntime *self) +{ + const gchar *runtime_id = ide_runtime_get_id (IDE_RUNTIME (self)); + + if (!g_str_has_prefix (runtime_id, RUNTIME_PREFIX)) + return runtime_id; + + return runtime_id + strlen(RUNTIME_PREFIX); +} + +static IdeSubprocessLauncher * +gbp_sysroot_runtime_create_launcher (IdeRuntime *runtime, + GError **error) +{ + IdeSubprocessLauncher *ret; + GbpSysrootRuntime *self = GBP_SYSROOT_RUNTIME(runtime); + + IDE_ENTRY; + + g_return_val_if_fail (GBP_IS_SYSROOT_RUNTIME (self), NULL); + + ret = (IdeSubprocessLauncher *)gbp_sysroot_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE); + + if (ret != NULL) + { + GbpSysrootManager *sysroot_manager = NULL; + const gchar *env_var = NULL; + const gchar *sysroot_id = NULL; + g_autofree gchar *sysroot_cflags = NULL; + g_autofree gchar *sysroot_libdirs = NULL; + g_auto(GStrv) path_parts = NULL; + g_autofree gchar *sysroot_path = NULL; + g_autofree gchar *pkgconfig_dirs = NULL; + + sysroot_id = gbp_sysroot_runtime_get_sysroot_id (self); + + sysroot_manager = gbp_sysroot_manager_get_default (); + + ide_subprocess_launcher_set_run_on_host (ret, TRUE); + ide_subprocess_launcher_set_clear_env (ret, FALSE); + + sysroot_path = gbp_sysroot_manager_get_target_path (sysroot_manager, sysroot_id); + + env_var = ide_subprocess_launcher_getenv (ret, "CFLAGS"); + sysroot_cflags = g_strconcat ("--sysroot=", sysroot_path, NULL); + ide_subprocess_launcher_setenv (ret, "CFLAGS", g_strjoin (" ", sysroot_cflags, env_var, NULL), TRUE); + + ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_DIR", "", TRUE); + + ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_SYSROOT_DIR", g_strdup (sysroot_path), TRUE); + + pkgconfig_dirs = gbp_sysroot_manager_get_target_pkg_config_path (sysroot_manager, sysroot_id); + if (pkgconfig_dirs != NULL && g_strcmp0 (pkgconfig_dirs, "") != 0) + { + g_autofree gchar *libdir_tmp = NULL; + + libdir_tmp = g_strjoin (":", pkgconfig_dirs, sysroot_libdirs, NULL); + sysroot_libdirs = g_steal_pointer (&libdir_tmp); + } + + ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_LIBDIR", sysroot_libdirs, TRUE); + } + else + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "An unknown error ocurred"); + } + + IDE_RETURN (ret); +} + +static gchar ** +gbp_sysroot_runtime_get_system_include_dirs (IdeRuntime *runtime) +{ + GbpSysrootRuntime *self = GBP_SYSROOT_RUNTIME(runtime); + GbpSysrootManager *sysroot_manager = NULL; + const gchar *sysroot_id = NULL; + const gchar *result_paths[2] = { NULL, NULL }; + g_autofree gchar *sysroot_path = NULL; + g_autofree gchar *full_path = NULL; + + g_return_val_if_fail (GBP_IS_SYSROOT_RUNTIME (self), NULL); + + sysroot_manager = gbp_sysroot_manager_get_default (); + sysroot_id = gbp_sysroot_runtime_get_sysroot_id (self); + sysroot_path = gbp_sysroot_manager_get_target_path (sysroot_manager, sysroot_id); + full_path = g_build_path (G_DIR_SEPARATOR_S, sysroot_path, "/usr/include", NULL); + result_paths[0] = full_path; + + return g_strdupv ((char**) result_paths); +} + +static gchar * +gbp_sysroot_runtime_get_arch (IdeRuntime *runtime) +{ + GbpSysrootRuntime *self = GBP_SYSROOT_RUNTIME(runtime); + GbpSysrootManager *sysroot_manager = NULL; + const gchar *sysroot_id = NULL; + + g_return_val_if_fail (GBP_IS_SYSROOT_RUNTIME (self), NULL); + + sysroot_manager = gbp_sysroot_manager_get_default (); + sysroot_id = gbp_sysroot_runtime_get_sysroot_id (self); + return gbp_sysroot_manager_get_target_arch (sysroot_manager, sysroot_id); +} + +static void +sysroot_runtime_target_name_changed (GbpSysrootRuntime *self, + gchar *target, + gchar *new_name, + gpointer user_data) +{ + const gchar* sysroot_id = gbp_sysroot_runtime_get_sysroot_id (self); + + if (g_strcmp0 (target, sysroot_id) == 0) + ide_runtime_set_display_name (IDE_RUNTIME (self), new_name); +} + +static void +gbp_sysroot_runtime_constructed (GObject *object) +{ + GbpSysrootManager *sysroot_manager = NULL; + g_autofree gchar *display_name = NULL; + const gchar* sysroot_id = NULL; + + sysroot_id = gbp_sysroot_runtime_get_sysroot_id (GBP_SYSROOT_RUNTIME (object)); + sysroot_manager = gbp_sysroot_manager_get_default (); + display_name = gbp_sysroot_manager_get_target_name (sysroot_manager, sysroot_id); + ide_runtime_set_display_name (IDE_RUNTIME (object), display_name); + + g_signal_connect_swapped (sysroot_manager, "target-name-changed", G_CALLBACK (sysroot_runtime_target_name_changed), object); +} + +static void +gbp_sysroot_runtime_class_init (GbpSysrootRuntimeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + IdeRuntimeClass *runtime_class = IDE_RUNTIME_CLASS (klass); + + object_class->constructed = gbp_sysroot_runtime_constructed; + + runtime_class->create_launcher = gbp_sysroot_runtime_create_launcher; + runtime_class->get_system_include_dirs = gbp_sysroot_runtime_get_system_include_dirs; + runtime_class->get_arch = gbp_sysroot_runtime_get_arch; +} + +static void +gbp_sysroot_runtime_init (GbpSysrootRuntime *self) +{ + +} + diff --git a/src/plugins/sysroot/gbp-sysroot-runtime.h b/src/plugins/sysroot/gbp-sysroot-runtime.h new file mode 100644 index 0000000000000000000000000000000000000000..11504a3c11ff8cccf2cfcc04bf4be2f23e34aaae --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-runtime.h @@ -0,0 +1,34 @@ +/* gbp-sysroot-runtime.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_RUNTIME (gbp_sysroot_runtime_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootRuntime, gbp_sysroot_runtime, GBP, SYSROOT_RUNTIME, IdeRuntime) + +GbpSysrootRuntime *gbp_sysroot_runtime_new (IdeContext *context, + const gchar *sysroot_id); +const gchar *gbp_sysroot_runtime_get_sysroot_id (GbpSysrootRuntime *self); + +G_END_DECLS diff --git a/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.c b/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.c new file mode 100644 index 0000000000000000000000000000000000000000..262b4d411c1ce6cbb1d0d0945e8bb947c9b681c8 --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.c @@ -0,0 +1,89 @@ +/* gbp-sysroot-subprocess-launcher.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#define G_LOG_DOMAIN "gbp-sysroot-subprocess-launcher" + +#include + +#include "gbp-sysroot-subprocess-launcher.h" + +struct _GbpSysrootSubprocessLauncher +{ + IdeSubprocessLauncher parent_instance; +}; + +G_DEFINE_TYPE (GbpSysrootSubprocessLauncher, + gbp_sysroot_subprocess_launcher, + IDE_TYPE_SUBPROCESS_LAUNCHER) + +GbpSysrootSubprocessLauncher * +gbp_sysroot_subprocess_launcher_new (GSubprocessFlags flags) +{ + return g_object_new (GBP_TYPE_SYSROOT_SUBPROCESS_LAUNCHER, + "flags", flags, + NULL); +} + +static IdeSubprocess * +gbp_sysroot_subprocess_launcher_spawn (IdeSubprocessLauncher *self, + GCancellable *cancellable, + GError **error) +{ + g_autofree gchar *argv = NULL; + const gchar * const *args = NULL; + g_autoptr(GString) cmd = NULL; + + g_assert (GBP_IS_SYSROOT_SUBPROCESS_LAUNCHER (self)); + g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + + /* don't prepend `sh -c` twice */ + args = ide_subprocess_launcher_get_argv (self); + if (args[0] != NULL && g_strcmp0 (args[0], "sh") == 0 && g_strcmp0 (args[1], "-c") == 0) + return IDE_SUBPROCESS_LAUNCHER_CLASS (gbp_sysroot_subprocess_launcher_parent_class)->spawn (self, cancellable, error); + + argv = ide_subprocess_launcher_pop_argv (self); + cmd = g_string_new (argv); + + while ((argv = ide_subprocess_launcher_pop_argv (self)) != NULL) + { + g_autofree gchar *arg = g_shell_quote(argv); + g_string_prepend (cmd, " "); + g_string_prepend (cmd, arg); + } + + ide_subprocess_launcher_push_argv (self, "sh"); + ide_subprocess_launcher_push_argv (self, "-c"); + ide_subprocess_launcher_push_argv (self, cmd->str); + + return IDE_SUBPROCESS_LAUNCHER_CLASS (gbp_sysroot_subprocess_launcher_parent_class)->spawn (self, cancellable, error); +} + +static void +gbp_sysroot_subprocess_launcher_class_init (GbpSysrootSubprocessLauncherClass *klass) +{ + IdeSubprocessLauncherClass *subprocess_launcher_class = IDE_SUBPROCESS_LAUNCHER_CLASS (klass); + + subprocess_launcher_class->spawn = gbp_sysroot_subprocess_launcher_spawn; +} + +static void +gbp_sysroot_subprocess_launcher_init (GbpSysrootSubprocessLauncher *self) +{ + +} diff --git a/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.h b/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.h new file mode 100644 index 0000000000000000000000000000000000000000..9e6f901c56c08de2717d53805e622a4a1e39ebbc --- /dev/null +++ b/src/plugins/sysroot/gbp-sysroot-subprocess-launcher.h @@ -0,0 +1,32 @@ +/* gbp-sysroot-subprocess-launcher.h + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define GBP_TYPE_SYSROOT_SUBPROCESS_LAUNCHER (gbp_sysroot_subprocess_launcher_get_type()) + +G_DECLARE_FINAL_TYPE (GbpSysrootSubprocessLauncher, gbp_sysroot_subprocess_launcher, GBP, SYSROOT_SUBPROCESS_LAUNCHER, IdeSubprocessLauncher) + +GbpSysrootSubprocessLauncher *gbp_sysroot_subprocess_launcher_new (GSubprocessFlags flags); + +G_END_DECLS diff --git a/src/plugins/sysroot/meson.build b/src/plugins/sysroot/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..ffdea996f49cb3d6f8ee2bbad0862c155707e750 --- /dev/null +++ b/src/plugins/sysroot/meson.build @@ -0,0 +1,28 @@ +if get_option('with_sysroot') + +sysroot_resources = gnome.compile_resources( + 'sysroot-resources', + 'sysroot.gresource.xml', + c_name: 'gbp_sysroot', +) + +sysroot_sources = [ + 'sysroot-plugin.c', + 'gbp-sysroot-manager.c', + 'gbp-sysroot-manager.h', + 'gbp-sysroot-preferences-addin.c', + 'gbp-sysroot-preferences-addin.h', + 'gbp-sysroot-preferences-row.c', + 'gbp-sysroot-preferences-row.h', + 'gbp-sysroot-runtime.c', + 'gbp-sysroot-runtime.h', + 'gbp-sysroot-runtime-provider.c', + 'gbp-sysroot-runtime-provider.h', + 'gbp-sysroot-subprocess-launcher.c', + 'gbp-sysroot-subprocess-launcher.h' +] + +gnome_builder_plugins_sources += files(sysroot_sources) +gnome_builder_plugins_sources += sysroot_resources[0] + +endif diff --git a/src/plugins/sysroot/sysroot-plugin.c b/src/plugins/sysroot/sysroot-plugin.c new file mode 100644 index 0000000000000000000000000000000000000000..404c6a45177b0e5fd5491918eefc2b7d60d1fdc3 --- /dev/null +++ b/src/plugins/sysroot/sysroot-plugin.c @@ -0,0 +1,30 @@ +/* sysroot-plugin.c + * + * Copyright (C) 2018 Corentin Noël + * Copyright (C) 2018 Collabora Ltd. + * + * 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 . + */ + +#include + +#include "gbp-sysroot-runtime-provider.h" +#include "gbp-sysroot-preferences-addin.h" + +void +gbp_sysroot_register_types (PeasObjectModule *module) +{ + peas_object_module_register_extension_type (module, IDE_TYPE_RUNTIME_PROVIDER, GBP_TYPE_SYSROOT_RUNTIME_PROVIDER); + peas_object_module_register_extension_type (module, IDE_TYPE_PREFERENCES_ADDIN, GBP_TYPE_SYSROOT_PREFERENCES_ADDIN); +} diff --git a/src/plugins/sysroot/sysroot.gresource.xml b/src/plugins/sysroot/sysroot.gresource.xml new file mode 100644 index 0000000000000000000000000000000000000000..298d19cefa2302e0b43478afcd0f283c2aec127e --- /dev/null +++ b/src/plugins/sysroot/sysroot.gresource.xml @@ -0,0 +1,9 @@ + + + + sysroot.plugin + + + gbp-sysroot-preferences-row.ui + + diff --git a/src/plugins/sysroot/sysroot.plugin b/src/plugins/sysroot/sysroot.plugin new file mode 100644 index 0000000000000000000000000000000000000000..e98638bc7eaa971df19df181327aa6af4f4d1243 --- /dev/null +++ b/src/plugins/sysroot/sysroot.plugin @@ -0,0 +1,8 @@ +[Plugin] +Module=sysroot-plugin +Name=Sysroot Support +Description=Provides sysroot support +Authors=Corentin Noël +Copyright=Copyright © 2018 Collabora Ltd. +Builtin=true +Embedded=gbp_sysroot_register_types