From: Michael Tremer Date: Thu, 22 Jul 2021 13:47:13 +0000 (+0000) Subject: build: Initialize build environment only when needed X-Git-Tag: 0.9.28~1019 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=149190224516a63fc7c8a0ef2a59680f9b496708;p=pakfire.git build: Initialize build environment only when needed Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/build.c b/src/libpakfire/build.c index 28ef1069b..f2a618258 100644 --- a/src/libpakfire/build.c +++ b/src/libpakfire/build.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -36,11 +35,8 @@ #include #include #include -#include #include -#define CCACHE_DIR "/var/cache/ccache" - static const char* stages[] = { "prepare", "build", @@ -59,133 +55,6 @@ static const char* stages[] = { "\n" \ "exit 0\n" -static int pakfire_build_install_packages(struct pakfire* pakfire, int* snapshot_needs_update) { - char** packages = NULL; - int r = 1; - - struct pakfire_config* config = pakfire_get_config(pakfire); - - // Fetch build environment - const char* requires = pakfire_config_get(config, "build", "requires", NULL); - if (!requires) { - ERROR(pakfire, "No build requirements have been defined\n"); - goto ERROR; - } - - // Split requirements into packages - packages = pakfire_split_string(requires, ','); - if (!packages) - goto ERROR; - - int changed = 0; - - // Install everything - r = pakfire_install(pakfire, 0, (const char**)packages, NULL, 0, &changed); - if (r) { - ERROR(pakfire, "Could not install build dependencies\n"); - goto ERROR; - } - - // Mark snapshot as changed if new packages were installed - if (changed) - *snapshot_needs_update = 1; - - // Update everything - r = pakfire_sync(pakfire, 0, 0, &changed); - if (r) { - ERROR(pakfire, "Could not update packages: %m\n"); - goto ERROR; - } - - // Has anything changed? - if (changed) - *snapshot_needs_update = 1; - - // Success - r = 0; - -ERROR: - if (packages) { - for (char** package = packages; *package; package++) - free(*package); - free(packages); - } - if (config) - pakfire_config_unref(config); - - return r; -} - -int pakfire_build_setup(struct pakfire* pakfire) { - char path[PATH_MAX]; - int r; - - // Mount ccache - if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_DISABLE_CCACHE)) { - r = pakfire_make_cache_path(pakfire, path, "%s", "ccache"); - if (r < 0) - return r; - - // Ensure path exists - r = pakfire_mkdir(path, 0); - if (r && errno != EEXIST) { - ERROR(pakfire, "Could not create ccache directory %s: %m\n", path); - return r; - } - - r = pakfire_bind(pakfire, path, CCACHE_DIR, MS_NOSUID|MS_NOEXEC|MS_NODEV); - if (r) { - ERROR(pakfire, "Could not mount ccache: %m\n"); - return r; - } - } - - // Extract snapshot - if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_DISABLE_SNAPSHOT)) { - r = pakfire_make_cache_path(pakfire, path, "%s", "snapshot.tar.zst"); - if (r < 0) - return r; - - // Open the snapshot - FILE* f = fopen(path, "r"); - - // Try restoring the snapshot - if (f) { - r = pakfire_snapshot_restore(pakfire, f); - if (r) { - fclose(f); - return r; - } - } - - // Tells us whether we need to (re-)create the snapshot - int snapshot_needs_update = 0; - - // Install or update any build dependencies - r = pakfire_build_install_packages(pakfire, &snapshot_needs_update); - if (r) - return r; - - if (snapshot_needs_update) { - // Open snapshot file for writing - f = fopen(path, "w"); - if (!f) { - ERROR(pakfire, "Could not open snapshot file for writing: %m\n"); - return 1; - } - - // Create a new snapshot - r = pakfire_snapshot_create(pakfire, f); - fclose(f); - - if (r) - return r; - } - } - - return 0; -} - static int pakfire_build_run_script(struct pakfire* pakfire, const char* filename, const char* args[], pakfire_execute_logging_callback logging_callback, void* data) { char* script = NULL; @@ -885,6 +754,11 @@ PAKFIRE_EXPORT int pakfire_build(struct pakfire* pakfire, const char* path, } } + // Setup build environment + r = pakfire_build_setup(pakfire); + if (r) + return r; + const char* packages[] = { path, NULL }; diff --git a/src/libpakfire/include/pakfire/build.h b/src/libpakfire/include/pakfire/build.h index 6f9ead595..cc936f7d9 100644 --- a/src/libpakfire/include/pakfire/build.h +++ b/src/libpakfire/include/pakfire/build.h @@ -27,8 +27,6 @@ enum pakfire_build_flags { PAKFIRE_BUILD_INTERACTIVE = (1 << 0), }; -int pakfire_build_setup(struct pakfire* pakfire); - int pakfire_build(struct pakfire* pakfire, const char* path, const char* target, const char* id, int flags, pakfire_execute_logging_callback logging_callback, void* data); int pakfire_shell(struct pakfire* pakfire); diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index c59be87cc..2a62926a5 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -155,6 +155,9 @@ struct pakfire_repo* pakfire_get_installed_repo(struct pakfire* pakfire); struct archive* pakfire_make_archive_disk_reader(struct pakfire* pakfire, int internal); struct archive* pakfire_make_archive_disk_writer(struct pakfire* pakfire); +// Build Stuff +int pakfire_build_setup(struct pakfire* pakfire); + #endif #endif /* PAKFIRE_PAKFIRE_H */ diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 2a7cd6b54..e16b25a0b 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -55,10 +55,13 @@ #include #include #include +#include #include #include #include +#define CCACHE_DIR "/var/cache/ccache" + struct mountpoint { STAILQ_ENTRY(mountpoint) nodes; char path[PATH_MAX]; @@ -83,6 +86,7 @@ struct pakfire { int nrefs; struct pakfire_config* config; + int build_setup; int mount_tmpfs; STAILQ_HEAD(mountpoints, mountpoint) mountpoints; @@ -958,10 +962,6 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, if (pakfire_has_flag(p, PAKFIRE_FLAGS_BUILD)) { // Builds are never interactive p->flags |= PAKFIRE_FLAGS_NON_INTERACTIVE; - - r = pakfire_build_setup(p); - if (r) - goto ERROR; } *pakfire = p; @@ -1955,3 +1955,141 @@ PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int f return pakfire_perform_transaction_simple(pakfire, solver_flags, pakfire_request_sync, flags, changed); } + +// Build Stuff + +static int pakfire_build_install_packages(struct pakfire* pakfire, int* snapshot_needs_update) { + char** packages = NULL; + int r = 1; + + // Fetch build environment + const char* requires = pakfire_config_get(pakfire->config, "build", "requires", NULL); + if (!requires) { + ERROR(pakfire, "No build requirements have been defined\n"); + goto ERROR; + } + + // Split requirements into packages + packages = pakfire_split_string(requires, ','); + if (!packages) + goto ERROR; + + int changed = 0; + + // Install everything + r = pakfire_install(pakfire, 0, (const char**)packages, NULL, 0, &changed); + if (r) { + ERROR(pakfire, "Could not install build dependencies\n"); + goto ERROR; + } + + // Mark snapshot as changed if new packages were installed + if (changed) + *snapshot_needs_update = 1; + + // Update everything + r = pakfire_sync(pakfire, 0, 0, &changed); + if (r) { + ERROR(pakfire, "Could not update packages: %m\n"); + goto ERROR; + } + + // Has anything changed? + if (changed) + *snapshot_needs_update = 1; + + // Success + r = 0; + +ERROR: + if (packages) { + for (char** package = packages; *package; package++) + free(*package); + free(packages); + } + + return r; +} + +int pakfire_build_setup(struct pakfire* pakfire) { + // This function can only be called when in build mode + if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_BUILD)) { + errno = EINVAL; + return 1; + } + + // Do nothing if build environment has been set up + if (pakfire->build_setup) + return 0; + + char path[PATH_MAX]; + int r; + + // Mount ccache + if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_DISABLE_CCACHE)) { + r = pakfire_make_cache_path(pakfire, path, "%s", "ccache"); + if (r < 0) + return r; + + // Ensure path exists + r = pakfire_mkdir(path, 0); + if (r && errno != EEXIST) { + ERROR(pakfire, "Could not create ccache directory %s: %m\n", path); + return r; + } + + r = pakfire_bind(pakfire, path, CCACHE_DIR, MS_NOSUID|MS_NOEXEC|MS_NODEV); + if (r) { + ERROR(pakfire, "Could not mount ccache: %m\n"); + return r; + } + } + + // Extract snapshot + if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_DISABLE_SNAPSHOT)) { + r = pakfire_make_cache_path(pakfire, path, "%s", "snapshot.tar.zst"); + if (r < 0) + return r; + + // Open the snapshot + FILE* f = fopen(path, "r"); + + // Try restoring the snapshot + if (f) { + r = pakfire_snapshot_restore(pakfire, f); + if (r) { + fclose(f); + return r; + } + } + + // Tells us whether we need to (re-)create the snapshot + int snapshot_needs_update = 0; + + // Install or update any build dependencies + r = pakfire_build_install_packages(pakfire, &snapshot_needs_update); + if (r) + return r; + + if (snapshot_needs_update) { + // Open snapshot file for writing + f = fopen(path, "w"); + if (!f) { + ERROR(pakfire, "Could not open snapshot file for writing: %m\n"); + return 1; + } + + // Create a new snapshot + r = pakfire_snapshot_create(pakfire, f); + fclose(f); + + if (r) + return r; + } + } + + // Build setup done + pakfire->build_setup = 1; + + return 0; +}