[gnome-builder/wip/tintou/sysroot-toolchain] sysroot: Provide the toolchain for OpenEmbedded targets
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/tintou/sysroot-toolchain] sysroot: Provide the toolchain for OpenEmbedded targets
- Date: Thu, 19 Apr 2018 15:12:49 +0000 (UTC)
commit afb78b801d3e2555671f844cee1aca02f85ad959
Author: Corentin Noël <corentin noel collabora co uk>
Date: Thu Apr 19 16:11:07 2018 +0100
sysroot: Provide the toolchain for OpenEmbedded targets
.../meson/gbp-meson-build-stage-cross-file.c | 230 +++++++++++++++
.../meson/gbp-meson-build-stage-cross-file.h | 35 +++
src/plugins/meson/gbp-meson-pipeline-addin.c | 77 +----
src/plugins/meson/meson.build | 2 +
src/plugins/sysroot/gbp-sysroot-runtime.c | 17 +-
.../sysroot/gbp-sysroot-toolchain-provider.c | 313 +++++++++++++++++++++
.../sysroot/gbp-sysroot-toolchain-provider.h | 30 ++
src/plugins/sysroot/meson.build | 4 +-
src/plugins/sysroot/sysroot-plugin.c | 2 +
9 files changed, 635 insertions(+), 75 deletions(-)
---
diff --git a/src/plugins/meson/gbp-meson-build-stage-cross-file.c
b/src/plugins/meson/gbp-meson-build-stage-cross-file.c
new file mode 100644
index 000000000..8d23c73b7
--- /dev/null
+++ b/src/plugins/meson/gbp-meson-build-stage-cross-file.c
@@ -0,0 +1,230 @@
+/* gbp-meson-build-stage-cross-file.c
+ *
+ * Copyright 2018 Corentin Noël <corentin noel collabora com>
+ * Copyright 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 <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-meson-build-stage-cross-file"
+
+#include "config.h"
+
+#include "gbp-meson-build-stage-cross-file.h"
+
+struct _GbpMesonBuildStageCrossFile
+{
+ IdeBuildStage parent_instance;
+ IdeToolchain *toolchain;
+};
+
+G_DEFINE_TYPE (GbpMesonBuildStageCrossFile, gbp_meson_build_stage_cross_file, IDE_TYPE_BUILD_STAGE)
+
+static void
+_g_key_file_set_string_quoted (GKeyFile *keyfile,
+ const gchar *group,
+ const gchar *key,
+ const gchar *unquoted_value)
+{
+ g_autofree gchar *quoted_value = NULL;
+
+ g_return_if_fail (keyfile != NULL);
+ g_return_if_fail (group != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (unquoted_value != NULL);
+
+ quoted_value = g_strdup_printf ("'%s'", unquoted_value);
+ g_key_file_set_string (keyfile, group, key, quoted_value);
+}
+
+static void
+_g_key_file_set_string_array_quoted (GKeyFile *keyfile,
+ const gchar *group,
+ const gchar *key,
+ const gchar *unquoted_value)
+{
+ g_autofree gchar *quoted_value = NULL;
+
+ g_return_if_fail (keyfile != NULL);
+ g_return_if_fail (group != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (unquoted_value != NULL);
+
+ quoted_value = g_strdup_printf ("['%s']", unquoted_value);
+ g_key_file_set_string (keyfile, group, key, quoted_value);
+}
+
+static void
+add_lang_executable (const gchar *lang,
+ const gchar *path,
+ GKeyFile *keyfile)
+{
+ if (g_strcmp0 (lang, IDE_TOOLCHAIN_TOOL_CPP) == 0)
+ lang = "cpp";
+
+ _g_key_file_set_string_quoted (keyfile, "binaries", lang, path);
+}
+
+static void
+gbp_meson_build_stage_cross_file_query (IdeBuildStage *stage,
+ IdeBuildPipeline *pipeline,
+ GCancellable *cancellable)
+{
+ GbpMesonBuildStageCrossFile *self = (GbpMesonBuildStageCrossFile *)stage;
+ g_autofree gchar *crossbuild_file = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_MESON_BUILD_STAGE_CROSS_FILE (self));
+ g_assert (IDE_IS_BUILD_PIPELINE (pipeline));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ crossbuild_file = gbp_meson_build_stage_cross_file_get_path (self, pipeline);
+ if (!g_file_test (crossbuild_file, G_FILE_TEST_EXISTS))
+ {
+ ide_build_stage_set_completed (stage, FALSE);
+ IDE_EXIT;
+ }
+
+ ide_build_stage_set_completed (stage, TRUE);
+
+ IDE_EXIT;
+}
+
+static gboolean
+gbp_meson_build_stage_cross_file_execute (IdeBuildStage *stage,
+ IdeBuildPipeline *pipeline,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GbpMesonBuildStageCrossFile *self = (GbpMesonBuildStageCrossFile *)stage;
+ g_autoptr(GKeyFile) crossbuild_keyfile = NULL;
+ g_autoptr(IdeTriplet) triplet = NULL;
+ g_autoptr(IdeSubprocessLauncher) env_launcher = NULL;
+ g_autofree gchar *crossbuild_file = NULL;
+ const gchar *binary_path;
+ const gchar *flags;
+ GHashTable *compilers;
+
+ IDE_ENTRY;
+
+ g_assert (GBP_IS_MESON_BUILD_STAGE_CROSS_FILE (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_assert (IDE_IS_TOOLCHAIN (self->toolchain));
+
+ ide_build_stage_set_active (stage, TRUE);
+
+ crossbuild_keyfile = g_key_file_new ();
+ triplet = ide_toolchain_get_host_triplet (self->toolchain);
+
+ compilers = ide_toolchain_get_tools_for_id (self->toolchain,
+ IDE_TOOLCHAIN_TOOL_CC);
+ g_hash_table_foreach (compilers, (GHFunc)add_lang_executable, crossbuild_keyfile);
+
+ binary_path = ide_toolchain_get_tool_for_language (self->toolchain,
+ IDE_TOOLCHAIN_LANGUAGE_ANY,
+ IDE_TOOLCHAIN_TOOL_AR);
+ if (binary_path != NULL)
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "ar", binary_path);
+
+ binary_path = ide_toolchain_get_tool_for_language (self->toolchain,
+ IDE_TOOLCHAIN_LANGUAGE_ANY,
+ IDE_TOOLCHAIN_TOOL_STRIP);
+ if (binary_path != NULL)
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "strip", binary_path);
+
+ binary_path = ide_toolchain_get_tool_for_language (self->toolchain,
+ IDE_TOOLCHAIN_LANGUAGE_ANY,
+ IDE_TOOLCHAIN_TOOL_PKG_CONFIG);
+ if (binary_path != NULL)
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "pkgconfig", binary_path);
+
+ binary_path = ide_toolchain_get_tool_for_language (self->toolchain,
+ IDE_TOOLCHAIN_LANGUAGE_ANY,
+ IDE_TOOLCHAIN_TOOL_EXEC);
+ if (binary_path != NULL)
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "exe_wrapper", binary_path);
+
+ binary_path = ide_triplet_get_kernel (triplet);
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "system", binary_path);
+
+ binary_path = ide_triplet_get_arch (triplet);
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "cpu_family", binary_path);
+
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "cpu", binary_path);
+ _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "endian", "little");
+
+ env_launcher = ide_build_pipeline_create_launcher (pipeline, error);
+ flags = ide_subprocess_launcher_getenv (env_launcher, "CFLAGS");
+ _g_key_file_set_string_array_quoted (crossbuild_keyfile, "properties", "c_args", flags);
+ flags = ide_subprocess_launcher_getenv (env_launcher, "LDFLAGS");
+ _g_key_file_set_string_array_quoted (crossbuild_keyfile, "properties", "c_link_args", flags);
+
+ crossbuild_file = gbp_meson_build_stage_cross_file_get_path (self, pipeline);
+ if (!g_key_file_save_to_file (crossbuild_keyfile, crossbuild_file, error))
+ IDE_RETURN (FALSE);
+
+ ide_build_stage_set_active (stage, FALSE);
+
+ IDE_RETURN (TRUE);
+}
+
+static void
+ide_build_stage_mkdirs_finalize (GObject *object)
+{
+ GbpMesonBuildStageCrossFile *self = (GbpMesonBuildStageCrossFile *)object;
+
+ g_clear_object (&self->toolchain);
+
+ G_OBJECT_CLASS (gbp_meson_build_stage_cross_file_parent_class)->finalize (object);
+}
+
+static void
+gbp_meson_build_stage_cross_file_class_init (GbpMesonBuildStageCrossFileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeBuildStageClass *stage_class = IDE_BUILD_STAGE_CLASS (klass);
+
+ object_class->finalize = ide_build_stage_mkdirs_finalize;
+
+ stage_class->execute = gbp_meson_build_stage_cross_file_execute;
+ stage_class->query = gbp_meson_build_stage_cross_file_query;
+}
+
+static void
+gbp_meson_build_stage_cross_file_init (GbpMesonBuildStageCrossFile *self)
+{
+
+}
+
+GbpMesonBuildStageCrossFile *
+gbp_meson_build_stage_cross_file_new (IdeContext *context,
+ IdeToolchain *toolchain)
+{
+ GbpMesonBuildStageCrossFile *build_stage = g_object_new (GBP_TYPE_MESON_BUILD_STAGE_CROSS_FILE,
+ "context", context,
+ NULL);
+ build_stage->toolchain = g_object_ref (toolchain);
+ return build_stage;
+}
+
+gchar *
+gbp_meson_build_stage_cross_file_get_path (GbpMesonBuildStageCrossFile *stage,
+ IdeBuildPipeline *pipeline)
+{
+ g_return_val_if_fail (GBP_IS_MESON_BUILD_STAGE_CROSS_FILE (stage), NULL);
+ g_return_val_if_fail (IDE_IS_BUILD_PIPELINE (pipeline), NULL);
+
+ return ide_build_pipeline_build_builddir_path (pipeline, "gnome-builder-meson.crossfile", NULL);
+}
diff --git a/src/plugins/meson/gbp-meson-build-stage-cross-file.h
b/src/plugins/meson/gbp-meson-build-stage-cross-file.h
new file mode 100644
index 000000000..4f06968eb
--- /dev/null
+++ b/src/plugins/meson/gbp-meson-build-stage-cross-file.h
@@ -0,0 +1,35 @@
+/* gbp-meson-build-stage-cross-file.h
+ *
+ * Copyright 2018 Corentin Noël <corentin noel collabora com>
+ * Copyright 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_MESON_BUILD_STAGE_CROSS_FILE (gbp_meson_build_stage_cross_file_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMesonBuildStageCrossFile, gbp_meson_build_stage_cross_file, GBP,
MESON_BUILD_STAGE_CROSS_FILE, IdeBuildStage)
+
+GbpMesonBuildStageCrossFile *gbp_meson_build_stage_cross_file_new (IdeContext *context,
+ IdeToolchain
*toolchain);
+gchar *gbp_meson_build_stage_cross_file_get_path (GbpMesonBuildStageCrossFile *stage,
+ IdeBuildPipeline
*pipeline);
+
+G_END_DECLS
diff --git a/src/plugins/meson/gbp-meson-pipeline-addin.c b/src/plugins/meson/gbp-meson-pipeline-addin.c
index afd37dabb..bc389eea2 100644
--- a/src/plugins/meson/gbp-meson-pipeline-addin.c
+++ b/src/plugins/meson/gbp-meson-pipeline-addin.c
@@ -21,6 +21,7 @@
#include <glib/gi18n.h>
#include "gbp-meson-toolchain.h"
+#include "gbp-meson-build-stage-cross-file.h"
#include "gbp-meson-build-system.h"
#include "gbp-meson-pipeline-addin.h"
@@ -44,31 +45,6 @@ on_stage_query (IdeBuildStage *stage,
ide_build_stage_set_completed (stage, FALSE);
}
-static void
-_g_key_file_set_string_quoted (GKeyFile *keyfile,
- const gchar *group,
- const gchar *key,
- const gchar *unquoted_value)
-{
- g_autofree gchar *quoted_value = NULL;
-
- g_return_if_fail (keyfile != NULL);
- g_return_if_fail (group != NULL);
- g_return_if_fail (key != NULL);
- g_return_if_fail (unquoted_value != NULL);
-
- quoted_value = g_strdup_printf ("'%s'", unquoted_value);
- g_key_file_set_string (keyfile, group, key, quoted_value);
-}
-
-static void
-add_lang_executable (gchar *lang,
- gchar *path,
- GKeyFile *keyfile)
-{
- _g_key_file_set_string_quoted (keyfile, "binaries", lang, path);
-}
-
static void
gbp_meson_pipeline_addin_load (IdeBuildPipelineAddin *addin,
IdeBuildPipeline *pipeline)
@@ -146,55 +122,18 @@ gbp_meson_pipeline_addin_load (IdeBuildPipelineAddin *addin,
if (NULL == (meson = ide_configuration_getenv (config, "MESON")))
meson = "meson";
- /* Create the toolchain file is required */
+ /* Create the toolchain file if required */
+
if (GBP_IS_MESON_TOOLCHAIN (toolchain))
crossbuild_file = g_strdup (gbp_meson_toolchain_get_file_path (GBP_MESON_TOOLCHAIN (toolchain)));
else if (g_strcmp0 (ide_toolchain_get_id (toolchain), "default") != 0)
{
- g_autoptr(GKeyFile) crossbuild_keyfile = NULL;
- g_autoptr(IdeTriplet) triplet = NULL;
- g_autofree gchar *crossfile_name = NULL;
- const gchar *binary_path;
- GHashTable *compilers;
+ GbpMesonBuildStageCrossFile *cross_file_stage;
+ cross_file_stage = gbp_meson_build_stage_cross_file_new (context, toolchain);
+ crossbuild_file = gbp_meson_build_stage_cross_file_get_path (cross_file_stage, pipeline);
- crossfile_name = g_strdup_printf ("gnome-builder-%s.crossfile", ide_toolchain_get_id (toolchain));
- crossbuild_file = ide_build_pipeline_build_builddir_path (pipeline, crossfile_name, NULL);
-
- crossbuild_keyfile = g_key_file_new ();
- triplet = ide_toolchain_get_host_triplet (toolchain);
-
- compilers = ide_toolchain_get_tools_for_id (toolchain,
- IDE_TOOLCHAIN_TOOL_CC);
- g_hash_table_foreach (compilers, (GHFunc)add_lang_executable, crossbuild_keyfile);
-
- binary_path = ide_toolchain_get_tool_for_language (toolchain,
- IDE_TOOLCHAIN_LANGUAGE_ANY,
- IDE_TOOLCHAIN_TOOL_AR);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "ar", binary_path);
-
- binary_path = ide_toolchain_get_tool_for_language (toolchain,
- IDE_TOOLCHAIN_LANGUAGE_ANY,
- IDE_TOOLCHAIN_TOOL_STRIP);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "strip", binary_path);
-
- binary_path = ide_toolchain_get_tool_for_language (toolchain,
- IDE_TOOLCHAIN_LANGUAGE_ANY,
- IDE_TOOLCHAIN_TOOL_PKG_CONFIG);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "pkgconfig", binary_path);
-
- binary_path = ide_toolchain_get_tool_for_language (toolchain,
- IDE_TOOLCHAIN_LANGUAGE_ANY,
- IDE_TOOLCHAIN_TOOL_EXEC);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "binaries", "exe_wrapper", binary_path);
-
- binary_path = ide_triplet_get_kernel (triplet);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "system", binary_path);
-
- binary_path = ide_triplet_get_arch (triplet);
- _g_key_file_set_string_quoted (crossbuild_keyfile, "host_machine", "cpu_family", binary_path);
-
- if (!g_key_file_save_to_file (crossbuild_keyfile, crossbuild_file, &error))
- IDE_GOTO (failure);
+ id = ide_build_pipeline_connect (pipeline, IDE_BUILD_PHASE_PREPARE, 0, IDE_BUILD_STAGE
(cross_file_stage));
+ ide_build_pipeline_addin_track (addin, id);
}
/* Setup our meson configure stage. */
diff --git a/src/plugins/meson/meson.build b/src/plugins/meson/meson.build
index 53ca7cd71..8337b0b67 100644
--- a/src/plugins/meson/meson.build
+++ b/src/plugins/meson/meson.build
@@ -8,6 +8,8 @@ meson_resources = gnome.compile_resources(
meson_sources = [
'meson-plugin.c',
+ 'gbp-meson-build-stage-cross-file.c',
+ 'gbp-meson-build-stage-cross-file.h',
'gbp-meson-build-system.c',
'gbp-meson-build-system.h',
'gbp-meson-build-target.c',
diff --git a/src/plugins/sysroot/gbp-sysroot-runtime.c b/src/plugins/sysroot/gbp-sysroot-runtime.c
index ec13aedfc..faa2e3388 100644
--- a/src/plugins/sysroot/gbp-sysroot-runtime.c
+++ b/src/plugins/sysroot/gbp-sysroot-runtime.c
@@ -90,21 +90,27 @@ gbp_sysroot_runtime_create_launcher (IdeRuntime *runtime,
if (ret != NULL)
{
GbpSysrootManager *sysroot_manager = NULL;
- g_autofree gchar *sysroot_cflags = NULL;
+ g_autofree gchar *sysroot_flag = NULL;
g_autofree gchar *sysroot_libdirs = NULL;
g_autofree gchar *sysroot_path = NULL;
g_autofree gchar *pkgconfig_dirs = NULL;
g_autofree gchar *cflags = NULL;
+ g_autofree gchar *ldflags = NULL;
g_auto(GStrv) path_parts = NULL;
- const gchar *env_var = NULL;
+ const gchar *previous_env = NULL;
const gchar *sysroot_id = NULL;
sysroot_id = gbp_sysroot_runtime_get_sysroot_id (self);
sysroot_manager = gbp_sysroot_manager_get_default ();
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);
- cflags = g_strjoin (" ", sysroot_cflags, env_var, NULL);
+ sysroot_flag = g_strconcat ("--sysroot=", sysroot_path, NULL);
+
+ previous_env = ide_subprocess_launcher_getenv (ret, "CFLAGS");
+ cflags = g_strjoin (" ", sysroot_flag, previous_env, NULL);
+
+ previous_env = ide_subprocess_launcher_getenv (ret, "LDFLAGS");
+ ldflags = g_strjoin (" ", sysroot_flag, previous_env, NULL);
+
pkgconfig_dirs = gbp_sysroot_manager_get_target_pkg_config_path (sysroot_manager, sysroot_id);
if (!dzl_str_empty0 (pkgconfig_dirs))
@@ -119,6 +125,7 @@ gbp_sysroot_runtime_create_launcher (IdeRuntime *runtime,
ide_subprocess_launcher_set_clear_env (ret, FALSE);
ide_subprocess_launcher_setenv (ret, "CFLAGS", cflags, TRUE);
+ ide_subprocess_launcher_setenv (ret, "LDFLAGS", ldflags, TRUE);
ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_DIR", "", TRUE);
ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_SYSROOT_DIR", g_strdup (sysroot_path), TRUE);
ide_subprocess_launcher_setenv (ret, "PKG_CONFIG_LIBDIR", sysroot_libdirs, TRUE);
diff --git a/src/plugins/sysroot/gbp-sysroot-toolchain-provider.c
b/src/plugins/sysroot/gbp-sysroot-toolchain-provider.c
new file mode 100644
index 000000000..015a8df69
--- /dev/null
+++ b/src/plugins/sysroot/gbp-sysroot-toolchain-provider.c
@@ -0,0 +1,313 @@
+/* gbp-sysroot-toolchain-provider.c
+ *
+ * Copyright 2018 Corentin Noël <corentin noel collabora com>
+ * Copyright 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 <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-sysroot-toolchain-provider"
+
+#include "gbp-sysroot-toolchain-provider.h"
+#include "gbp-sysroot-manager.h"
+
+struct _GbpSysrootToolchainProvider
+{
+ IdeObject parent_instance;
+ GPtrArray *toolchains;
+};
+
+static gchar *
+_create_tool_path (const gchar *base_path,
+ const gchar *original_basename,
+ const gchar *suffix)
+{
+ g_autofree gchar *tool_name = g_strdup_printf ("%s%s", original_basename, suffix);
+ g_autofree gchar *tool_path = g_build_filename (base_path, tool_name, NULL);
+ if (!g_file_test (tool_path, G_FILE_TEST_EXISTS))
+ return NULL;
+
+ return g_steal_pointer (&tool_path);
+}
+
+gchar *
+_test_sdk_dirs (const gchar *basepath,
+ const gchar *dir)
+{
+ g_auto(GStrv) parts = NULL;
+ guint parts_length;
+
+ g_return_val_if_fail (basepath != NULL, NULL);
+ g_return_val_if_fail (dir != NULL, NULL);
+
+ parts = g_strsplit (dir, "-", -1);
+ parts_length = g_strv_length (parts);
+
+ if (parts_length <= 1)
+ return NULL;
+
+ for (guint i = 1; i < parts_length - 1; i++)
+ {
+ g_autofree gchar *head = NULL;
+ g_autofree gchar *tail = NULL;
+ g_autofree gchar *total = NULL;
+ g_autofree gchar *total_path = NULL;
+ gchar *part = parts[i];
+
+ parts[i] = NULL;
+ head = g_strjoinv ("-", parts);
+ tail = g_strjoinv ("-", parts + i + 1);
+ total = g_strdup_printf ("%s-%ssdk-%s", head, part, tail);
+ total_path = g_build_filename (basepath, "..", total, NULL);
+ parts[i] = part;
+
+ if (g_file_test (total_path, G_FILE_TEST_EXISTS))
+ return g_steal_pointer (&total_path);
+ }
+
+ return NULL;
+}
+
+/* Yocto systems are the most used ones, but the native toolchain is in a different folder */
+IdeToolchain *
+gbp_sysroot_toolchain_provider_try_poky (GbpSysrootToolchainProvider *self,
+ const gchar *sysroot_id)
+{
+ g_autoptr(IdeTriplet) system_triplet = NULL;
+ g_autoptr(IdeTriplet) sysroot_triplet = NULL;
+ g_autoptr(GRegex) arch_regex = NULL;
+ g_autoptr(GError) regex_error = NULL;
+ g_autofree gchar *sysroot_path = NULL;
+ g_autofree gchar *sysroot_basename = NULL;
+ g_autofree gchar *arch_escaped = NULL;
+ g_autofree gchar *sdk_dir = NULL;
+ g_autofree gchar *sysroot_arch = NULL;
+ g_autofree gchar *sdk_path = NULL;
+ GbpSysrootManager *sysroot_manager;
+
+ g_assert (GBP_IS_SYSROOT_TOOLCHAIN_PROVIDER (self));
+ g_assert (sysroot_id != NULL);
+
+ sysroot_manager = gbp_sysroot_manager_get_default ();
+ sysroot_path = gbp_sysroot_manager_get_target_path (sysroot_manager, sysroot_id);
+ sysroot_basename = g_path_get_basename (sysroot_path);
+
+ /* we need to change something like aarch64-poky-linux to x86_64-pokysdk-linux */
+ sysroot_arch = gbp_sysroot_manager_get_target_arch (sysroot_manager, sysroot_id);
+ system_triplet = ide_triplet_new_from_system ();
+ sysroot_triplet = ide_triplet_new (sysroot_arch);
+
+ arch_escaped = g_regex_escape_string (ide_triplet_get_arch (sysroot_triplet), -1);
+ arch_regex = g_regex_new (arch_escaped, 0, 0, ®ex_error);
+ if (regex_error != NULL)
+ return NULL;
+
+ sdk_dir = g_regex_replace_literal (arch_regex, sysroot_basename, -1, 0, ide_triplet_get_arch
(system_triplet), 0, ®ex_error);
+ if (regex_error != NULL)
+ return NULL;
+
+ sdk_path = _test_sdk_dirs (sysroot_path, sdk_dir);
+
+ if (sdk_path != NULL)
+ {
+ g_autoptr(IdeSimpleToolchain) toolchain = NULL;
+ g_autoptr(GFile) sdk_file = NULL;
+ g_autofree gchar *toolchain_id = NULL;
+ g_autofree gchar *sdk_canonical_path = NULL;
+ g_autofree gchar *sdk_tools_path = NULL;
+ g_autofree gchar *sdk_cc_path = NULL;
+ g_autofree gchar *sdk_cpp_path = NULL;
+ g_autofree gchar *sdk_cplusplus_path = NULL;
+ g_autofree gchar *sdk_ar_path = NULL;
+ g_autofree gchar *sdk_ld_path = NULL;
+ g_autofree gchar *sdk_strip_path = NULL;
+ g_autofree gchar *sdk_pkg_config_path = NULL;
+ g_autofree gchar *qemu_static_name = NULL;
+ g_autofree gchar *qemu_static_path = NULL;
+ IdeContext *context;
+
+ sdk_file = g_file_new_for_path (sdk_path);
+ sdk_canonical_path = g_file_get_path (sdk_file);
+ toolchain_id = g_strdup_printf ("sysroot:%s", sdk_canonical_path);
+ context = ide_object_get_context (IDE_OBJECT (self));
+ toolchain = ide_simple_toolchain_new (context, toolchain_id);
+ ide_toolchain_set_host_triplet (IDE_TOOLCHAIN (toolchain), sysroot_triplet);
+
+ sdk_tools_path = g_build_filename (sdk_canonical_path, "usr", "bin", sysroot_basename, NULL);
+ sdk_cc_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-gcc");
+ sdk_cplusplus_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-g++");
+ sdk_cpp_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-cpp");
+ sdk_ar_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-ar");
+ sdk_ld_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-ld");
+ sdk_strip_path = _create_tool_path (sdk_tools_path, sysroot_basename, "-strip");
+ sdk_pkg_config_path = g_build_filename (sdk_canonical_path, "usr", "bin", "pkg-config", NULL);
+
+ if (sdk_cc_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_C,
IDE_TOOLCHAIN_TOOL_CC, sdk_cc_path);
+
+ if (sdk_cplusplus_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_CPLUSPLUS,
IDE_TOOLCHAIN_TOOL_CC, sdk_cplusplus_path);
+
+ if (sdk_ar_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_ANY,
IDE_TOOLCHAIN_TOOL_AR, sdk_ar_path);
+
+ if (sdk_ld_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_ANY,
IDE_TOOLCHAIN_TOOL_LD, sdk_ld_path);
+
+ if (sdk_strip_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_ANY,
IDE_TOOLCHAIN_TOOL_STRIP, sdk_strip_path);
+
+ if (g_file_test (sdk_pkg_config_path, G_FILE_TEST_EXISTS))
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_ANY,
IDE_TOOLCHAIN_TOOL_PKG_CONFIG, sdk_pkg_config_path);
+
+ qemu_static_name = g_strdup_printf ("qemu-%s-static", ide_triplet_get_arch (sysroot_triplet));
+ qemu_static_path = g_find_program_in_path (qemu_static_name);
+ if (qemu_static_path != NULL)
+ ide_simple_toolchain_set_tool_for_language (toolchain, IDE_TOOLCHAIN_LANGUAGE_ANY,
IDE_TOOLCHAIN_TOOL_EXEC, qemu_static_path);
+
+ return g_steal_pointer (&toolchain);
+ }
+
+ return NULL;
+}
+
+static void
+gbp_sysroot_toolchain_provider_load_worker (IdeTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GbpSysrootToolchainProvider *self = source_object;
+ g_autoptr(GPtrArray) toolchains = NULL;
+ g_auto(GStrv) sysroot_list = NULL;
+ GbpSysrootManager *sysroot_manager;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_TASK (task));
+ g_assert (GBP_IS_SYSROOT_TOOLCHAIN_PROVIDER (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ toolchains = g_ptr_array_new_with_free_func (g_object_unref);
+ sysroot_manager = gbp_sysroot_manager_get_default ();
+ sysroot_list = gbp_sysroot_manager_list (sysroot_manager);
+
+ for (guint i = 0; sysroot_list[i] != NULL; i++)
+ {
+ g_autoptr(IdeToolchain) toolchain = NULL;
+
+ toolchain = gbp_sysroot_toolchain_provider_try_poky (self, sysroot_list[i]);
+ if (toolchain != NULL)
+ g_ptr_array_add (toolchains, g_steal_pointer (&toolchain));
+ }
+
+ ide_task_return_pointer (task,
+ g_steal_pointer (&toolchains),
+ (GDestroyNotify)g_ptr_array_unref);
+
+ IDE_EXIT;
+}
+
+static void
+gbp_sysroot_toolchain_provider_load_async (IdeToolchainProvider *provider,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GbpSysrootToolchainProvider *self = (GbpSysrootToolchainProvider *)provider;
+ g_autoptr(IdeTask) task = NULL;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (GBP_IS_SYSROOT_TOOLCHAIN_PROVIDER (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_priority (task, G_PRIORITY_LOW);
+ ide_task_set_source_tag (task, gbp_sysroot_toolchain_provider_load_async);
+ ide_task_run_in_thread (task, gbp_sysroot_toolchain_provider_load_worker);
+
+ IDE_EXIT;
+}
+
+static gboolean
+gbp_sysroot_toolchain_provider_load_finish (IdeToolchainProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ GbpSysrootToolchainProvider *self = (GbpSysrootToolchainProvider *)provider;
+ g_autoptr(GPtrArray) toolchains = NULL;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (GBP_IS_SYSROOT_TOOLCHAIN_PROVIDER (self));
+ g_assert (IDE_IS_TASK (result));
+ g_assert (ide_task_is_valid (IDE_TASK (result), provider));
+
+ toolchains = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+ if (toolchains == NULL)
+ return FALSE;
+
+ g_clear_pointer (&self->toolchains, g_ptr_array_unref);
+ self->toolchains = g_ptr_array_ref (toolchains);
+
+ for (guint i = 0; i < toolchains->len; i++)
+ {
+ IdeToolchain *toolchain = g_ptr_array_index (toolchains, i);
+
+ g_assert (IDE_IS_TOOLCHAIN (toolchain));
+
+ ide_toolchain_provider_emit_added (provider, toolchain);
+ }
+
+ return TRUE;
+}
+
+void
+gbp_sysroot_toolchain_provider_unload (IdeToolchainProvider *provider,
+ IdeToolchainManager *manager)
+{
+ GbpSysrootToolchainProvider *self = (GbpSysrootToolchainProvider *) provider;
+
+ g_assert (GBP_IS_SYSROOT_TOOLCHAIN_PROVIDER (self));
+ g_assert (IDE_IS_TOOLCHAIN_MANAGER (manager));
+
+ g_clear_pointer (&self->toolchains, g_ptr_array_unref);
+}
+
+static void
+toolchain_provider_iface_init (IdeToolchainProviderInterface *iface)
+{
+ iface->load_async = gbp_sysroot_toolchain_provider_load_async;
+ iface->load_finish = gbp_sysroot_toolchain_provider_load_finish;
+ iface->unload = gbp_sysroot_toolchain_provider_unload;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GbpSysrootToolchainProvider,
+ gbp_sysroot_toolchain_provider,
+ IDE_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_TOOLCHAIN_PROVIDER,
+ toolchain_provider_iface_init))
+
+static void
+gbp_sysroot_toolchain_provider_class_init (GbpSysrootToolchainProviderClass *klass)
+{
+}
+
+static void
+gbp_sysroot_toolchain_provider_init (GbpSysrootToolchainProvider *self)
+{
+
+}
diff --git a/src/plugins/sysroot/gbp-sysroot-toolchain-provider.h
b/src/plugins/sysroot/gbp-sysroot-toolchain-provider.h
new file mode 100644
index 000000000..72899c9ac
--- /dev/null
+++ b/src/plugins/sysroot/gbp-sysroot-toolchain-provider.h
@@ -0,0 +1,30 @@
+/* gbp-sysroot-toolchain-provider.h
+ *
+ * Copyright 2018 Corentin Noël <corentin noel collabora com>
+ * Copyright 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_SYSROOT_TOOLCHAIN_PROVIDER (gbp_sysroot_toolchain_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpSysrootToolchainProvider, gbp_sysroot_toolchain_provider, GBP,
SYSROOT_TOOLCHAIN_PROVIDER, IdeObject)
+
+G_END_DECLS
diff --git a/src/plugins/sysroot/meson.build b/src/plugins/sysroot/meson.build
index ffdea996f..01c2b4d72 100644
--- a/src/plugins/sysroot/meson.build
+++ b/src/plugins/sysroot/meson.build
@@ -19,7 +19,9 @@ sysroot_sources = [
'gbp-sysroot-runtime-provider.c',
'gbp-sysroot-runtime-provider.h',
'gbp-sysroot-subprocess-launcher.c',
- 'gbp-sysroot-subprocess-launcher.h'
+ 'gbp-sysroot-subprocess-launcher.h',
+ 'gbp-sysroot-toolchain-provider.c',
+ 'gbp-sysroot-toolchain-provider.h'
]
gnome_builder_plugins_sources += files(sysroot_sources)
diff --git a/src/plugins/sysroot/sysroot-plugin.c b/src/plugins/sysroot/sysroot-plugin.c
index 404c6a451..b84f91669 100644
--- a/src/plugins/sysroot/sysroot-plugin.c
+++ b/src/plugins/sysroot/sysroot-plugin.c
@@ -21,10 +21,12 @@
#include "gbp-sysroot-runtime-provider.h"
#include "gbp-sysroot-preferences-addin.h"
+#include "gbp-sysroot-toolchain-provider.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);
+ peas_object_module_register_extension_type (module, IDE_TYPE_TOOLCHAIN_PROVIDER,
GBP_TYPE_SYSROOT_TOOLCHAIN_PROVIDER);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]