]> git.ipfire.org Git - pakfire.git/commitdiff
arch: Teach Pakfire to run a different arch effectively
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 29 Aug 2023 19:34:59 +0000 (19:34 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 29 Aug 2023 19:34:59 +0000 (19:34 +0000)
This is useful to let Pakfire think it is running in "noarch" mode, when
we of course actually have to install some binary packages.

This might also become useful when bootstrapping the distribution for a
new architecture.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/arch.c
src/libpakfire/db.c
src/libpakfire/dist.c
src/libpakfire/include/pakfire/arch.h
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/jail.c
src/libpakfire/mount.c
src/libpakfire/pakfire.c
src/libpakfire/repo.c

index b6e96337872cc1b8b1f3eeb148ad92ee179700df..dda1538f0942e359d2c9f2a4a109a4d85a0c1f62 100644 (file)
@@ -199,14 +199,29 @@ int pakfire_arch_is_compatible(const char* name, const char* compatible_arch) {
        return 0;
 }
 
-int pakfire_arch_supported_by_host(const char* name) {
-       if (!name)
-               return -EINVAL;
+/*
+       This function figures out which architecture the build environment has -
+       which might not be the same as the requested architecture.
+*/
+const char* pakfire_arch_supported_by_host(const char* name) {
+       if (!name) {
+               errno = EINVAL;
+               return NULL;
+       }
 
        const char* native_arch = pakfire_arch_native();
 
+       // All hosts support noarch natively
+       if (strcmp(name, "noarch") == 0)
+               return native_arch;
+
        // Check if those two architectures are compatible
-       return pakfire_arch_is_compatible(native_arch, name);
+       if (pakfire_arch_is_compatible(native_arch, name))
+               return name;
+
+       // Not supported
+       errno = ENOTSUP;
+       return NULL;
 }
 
 static char* find_interpreter(DIR* dir, const char* path, const char* magic) {
index 9d17ce9a05e71685a694c1cdb2e58b1a6ba339fd..8e5d441a8b3d329029110e2ffb1d176d8d714291 100644 (file)
@@ -461,7 +461,7 @@ static int pakfire_db_create_schema(struct pakfire_db* db) {
        if (r)
                return 1;
 
-       const char* arch = pakfire_get_arch(db->pakfire);
+       const char* arch = pakfire_get_effective_arch(db->pakfire);
 
        // Set architecture
        r = pakfire_db_set_string(db, "arch", arch);
@@ -545,7 +545,7 @@ static int pakfire_db_check_arch(struct pakfire_db* db) {
        }
 
        // Fetch the running architecture
-       const char* arch = pakfire_get_arch(db->pakfire);
+       const char* arch = pakfire_get_effective_arch(db->pakfire);
        if (!arch)
                goto ERROR;
 
index 8905cd873fa0839411cfa974465a920ff27dff08..b67a5e1937237039f2391ebd6dcacf09554c94b2 100644 (file)
@@ -105,22 +105,22 @@ static int pakfire_makefile_set_defaults(struct pakfire* pakfire,
                pakfire_parser_set(parser, NULL, "DISTRO_VENDOR", vendor, 0);
 
        // Set DISTRO_ARCH
-       const char* arch = pakfire_get_arch(pakfire);
-       if (arch) {
-               pakfire_parser_set(parser, NULL, "DISTRO_ARCH", arch, 0);
+       const char* effective_arch = pakfire_get_effective_arch(pakfire);
+       if (effective_arch) {
+               pakfire_parser_set(parser, NULL, "DISTRO_ARCH", effective_arch, 0);
 
-               const char* platform = pakfire_arch_platform(arch);
+               const char* platform = pakfire_arch_platform(effective_arch);
                if (platform)
                        pakfire_parser_set(parser, NULL, "DISTRO_PLATFORM", platform, 0);
 
                if (vendor) {
                        // Set DISTRO_MACHINE
-                       r = pakfire_arch_machine(buffer, arch, vendor);
+                       r = pakfire_arch_machine(buffer, effective_arch, vendor);
                        if (!r)
                                pakfire_parser_set(parser, NULL, "DISTRO_MACHINE", buffer, 0);
 
                        // Set DISTRO_BUILDTARGET
-                       r = pakfire_arch_buildtarget(buffer, arch, vendor);
+                       r = pakfire_arch_buildtarget(buffer, effective_arch, vendor);
                        if (!r)
                                pakfire_parser_set(parser, NULL, "DISTRO_BUILDTARGET", buffer, 0);
                }
index 84ff0387a42ff0d5b27947dca8601779556cf602..f09f777c3febc3b739e8607d025661c09ecff686 100644 (file)
@@ -40,7 +40,7 @@ int __pakfire_arch_buildtarget(char* buffer, size_t length, const char* arch, co
 const char* pakfire_arch_platform(const char* name);
 int pakfire_arch_is_compatible(const char* name, const char* compatible_arch);
 
-int pakfire_arch_supported_by_host(const char* name);
+const char* pakfire_arch_supported_by_host(const char* name);
 char* pakfire_arch_find_interpreter(const char* name);
 
 #endif
index 094a2a2fc1a555839fda818bd2d108cb4105c2b0..7423d664428ec5d9f09acf4d7e4f98d7a45c8a72 100644 (file)
@@ -125,6 +125,8 @@ int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags, int* chan
 #include <pakfire/config.h>
 #include <pakfire/pwd.h>
 
+const char* pakfire_get_effective_arch(struct pakfire* pakfire);
+
 int pakfire_on_root(struct pakfire* pakfire);
 
 uid_t pakfire_uid(struct pakfire* pakfire);
index 1adbda0333d123145439db4f8736893d45fcf198..e22feeca5ce62ec4695ee896165988dcafcb3993 100644 (file)
@@ -254,7 +254,7 @@ static int pakfire_jail_setup_interactive_env(struct pakfire_jail* jail) {
 PAKFIRE_EXPORT int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) {
        int r;
 
-       const char* arch = pakfire_get_arch(pakfire);
+       const char* arch = pakfire_get_effective_arch(pakfire);
 
        // Allocate a new jail
        struct pakfire_jail* j = calloc(1, sizeof(*j));
@@ -1642,7 +1642,7 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
        }
 
        const char* root = pakfire_get_path(jail->pakfire);
-       const char* arch = pakfire_get_arch(jail->pakfire);
+       const char* arch = pakfire_get_effective_arch(jail->pakfire);
 
        // Change mount propagation to slave to receive anything from the parent namespace
        r = pakfire_mount_change_propagation(jail->pakfire, MS_SLAVE, "/");
index 2647810442264df2fe07a03dd1fc38c69d8297dc..fc7781f6fbe784673dd3ad9263cbc45597bcf48f 100644 (file)
@@ -361,7 +361,7 @@ static int pakfire_mount_interpreter(struct pakfire* pakfire) {
        char target[PATH_MAX];
 
        // Fetch the target architecture
-       const char* arch = pakfire_get_arch(pakfire);
+       const char* arch = pakfire_get_effective_arch(pakfire);
 
        // Can we emulate this architecture?
        char* interpreter = pakfire_arch_find_interpreter(arch);
index e03f2c1d3113a7997ddc4e3537f4aa6e731436b9..e3f392dd78bb5c4d7e158fac8e74f28e883bf019 100644 (file)
@@ -70,7 +70,11 @@ struct pakfire {
        char path[PATH_MAX];
        char lock_path[PATH_MAX];
        char cache_path[PATH_MAX];
-       char arch[ARCH_MAX];
+
+       struct pakfire_arches {
+               char nominal[ARCH_MAX];
+               const char* effective;
+       } arches;
 
        int flags;
 
@@ -297,6 +301,8 @@ static int pakfire_populate_pool(struct pakfire* pakfire) {
        struct pakfire_repo* system = NULL;
        int r;
 
+       const char* arch = pakfire_get_effective_arch(pakfire);
+
        // Initialize the pool
        Pool* pool = pakfire->pool = pool_create();
        pool_setdisttype(pool, DISTTYPE_RPM);
@@ -307,7 +313,7 @@ static int pakfire_populate_pool(struct pakfire* pakfire) {
 #endif
 
        // Set architecture of the pool
-       pool_setarch(pool, pakfire->arch);
+       pool_setarch(pool, arch);
 
        // Set path
        pool_set_rootdir(pool, pakfire->path);
@@ -740,6 +746,8 @@ static int pakfire_set_cache_path(struct pakfire* pakfire) {
        char basepath[PATH_MAX];
        int r;
 
+       const char* arch = pakfire_get_effective_arch(pakfire);
+
        // Fetch the path from the configuration file
        const char* path = pakfire_config_get(pakfire->config, "general", "cache_path", NULL);
        if (!path) {
@@ -754,7 +762,7 @@ static int pakfire_set_cache_path(struct pakfire* pakfire) {
 
        // Format the final path
        return pakfire_string_format(pakfire->cache_path, "%s/%s/%s/%s",
-               path, pakfire->distro.id, pakfire->distro.version_id, pakfire->arch);
+               path, pakfire->distro.id, pakfire->distro.version_id, arch);
 }
 
 static int pakfire_setup_user(struct pakfire* pakfire) {
@@ -852,16 +860,19 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
                        pakfire_log_set_priority(p, log_priority(env));
        }
 
-       // Check if the architecture is supported by this host
-       if (!pakfire_arch_supported_by_host(arch)) {
+       // Store the nominal architecture
+       r = pakfire_string_set(p->arches.nominal, arch);
+       if (r)
+               goto ERROR;
+
+       // Determine the effective architecture
+       p->arches.effective = pakfire_arch_supported_by_host(arch);
+       if (!p->arches.effective) {
                ERROR(p, "Unsupported architecture: %s\n", arch);
-               r = -EINVAL;
+               r = errno;
                goto ERROR;
        }
 
-       // Set architecture
-       pakfire_string_set(p->arch, arch);
-
        // Path must be absolute
        if (path && !pakfire_string_startswith(path, "/")) {
                ERROR(p, "Invalid path: %s\n", path);
@@ -907,7 +918,7 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path,
        DEBUG(p, "Pakfire initialized at %p\n", p);
        DEBUG(p, "  user   = %s (%d)\n", p->user.name, p->user.uid);
        DEBUG(p, "  group  = %s (%d)\n", p->group.name, p->group.gid);
-       DEBUG(p, "  arch   = %s\n", pakfire_get_arch(p));
+       DEBUG(p, "  arch   = %s (%s)\n", pakfire_get_arch(p), pakfire_get_effective_arch(p));
        DEBUG(p, "  path   = %s\n", pakfire_get_path(p));
        if (p->user.subuids.id)
                DEBUG(p, "  subuid = %d (%zu)\n", p->user.subuids.id, p->user.subuids.length);
@@ -1314,7 +1325,11 @@ PAKFIRE_EXPORT int pakfire_copy_out(struct pakfire* pakfire, const char* src, co
 }
 
 PAKFIRE_EXPORT const char* pakfire_get_arch(struct pakfire* pakfire) {
-       return pakfire->arch;
+       return pakfire->arches.nominal;
+}
+
+const char* pakfire_get_effective_arch(struct pakfire* pakfire) {
+       return pakfire->arches.effective;
 }
 
 PAKFIRE_EXPORT int pakfire_version_compare(struct pakfire* pakfire, const char* evr1, const char* evr2) {
index 10ccde02a8a5ccb90ab605788baa7e2fce676fe3..77ca4aa67950f3df9ee0d094d8a943e65bdbc5af 100644 (file)
@@ -765,7 +765,7 @@ static char* pakfire_repo_url_replace(struct pakfire_repo* repo, const char* url
                const char* replacement;
        } replacements[] = {
                { "%{name}", pakfire_repo_get_name(repo) },
-               { "%{arch}", pakfire_get_arch(repo->pakfire) },
+               { "%{arch}", pakfire_get_effective_arch(repo->pakfire) },
                { "%{distro}", pakfire_get_distro_id(repo->pakfire) },
                { "%{version}", pakfire_get_distro_version_id(repo->pakfire) },
                { NULL, NULL },