From: Michael Tremer Date: Fri, 3 Jan 2025 08:16:19 +0000 (+0000) Subject: build: Find pkg-config requires in C X-Git-Tag: 0.9.30~573 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a21c4797a590c8045acce606f82a0a7fe060b40d;p=pakfire.git build: Find pkg-config requires in C Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/build.c b/src/pakfire/build.c index 42026887e..3b5eff37e 100644 --- a/src/pakfire/build.c +++ b/src/pakfire/build.c @@ -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) diff --git a/src/scripts/find-requires b/src/scripts/find-requires index 6c6858072..268730e1f 100644 --- a/src/scripts/find-requires +++ b/src/scripts/find-requires @@ -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