]> git.ipfire.org Git - pakfire.git/commitdiff
build: Initialize build environment only when needed
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Jul 2021 13:47:13 +0000 (13:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Jul 2021 13:47:13 +0000 (13:47 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/build.c
src/libpakfire/include/pakfire/build.h
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/pakfire.c

index 28ef1069b47c6876256ea2d6e692a70efd3e1318..f2a61825852c8720a3cf255f7c5e187f60596592 100644 (file)
@@ -21,7 +21,6 @@
 #include <errno.h>
 #include <glob.h>
 #include <stdlib.h>
-#include <sys/mount.h>
 #include <unistd.h>
 #include <uuid/uuid.h>
 
 #include <pakfire/private.h>
 #include <pakfire/repo.h>
 #include <pakfire/scriptlet.h>
-#include <pakfire/snapshot.h>
 #include <pakfire/util.h>
 
-#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
        };
index 6f9ead595809505deb776000df8bf428e461946a..cc936f7d98cad231e988e6370cc50d3cbf74f5ec 100644 (file)
@@ -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);
index c59be87cc0dc71fca851e5370a76a8220ef8d76f..2a62926a5d94e0828329ec52cf25a7c5b77c72ea 100644 (file)
@@ -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 */
index 2a7cd6b542f7ccf19e223340737664229bdd5158..e16b25a0bd841dc98d7ba6537bc80b5a81fda7f5 100644 (file)
 #include <pakfire/pwd.h>
 #include <pakfire/repo.h>
 #include <pakfire/request.h>
+#include <pakfire/snapshot.h>
 #include <pakfire/transaction.h>
 #include <pakfire/ui.h>
 #include <pakfire/util.h>
 
+#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;
+}