diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index 58a248e0..a9ef55fe 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -46,6 +46,8 @@ flatpak_builder_SOURCES = \ src/builder-flatpak-utils.h \ src/builder-git.c \ src/builder-git.h \ + src/builder-sdk-config.c \ + src/builder-sdk-config.h \ $(NULL) flatpak_builder_LDADD = $(AM_LDADD) $(BASE_LIBS) $(LIBELF_LIBS) $(YAML_LIBS) libglnx.la diff --git a/src/builder-context.c b/src/builder-context.c index f3aa1436..19e9612f 100644 --- a/src/builder-context.c +++ b/src/builder-context.c @@ -78,6 +78,8 @@ struct BuilderContext gboolean have_rofiles; gboolean run_tests; gboolean no_shallow_clone; + + BuilderSdkConfig *sdk_config; }; typedef struct @@ -113,6 +115,7 @@ builder_context_finalize (GObject *object) g_clear_object (&self->base_dir); g_clear_object (&self->soup_session); g_clear_object (&self->options); + g_clear_object (&self->sdk_config); g_free (self->arch); g_free (self->state_subdir); g_free (self->stop_at); @@ -980,6 +983,34 @@ builder_context_extend_env (BuilderContext *self, return envp; } +gboolean +builder_context_load_sdk_config (BuilderContext *self, + const char *sdk_path, + GError **error) +{ + g_autoptr(GFile) root = g_file_new_for_path (sdk_path); + g_autoptr(GFile) config_file = g_file_resolve_relative_path (root, "files/etc/flatpak-builder/defaults.json"); + g_autoptr(GError) local_error = NULL; + g_autoptr(BuilderSdkConfig) sdk_config = NULL; + + sdk_config = builder_sdk_config_from_file (config_file, &local_error); + if (sdk_config == NULL && + !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + + g_set_object (&self->sdk_config, sdk_config); + return TRUE; +} + +BuilderSdkConfig * +builder_context_get_sdk_config (BuilderContext *self) +{ + return self->sdk_config; +} + BuilderContext * builder_context_new (GFile *run_dir, GFile *app_dir, diff --git a/src/builder-context.h b/src/builder-context.h index f119220e..2c1a7691 100644 --- a/src/builder-context.h +++ b/src/builder-context.h @@ -25,6 +25,7 @@ #include #include "builder-options.h" #include "builder-utils.h" +#include "builder-sdk-config.h" G_BEGIN_DECLS @@ -139,6 +140,12 @@ gboolean builder_context_get_no_shallow_clone (BuilderContext *self); char ** builder_context_extend_env (BuilderContext *self, char **envp); +gboolean builder_context_load_sdk_config (BuilderContext *self, + const char *sdk_path, + GError **error); + +BuilderSdkConfig * builder_context_get_sdk_config (BuilderContext *self); + G_DEFINE_AUTOPTR_CLEANUP_FUNC (BuilderContext, g_object_unref) G_END_DECLS diff --git a/src/builder-manifest.c b/src/builder-manifest.c index c1ecf710..ab09ea9e 100644 --- a/src/builder-manifest.c +++ b/src/builder-manifest.c @@ -1463,6 +1463,34 @@ flatpak_info (gboolean opt_user, return NULL; } +static char * +flatpak_info_show_path (const char *id, + const char *branch, + BuilderContext *context) +{ + g_autofree char *sdk_info = NULL; + g_autofree char *arch_option = NULL; + g_auto(GStrv) sdk_info_lines = NULL; + int i; + + /* Unfortunately there is not flatpak info --show-path, so we have to look at the full flatpak info output */ + + arch_option = g_strdup_printf ("--arch=%s", builder_context_get_arch (context)); + + sdk_info = flatpak (NULL, "info", arch_option, id, branch, NULL); + if (sdk_info == NULL) + return NULL; + + sdk_info_lines = g_strsplit (sdk_info, "\n", -1); + for (i = 0; sdk_info_lines[i] != NULL; i++) + { + if (g_str_has_prefix (sdk_info_lines[i], "Location:")) + return g_strstrip (g_strdup (sdk_info_lines[i] + strlen ("Location:"))); + } + + return NULL; +} + gboolean builder_manifest_start (BuilderManifest *self, gboolean download_only, @@ -1472,6 +1500,7 @@ builder_manifest_start (BuilderManifest *self, { g_autofree char *arch_option = NULL; g_autoptr(GHashTable) names = g_hash_table_new (g_str_hash, g_str_equal); + g_autofree char *sdk_path = NULL; const char *stop_at; if (self->sdk == NULL) @@ -1490,6 +1519,11 @@ builder_manifest_start (BuilderManifest *self, self->sdk, builder_manifest_get_runtime_version (self)); + sdk_path = flatpak_info_show_path (self->sdk, builder_manifest_get_runtime_version (self), context); + if (sdk_path != NULL && + !builder_context_load_sdk_config (context, sdk_path, error)) + return FALSE; + self->runtime_commit = flatpak (NULL, "info", arch_option, "--show-commit", self->runtime, builder_manifest_get_runtime_version (self), NULL); if (!download_only && !allow_missing_runtimes && self->runtime_commit == NULL) diff --git a/src/builder-sdk-config.c b/src/builder-sdk-config.c new file mode 100644 index 00000000..d7601974 --- /dev/null +++ b/src/builder-sdk-config.c @@ -0,0 +1,236 @@ +/* + * Copyright © 2018 Codethink Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Valentin David + */ + +#include "builder-sdk-config.h" + +#include + +struct BuilderSdkConfig { + GObject parent; + + char *libdir; + char *cppflags; + char *cflags; + char *cxxflags; + char *ldflags; +}; + +typedef struct +{ + GObjectClass parent_class; +} BuilderSdkConfigClass; + +G_DEFINE_TYPE (BuilderSdkConfig, builder_sdk_config, G_TYPE_OBJECT) + +static void +builder_sdk_config_finalize (GObject *object) +{ + BuilderSdkConfig *self = (BuilderSdkConfig *) object; + + g_free (self->libdir); + g_free (self->cppflags); + g_free (self->cflags); + g_free (self->cxxflags); + g_free (self->ldflags); + + G_OBJECT_CLASS (builder_sdk_config_parent_class)->finalize (object); +} + +enum { + PROP_0, + PROP_LIBDIR, + PROP_CPPFLAGS, + PROP_CFLAGS, + PROP_CXXFLAGS, + PROP_LDFLAGS, + LAST_PROP +}; + +static void +builder_sdk_config_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BuilderSdkConfig *self = BUILDER_SDK_CONFIG (object); + + switch (prop_id) + { + case PROP_LIBDIR: + g_value_set_string (value, self->libdir); + break; + + case PROP_CPPFLAGS: + g_value_set_string (value, self->cppflags); + break; + + case PROP_CFLAGS: + g_value_set_string (value, self->cflags); + break; + + case PROP_CXXFLAGS: + g_value_set_string (value, self->cxxflags); + break; + + case PROP_LDFLAGS: + g_value_set_string (value, self->ldflags); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +builder_sdk_config_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BuilderSdkConfig *self = BUILDER_SDK_CONFIG (object); + + switch (prop_id) + { + case PROP_LIBDIR: + g_free (self->libdir); + self->libdir = g_value_dup_string(value); + break ; + + case PROP_CPPFLAGS: + g_free (self->cppflags); + self->cppflags = g_value_dup_string(value); + break ; + + case PROP_CFLAGS: + g_free (self->cflags); + self->cflags = g_value_dup_string(value); + break ; + + case PROP_CXXFLAGS: + g_free (self->cxxflags); + self->cxxflags = g_value_dup_string(value); + break ; + + case PROP_LDFLAGS: + g_free (self->ldflags); + self->ldflags = g_value_dup_string(value); + break ; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +builder_sdk_config_class_init (BuilderSdkConfigClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = builder_sdk_config_finalize; + object_class->get_property = builder_sdk_config_get_property; + object_class->set_property = builder_sdk_config_set_property; + + g_object_class_install_property (object_class, + PROP_LIBDIR, + g_param_spec_string ("libdir", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_CPPFLAGS, + g_param_spec_string ("cppflags", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_CFLAGS, + g_param_spec_string ("cflags", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_CXXFLAGS, + g_param_spec_string ("cxxflags", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_LDFLAGS, + g_param_spec_string ("ldflags", + "", + "", + NULL, + G_PARAM_READWRITE)); +} + +static void +builder_sdk_config_init (BuilderSdkConfig *self) +{ +} + + +const char * +builder_sdk_config_get_libdir (BuilderSdkConfig *self) +{ + return self->libdir; +} + +const char * +builder_sdk_config_get_cppflags (BuilderSdkConfig *self) +{ + return self->cppflags; +} + +const char * +builder_sdk_config_get_cflags (BuilderSdkConfig *self) +{ + return self->cflags; +} + +const char * +builder_sdk_config_get_cxxflags (BuilderSdkConfig *self) +{ + return self->cxxflags; +} + +const char * +builder_sdk_config_get_ldflags (BuilderSdkConfig *self) +{ + return self->ldflags; +} + +BuilderSdkConfig * +builder_sdk_config_from_file (GFile *file, + GError **error) +{ + g_autofree gchar *config_contents = NULL; + gsize config_size; + + if (!g_file_load_contents (file, NULL, &config_contents, &config_size, NULL, error)) + return NULL; + + return (BuilderSdkConfig*) json_gobject_from_data (BUILDER_TYPE_SDK_CONFIG, + config_contents, + config_size, + error); +} diff --git a/src/builder-sdk-config.h b/src/builder-sdk-config.h new file mode 100644 index 00000000..1b4d67ba --- /dev/null +++ b/src/builder-sdk-config.h @@ -0,0 +1,49 @@ +/* + * Copyright © 2018 Codethink Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Valentin David + */ + +#ifndef __BUILDER_SDK_CONFIG_H__ +#define __BUILDER_SDK_CONFIG_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct BuilderSdkConfig BuilderSdkConfig; + +#define BUILDER_TYPE_SDK_CONFIG (builder_sdk_config_get_type ()) +#define BUILDER_SDK_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUILDER_TYPE_SDK_CONFIG, BuilderSdkConfig)) + +GType builder_sdk_config_get_type (void); + +const char * builder_sdk_config_get_libdir (BuilderSdkConfig *self); +const char * builder_sdk_config_get_cppflags (BuilderSdkConfig *self); +const char * builder_sdk_config_get_cflags (BuilderSdkConfig *self); +const char * builder_sdk_config_get_cxxflags (BuilderSdkConfig *self); +const char * builder_sdk_config_get_ldflags (BuilderSdkConfig *self); + +BuilderSdkConfig *builder_sdk_config_from_file (GFile *file, + GError **error); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (BuilderSdkConfig, g_object_unref) + +G_END_DECLS + +#endif /* __BUILDER_SDK_CONFIG_H__ */