From f95cd2d029db0e58d6dd82de82d88ef5614d972f Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 12 Jan 2016 12:09:09 +0100 Subject: [PATCH] builder: Add option to enable ccache use in build --- builder/builder-context.c | 64 ++++++++++++++++++++++++++++++++++ builder/builder-context.h | 6 +++- builder/builder-module.c | 15 +++++--- builder/builder-options.c | 2 +- builder/xdg-app-builder-main.c | 19 ++++++---- doc/xdg-app-builder.xml | 8 +++++ 6 files changed, 101 insertions(+), 13 deletions(-) diff --git a/builder/builder-context.c b/builder/builder-context.c index cbfe9883e..9da1f0e0d 100644 --- a/builder/builder-context.c +++ b/builder/builder-context.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "builder-context.h" #include "xdg-app-utils.h" @@ -41,10 +42,12 @@ struct BuilderContext { GFile *download_dir; GFile *state_dir; GFile *cache_dir; + GFile *ccache_dir; BuilderOptions *options; gboolean keep_build_dirs; char **cleanup; + gboolean use_ccache; }; typedef struct { @@ -130,6 +133,7 @@ builder_context_constructed (GObject *object) self->state_dir = g_file_get_child (self->base_dir, ".xdg-app-builder"); self->download_dir = g_file_get_child (self->state_dir, "downloads"); self->cache_dir = g_file_get_child (self->state_dir, "cache"); + self->ccache_dir = g_file_get_child (self->state_dir, "ccache"); } static void @@ -193,6 +197,12 @@ builder_context_get_cache_dir (BuilderContext *self) return self->cache_dir; } +GFile * +builder_context_get_ccache_dir (BuilderContext *self) +{ + return self->ccache_dir; +} + SoupSession * builder_context_get_soup_session (BuilderContext *self) { @@ -283,6 +293,60 @@ builder_context_get_keep_build_dirs (BuilderContext *self) return self->keep_build_dirs; } +gboolean +builder_context_enable_ccache (BuilderContext *self, + GError **error) +{ + g_autofree char *ccache_path = g_file_get_path (self->ccache_dir); + g_autofree char *ccache_bin_path = g_build_filename (ccache_path, "bin", NULL); + int i; + static const char *compilers[] = { + "cc", + "c++", + "gcc", + "g++" + }; + + if (g_mkdir_with_parents (ccache_bin_path, 0755) != 0) + { + glnx_set_error_from_errno (error); + return FALSE; + } + + for (i = 0; i < G_N_ELEMENTS (compilers); i++) + { + const char *symlink_path = g_build_filename (ccache_bin_path, compilers[i], NULL); + if (symlink ("/usr/bin/ccache", symlink_path) && errno != EEXIST) + { + glnx_set_error_from_errno (error); + return FALSE; + } + } + + self->use_ccache = TRUE; + + return TRUE; +} + +char ** +builder_context_extend_env (BuilderContext *self, + char **envp) +{ + if (self->use_ccache) + { + const char *old_path = g_environ_getenv (envp, "PATH"); + g_autofree char *new_path = NULL; + if (old_path == NULL) + old_path = "/app/bin:/usr/bin"; /* This is the xdg-app default PATH */ + + new_path = g_strdup_printf ("/run/ccache/bin:%s", old_path); + envp = g_environ_setenv (envp, "PATH", new_path, TRUE); + envp = g_environ_setenv (envp, "CCACHE_DIR", "/run/ccache", TRUE); + } + + return envp; +} + BuilderContext * builder_context_new (GFile *base_dir, GFile *app_dir) diff --git a/builder/builder-context.h b/builder/builder-context.h index ba954bc56..916b4ecf2 100644 --- a/builder/builder-context.h +++ b/builder/builder-context.h @@ -39,6 +39,7 @@ GFile * builder_context_get_app_dir (BuilderContext *self); GFile * builder_context_get_base_dir (BuilderContext *self); GFile * builder_context_get_state_dir (BuilderContext *self); GFile * builder_context_get_cache_dir (BuilderContext *self); +GFile * builder_context_get_ccache_dir (BuilderContext *self); GFile * builder_context_get_download_dir (BuilderContext *self); SoupSession * builder_context_get_soup_session (BuilderContext *self); const char * builder_context_get_arch (BuilderContext *self); @@ -55,9 +56,12 @@ BuilderOptions *builder_context_get_options (BuilderContext *self); void builder_context_set_options (BuilderContext *self, BuilderOptions *option); - BuilderContext *builder_context_new (GFile *base_dir, GFile *app_dir); +gboolean builder_context_enable_ccache (BuilderContext *self, + GError **error); +char ** builder_context_extend_env (BuilderContext *self, + char **envp); G_DEFINE_AUTOPTR_CLEANUP_FUNC(BuilderContext, g_object_unref) diff --git a/builder/builder-module.c b/builder/builder-module.c index cd6476b87..68f1b5082 100644 --- a/builder/builder-module.c +++ b/builder/builder-module.c @@ -517,6 +517,7 @@ static const char strv_arg[] = "strv"; static gboolean build (GFile *app_dir, const char *module_name, + BuilderContext *context, GFile *source_dir, const char *cwd_subdir, char **xdg_app_opts, @@ -535,6 +536,7 @@ build (GFile *app_dir, g_autofree char *source_dir_path_canonical = NULL; g_autofree char *cwd_dir_path = NULL; g_autofree char *cwd_dir_path_canonical = NULL; + g_autofree char *ccache_dir_path = NULL; va_list ap; int i; @@ -553,6 +555,9 @@ build (GFile *app_dir, else g_ptr_array_add (args, g_strdup_printf ("--build-dir=/run/build/%s", module_name)); + ccache_dir_path = g_file_get_path (builder_context_get_ccache_dir (context)); + g_ptr_array_add (args, g_strdup_printf ("--bind-mount=/run/ccache=%s", ccache_dir_path)); + if (xdg_app_opts) { for (i = 0; xdg_app_opts[i] != NULL; i++) @@ -809,7 +814,7 @@ builder_module_build (BuilderModule *self, } env_with_noconfigure = g_environ_setenv (g_strdupv (env), "NOCONFIGURE", "1", TRUE); - if (!build (app_dir, self->name, source_dir, source_subdir_relative, build_args, env_with_noconfigure, error, + if (!build (app_dir, self->name, context, source_dir, source_subdir_relative, build_args, env_with_noconfigure, error, autogen_cmd, NULL)) return FALSE; @@ -873,7 +878,7 @@ builder_module_build (BuilderModule *self, configure_prefix_arg = g_strdup_printf ("--prefix=%s", builder_options_get_prefix (self->build_options, context)); - if (!build (app_dir, self->name, source_dir, build_dir_relative, build_args, env, error, + if (!build (app_dir, self->name, context, source_dir, build_dir_relative, build_args, env, error, configure_cmd, configure_prefix_arg, strv_arg, self->config_opts, configure_final_arg, NULL)) return FALSE; } @@ -912,11 +917,11 @@ builder_module_build (BuilderModule *self, /* Build and install */ - if (!build (app_dir, self->name, source_dir, build_dir_relative, build_args, env, error, + if (!build (app_dir, self->name, context, source_dir, build_dir_relative, build_args, env, error, "make", make_j?make_j:skip_arg, make_l?make_l:skip_arg, strv_arg, self->make_args, NULL)) return FALSE; - if (!build (app_dir, self->name, source_dir, build_dir_relative, build_args, env, error, + if (!build (app_dir, self->name, context, source_dir, build_dir_relative, build_args, env, error, "make", "install", strv_arg, self->make_install_args, NULL)) return FALSE; @@ -926,7 +931,7 @@ builder_module_build (BuilderModule *self, { for (i = 0; self->post_install[i] != NULL; i++) { - if (!build (app_dir, self->name, source_dir, build_dir_relative, build_args, env, error, + if (!build (app_dir, self->name, context, source_dir, build_dir_relative, build_args, env, error, "/bin/sh", "-c", self->post_install[i], NULL)) return FALSE; } diff --git a/builder/builder-options.c b/builder/builder-options.c index f1737d8a4..e9116109e 100644 --- a/builder/builder-options.c +++ b/builder/builder-options.c @@ -574,7 +574,7 @@ builder_options_get_env (BuilderOptions *self, BuilderContext *context) } } - return envp; + return builder_context_extend_env (context, envp); } char ** diff --git a/builder/xdg-app-builder-main.c b/builder/xdg-app-builder-main.c index a6b97c36d..f631f046e 100644 --- a/builder/xdg-app-builder-main.c +++ b/builder/xdg-app-builder-main.c @@ -38,6 +38,7 @@ static gboolean opt_download_only; static gboolean opt_build_only; static gboolean opt_disable_download; static gboolean opt_disable_updates; +static gboolean opt_ccache; static gboolean opt_require_changes; static gboolean opt_keep_build_dirs; static char *opt_repo; @@ -45,6 +46,7 @@ static char *opt_repo; static GOptionEntry entries[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL }, { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Print version information and exit", NULL }, + { "ccache", 0, 0, G_OPTION_ARG_NONE, &opt_ccache, "Use ccache", NULL }, { "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Disable cache", NULL }, { "disable-download", 0, 0, G_OPTION_ARG_NONE, &opt_disable_download, "Don't download any new sources", NULL }, { "disable-updates", 0, 0, G_OPTION_ARG_NONE, &opt_disable_updates, "Only download missing sources, never update to latest vcs version", NULL }, @@ -197,13 +199,18 @@ main (int argc, builder_context_set_keep_build_dirs (build_context, opt_keep_build_dirs); - if (!opt_disable_download) + if (opt_ccache && + !builder_context_enable_ccache (build_context, &error)) { - if (!builder_manifest_download (manifest, !opt_disable_updates, build_context, &error)) - { - g_print ("error: %s\n", error->message); - return 1; - } + g_printerr ("Can't initialize ccache use: %s\n", error->message); + return 1; + } + + if (!opt_disable_download && + !builder_manifest_download (manifest, !opt_disable_updates, build_context, &error)) + { + g_print ("Failed to download sources: %s\n", error->message); + return 1; } if (opt_download_only) diff --git a/doc/xdg-app-builder.xml b/doc/xdg-app-builder.xml index 2cefea3c9..d653c5546 100644 --- a/doc/xdg-app-builder.xml +++ b/doc/xdg-app-builder.xml @@ -526,6 +526,14 @@ + + + + + Enable use of ccache in the build (needs ccache in the sdk) + + +