]> git.ipfire.org Git - pakfire.git/commitdiff
build: Find pkg-config requires in C
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 3 Jan 2025 08:16:19 +0000 (08:16 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 3 Jan 2025 08:16:19 +0000 (08:16 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/build.c
src/scripts/find-requires

index 42026887e4a11a363b51e9ef7f03bd25f780e299..3b5eff37e54e4b99ebc49242d9e13cf03af49a85 100644 (file)
@@ -496,6 +496,150 @@ ERROR:
        return r;
 }
 
+static int __pakfire_build_find_pkgconfig_requires(struct pakfire_ctx* ctx,
+               void* data, const char* line, const size_t length) {
+       struct pakfire_find_deps_ctx* deps = data;
+       char buffer[PATH_MAX];
+       int r;
+
+       // Copy the line to a buffer
+       r = pakfire_string_set(buffer, line);
+       if (r < 0)
+               return r;
+
+       // Remove any whitespace
+       pakfire_string_strip(buffer);
+
+       const char* name = NULL;
+       const char* op = NULL;
+       const char* version = NULL;
+       const char* token = NULL;
+       char* p = NULL;
+       int i = 0;
+
+       // Try splitting the string
+       token = strtok_r(buffer, " ", &p);
+
+       while (token) {
+               switch (i++) {
+                       case 0:
+                               name = token;
+                               break;
+
+                       case 1:
+                               op = token;
+                               break;
+
+                       case 2:
+                               version = token;
+                               break;
+
+                       default:
+                               break;
+               };
+
+               token = strtok_r(NULL, " ", &p);
+       }
+
+       // Add everything if we have all the information
+       if (name && op && version) {
+               r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_REQUIRES,
+                               "pkgconfig(%s) %s %s", name, op, version);
+               if (r < 0)
+                       return r;
+
+       // Otherwise we add the entire buffer and hope for the best
+       } else {
+               r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_REQUIRES,
+                               "pkgconfig(%s)", buffer);
+               if (r < 0)
+                       return r;
+       }
+
+       return length;
+}
+
+static int pakfire_build_find_pkgconfig_requires(
+               struct pakfire_ctx* ctx, struct pakfire_file* file, struct pakfire_find_deps_ctx* deps) {
+       struct pakfire_env* env = NULL;
+       const char* buildroot = NULL;
+       int r;
+
+       // Fetch the absolute path
+       const char* path = pakfire_file_get_abspath(file);
+       if (!path)
+               return -EINVAL;
+
+       // Fetch the path to the buildroot
+       buildroot = pakfire_relpath(deps->build->pakfire, deps->build->buildroot);
+       if (!buildroot)
+               return -EINVAL;
+
+       // This package now requires pkgconfig
+       r = pakfire_package_add_dep(deps->pkg, PAKFIRE_PKG_REQUIRES, "pkgconfig");
+       if (r < 0)
+               goto ERROR;
+
+       // Create a new environment
+       r = pakfire_env_create(&env, ctx);
+       if (r < 0)
+               goto ERROR;
+
+       const char* argv[] = {
+               "pkg-config",
+               "--print-requires",
+               "--print-requires-private",
+               pakfire_relpath(deps->build->pakfire, path),
+               NULL,
+       };
+
+       // Tell pkg-config to look inside BUILDROOT
+       r = pakfire_env_set(env,
+                       "PKG_CONFIG_PATH", "%s/usr/lib64/pkgconfig:%s/usr/lib/pkgconfig:%s/usr/share/pkgconfig",
+                       buildroot, buildroot, buildroot);
+       if (r < 0)
+               goto ERROR;
+
+       // Run pkg-config and process the output
+       r = pakfire_jail_communicate(deps->build->jail, argv, env, 0, NULL, NULL,
+                       __pakfire_build_find_pkgconfig_requires, deps);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (env)
+               pakfire_env_unref(env);
+
+       return r;
+}
+
+static int __pakfire_build_find_requires(
+               struct pakfire_ctx* ctx, struct pakfire_file* file, void* data) {
+       struct pakfire_find_deps_ctx* deps = data;
+       const char* path = NULL;
+
+       // Fetch the file path
+       path = pakfire_file_get_path(file);
+       if (!path)
+               return -EINVAL;
+
+       // Handle pkg-config files
+       if (pakfire_path_match("**.pc", path))
+               return pakfire_build_find_pkgconfig_requires(ctx, file, deps);
+
+       return 0;
+}
+
+static int pakfire_build_find_requires(struct pakfire_build* build,
+               struct pakfire_package* pkg, struct pakfire_filelist* filelist, const pcre2_code* filter) {
+       struct pakfire_find_deps_ctx deps = {
+               .build = build,
+               .pkg   = pkg,
+       };
+
+       return pakfire_filelist_walk(filelist, __pakfire_build_find_requires, &deps, 0, NULL);
+}
+
 /*
        This function is a special way to run a script.
 
@@ -576,6 +720,11 @@ static int pakfire_build_find_dependencies(struct pakfire_build* build,
                goto ERROR;
 
        // Find all requires
+       r = pakfire_build_find_requires(build, pkg, filelist, filter_requires);
+       if (r < 0)
+               goto ERROR;
+
+       // XXX LEGACY CODE
        r = pakfire_build_find_deps(build, pkg,
                PAKFIRE_PKG_REQUIRES, "find-requires", filelist, 0, filter_requires);
        if (r)
index 6c685807285e1ea7657a83ce818ca42abef149d7..268730e1f7000ff687da1fda2b3a4403a16ce425 100644 (file)
@@ -23,20 +23,6 @@ error() {
        echo "$@" >&2
 }
 
-pkgconfig_requires() {
-       local file="${1}"
-
-       # Require the pkgconfig package
-       echo "pkgconfig"
-
-       local n r v
-       while read -r n r v; do
-               echo "pkgconfig(${n}) ${r} ${v}"
-       done < <(pkg-config --print-requires --print-requires-private "${file}" 2>/dev/null)
-
-       return 0
-}
-
 find_elf_interpreter() {
        local file="${1}"
        local filelist="${2}"
@@ -133,9 +119,6 @@ main() {
                return 1
        fi
 
-       # Tell pkg-config to search in the newly created files, too
-       export PKG_CONFIG_PATH="${buildroot}/usr/lib64/pkgconfig:${buildroot}/usr/lib/pkgconfig:${buildroot}/usr/share/pkgconfig"
-
        local file
        while read -r file; do
                # Filter out what we don't need