forked from ariadne/pkgconf
Compare commits
46 Commits
pkgconf-1.
...
master
Author | SHA1 | Date |
---|---|---|
Ariadne Conill | 0226cdda6d | |
Dylan Baker | fa803c7ecd | |
Ariadne Conill | bddf1641f8 | |
Ariadne Conill | 8754bdfe09 | |
Ariadne Conill | 6a66b312b4 | |
Ariadne Conill | 4c38d3f60c | |
Ariadne Conill | b7593aea27 | |
Ariadne Conill | dbd78db67f | |
Ariadne Conill | 80bc5ac3b9 | |
Ariadne Conill | 5044491f43 | |
Ariadne Conill | c6d14e6fa1 | |
Ariadne Conill | ced9bee613 | |
Ariadne Conill | 2c89541101 | |
Ariadne Conill | 5500a15133 | |
Ariadne Conill | 74faf8d0e2 | |
Ariadne Conill | c918b6e225 | |
Ariadne Conill | 12f3a30980 | |
Ariadne Conill | 01c1d9f4cc | |
Ariadne Conill | 9e8052b699 | |
Ariadne Conill | 696124b608 | |
Ariadne Conill | 79327b8967 | |
Ariadne Conill | f3021a82c5 | |
Ariadne Conill | 194ad3e656 | |
Ariadne Conill | aa99ddf789 | |
Ariadne Conill | 68b5cab72d | |
Ariadne Conill | 78f00da130 | |
psykose | 746005582f | |
Ariadne Conill | 28b5d57b98 | |
Ariadne Conill | af9b26c15c | |
Ariadne Conill | c0d2d65347 | |
Ariadne Conill | 69a3d458ef | |
Ariadne Conill | 7e9aa7e1fc | |
Ariadne Conill | 4e449bd45f | |
Ariadne Conill | 69f630aadc | |
Ariadne Conill | 760d1eea10 | |
Ariadne Conill | 8764578719 | |
Ariadne Conill | 5b10a85a82 | |
Ariadne Conill | 884a88583b | |
Ariadne Conill | 4e8f376c5d | |
Ariadne Conill | 79d25f979d | |
Ariadne Conill | 03ba00d30b | |
Ariadne Conill | 1a66d963cf | |
Ariadne Conill | 8271ea1952 | |
Ariadne Conill | b29f9d8713 | |
Ariadne Conill | 94b3f118cc | |
Dylan Baker | 7976daab9a |
13
Makefile.am
13
Makefile.am
|
@ -11,7 +11,7 @@ nodist_pkgconfig_DATA = libpkgconf.pc
|
|||
|
||||
AM_CFLAGS = -DPERSONALITY_PATH=\"$(personality_dir)\" -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\"
|
||||
|
||||
bin_PROGRAMS = pkgconf
|
||||
bin_PROGRAMS = pkgconf bomtool
|
||||
lib_LTLIBRARIES = libpkgconf.la
|
||||
|
||||
EXTRA_DIST = pkg.m4 \
|
||||
|
@ -89,6 +89,9 @@ EXTRA_DIST = pkg.m4 \
|
|||
tests/lib1/malformed-1.pc \
|
||||
tests/lib1/malformed-quoting.pc \
|
||||
tests/lib1/malformed-version.pc \
|
||||
tests/lib1/metapackage.pc \
|
||||
tests/lib1/metapackage-1.pc \
|
||||
tests/lib1/metapackage-2.pc \
|
||||
tests/lib1/explicit-sysroot.pc \
|
||||
tests/lib1/escaped-backslash.pc \
|
||||
tests/lib1/cflags-internal.pc \
|
||||
|
@ -164,11 +167,17 @@ pkgconf_SOURCES = \
|
|||
cli/main.c \
|
||||
cli/getopt_long.c \
|
||||
cli/renderer-msvc.c
|
||||
pkgconf_CPPFLAGS = -Ilibpkgconf -Icli
|
||||
pkgconf_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli
|
||||
noinst_HEADERS = \
|
||||
cli/getopt_long.h \
|
||||
cli/renderer-msvc.h
|
||||
|
||||
bomtool_LDADD = libpkgconf.la
|
||||
bomtool_SOURCES = \
|
||||
cli/bomtool/main.c \
|
||||
cli/getopt_long.c
|
||||
bomtool_CPPFLAGS = -I$(top_srcdir)/libpkgconf -I$(top_srcdir)/cli -I$(top_srcdir)/cli/bomtool
|
||||
|
||||
dist_doc_DATA = README.md AUTHORS
|
||||
|
||||
m4datadir = $(datadir)/aclocal
|
||||
|
|
29
NEWS
29
NEWS
|
@ -1,6 +1,35 @@
|
|||
Changes from previous version of pkgconf
|
||||
========================================
|
||||
|
||||
Changes from 1.9.2 to 1.9.3:
|
||||
----------------------------
|
||||
|
||||
* Fix a bunch of minor code issues pointed out using Clang static analyzer.
|
||||
|
||||
* New API: pkgconf_solution_free(), which frees a compiled solution graph.
|
||||
|
||||
* Fix behavior when overriding global variables with `--define-variable`.
|
||||
|
||||
Changes from 1.9.1 to 1.9.2:
|
||||
----------------------------
|
||||
|
||||
* Do not try to break dependency cycles across dependency lists. This causes
|
||||
the solved graph to sometimes miss required dependency nodes because the
|
||||
solver detected an incorrect dependency cycle.
|
||||
|
||||
* New API: pkgconf_queue_solve(), which replaces pkgconf_queue_apply().
|
||||
pkgconf_queue_apply is now deprecated and should not be used in new code.
|
||||
|
||||
Changes from 1.9.0 to 1.9.1:
|
||||
----------------------------
|
||||
|
||||
* Skip graph flattening and traversal for query types which only make sense
|
||||
for a single pkg-config module.
|
||||
|
||||
The old solver walked these graphs with --maximum-traverse-depth=1 in
|
||||
these cases, but this is no longer helpful because the graph is flattened
|
||||
by the new solver.
|
||||
|
||||
Changes from 1.8.0 to 1.9.0:
|
||||
----------------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* bomtool/main.c
|
||||
* main() routine, printer functions
|
||||
*
|
||||
* Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
|
||||
* pkgconf authors (see AUTHORS).
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* This software is provided 'as is' and without any warranty, express or
|
||||
* implied. In no event shall the authors be liable for any damages arising
|
||||
* from the use of this software.
|
||||
*/
|
||||
|
||||
#include "libpkgconf/config.h"
|
||||
#include <libpkgconf/stdinc.h>
|
||||
#include <libpkgconf/libpkgconf.h>
|
||||
#include "getopt_long.h"
|
||||
|
||||
#define PKG_VERSION (((uint64_t) 1) << 1)
|
||||
#define PKG_ABOUT (((uint64_t) 1) << 2)
|
||||
#define PKG_HELP (((uint64_t) 1) << 3)
|
||||
|
||||
static const char *spdx_version = "SPDX-2.2";
|
||||
static const char *bom_license = "CC0-1.0";
|
||||
static const char *document_ref = "SPDXRef-DOCUMENT";
|
||||
|
||||
static pkgconf_client_t pkg_client;
|
||||
static uint64_t want_flags;
|
||||
static size_t maximum_package_count = 0;
|
||||
static int maximum_traverse_depth = 2000;
|
||||
FILE *error_msgout = NULL;
|
||||
|
||||
static bool
|
||||
error_handler(const char *msg, const pkgconf_client_t *client, void *data)
|
||||
{
|
||||
(void) client;
|
||||
(void) data;
|
||||
fprintf(error_msgout, "%s", msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *
|
||||
sbom_spdx_identity(pkgconf_pkg_t *pkg)
|
||||
{
|
||||
static char buf[PKGCONF_ITEM_SIZE];
|
||||
|
||||
snprintf(buf, sizeof buf, "%sC64%s", pkg->id, pkg->version);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static const char *
|
||||
sbom_name(pkgconf_pkg_t *world)
|
||||
{
|
||||
static char buf[PKGCONF_BUFSIZE];
|
||||
pkgconf_node_t *node;
|
||||
|
||||
pkgconf_strlcpy(buf, "SBOM-SPDX", sizeof buf);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
|
||||
if (!dep->match)
|
||||
continue;
|
||||
|
||||
pkgconf_strlcat(buf, "-", sizeof buf);
|
||||
pkgconf_strlcat(buf, sbom_spdx_identity(match), sizeof buf);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
write_sbom_header(pkgconf_client_t *client, pkgconf_pkg_t *world)
|
||||
{
|
||||
(void) client;
|
||||
(void) world;
|
||||
|
||||
printf("SPDXVersion: %s\n", spdx_version);
|
||||
printf("DataLicense: %s\n", bom_license);
|
||||
printf("SPDXID: %s\n", document_ref);
|
||||
printf("DocumentName: %s\n", sbom_name(world));
|
||||
printf("DocumentNamespace: https://spdx.org/spdxdocs/bomtool-%s\n", PACKAGE_VERSION);
|
||||
printf("Creator: Tool: bomtool %s\n", PACKAGE_VERSION);
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static const char *
|
||||
sbom_identity(pkgconf_pkg_t *pkg)
|
||||
{
|
||||
static char buf[PKGCONF_ITEM_SIZE];
|
||||
|
||||
snprintf(buf, sizeof buf, "%s@%s", pkg->id, pkg->version);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
write_sbom_package(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
|
||||
{
|
||||
(void) client;
|
||||
(void) unused;
|
||||
|
||||
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
|
||||
return;
|
||||
|
||||
printf("##### Package: %s\n\n", sbom_identity(pkg));
|
||||
|
||||
printf("PackageName: %s\n", sbom_identity(pkg));
|
||||
printf("SPDXID: SPDXRef-Package-%s\n", sbom_spdx_identity(pkg));
|
||||
printf("PackageVersion: %s\n", pkg->version);
|
||||
printf("PackageDownloadLocation: NOASSERTION\n");
|
||||
printf("PackageVerificationCode: NOASSERTION\n");
|
||||
|
||||
/* XXX: What about projects? */
|
||||
if (pkg->maintainer != NULL)
|
||||
printf("PackageSupplier: Person: %s\n", pkg->maintainer);
|
||||
|
||||
if (pkg->url != NULL)
|
||||
printf("PackageHomePage: %s\n", pkg->url);
|
||||
|
||||
printf("PackageLicenseDeclared: %s\n", pkg->license != NULL ? pkg->license : "NOASSERTION");
|
||||
|
||||
if (pkg->copyright != NULL)
|
||||
printf("PackageCopyrightText: <text>%s</text>\n", pkg->copyright);
|
||||
|
||||
if (pkg->description != NULL)
|
||||
printf("PackageSummary: <text>%s</text>\n", pkg->description);
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
write_sbom_relationships(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
|
||||
{
|
||||
(void) client;
|
||||
(void) unused;
|
||||
|
||||
char baseref[PKGCONF_ITEM_SIZE];
|
||||
pkgconf_node_t *node;
|
||||
|
||||
if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
|
||||
return;
|
||||
|
||||
snprintf(baseref, sizeof baseref, "SPDXRef-Package-%sC64%s", pkg->id, pkg->version);
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
|
||||
if (!dep->match)
|
||||
continue;
|
||||
|
||||
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
|
||||
printf("Relationship: SPDXRef-Package-%s DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
|
||||
}
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
|
||||
if (!dep->match)
|
||||
continue;
|
||||
|
||||
printf("Relationship: %s DEPENDS_ON SPDXRef-Package-%s\n", baseref, sbom_spdx_identity(match));
|
||||
printf("Relationship: SPDXRef-Package-%s DEV_DEPENDENCY_OF %s\n", sbom_spdx_identity(match), baseref);
|
||||
}
|
||||
|
||||
if (pkg->required.head != NULL || pkg->requires_private.head != NULL)
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
static bool
|
||||
generate_sbom_from_world(pkgconf_client_t *client, pkgconf_pkg_t *world)
|
||||
{
|
||||
int eflag;
|
||||
pkgconf_node_t *node;
|
||||
|
||||
write_sbom_header(client, world);
|
||||
|
||||
eflag = pkgconf_pkg_traverse(client, world, write_sbom_package, NULL, maximum_traverse_depth, 0);
|
||||
if (eflag != PKGCONF_PKG_ERRF_OK)
|
||||
return false;
|
||||
|
||||
eflag = pkgconf_pkg_traverse(client, world, write_sbom_relationships, NULL, maximum_traverse_depth, 0);
|
||||
if (eflag != PKGCONF_PKG_ERRF_OK)
|
||||
return false;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(world->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *dep = node->data;
|
||||
pkgconf_pkg_t *match = dep->match;
|
||||
|
||||
if (!dep->match)
|
||||
continue;
|
||||
|
||||
printf("Relationship: %s DESCRIBES SPDXRef-Package-%s\n", document_ref, sbom_spdx_identity(match));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
version(void)
|
||||
{
|
||||
printf("bomtool %s\n", PACKAGE_VERSION);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
about(void)
|
||||
{
|
||||
printf("bomtool (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
printf("Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021\n");
|
||||
printf(" pkgconf authors (see AUTHORS in documentation directory).\n\n");
|
||||
printf("Permission to use, copy, modify, and/or distribute this software for any\n");
|
||||
printf("purpose with or without fee is hereby granted, provided that the above\n");
|
||||
printf("copyright notice and this permission notice appear in all copies.\n\n");
|
||||
printf("This software is provided 'as is' and without any warranty, express or\n");
|
||||
printf("implied. In no event shall the authors be liable for any damages arising\n");
|
||||
printf("from the use of this software.\n\n");
|
||||
printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: bomtool [--flags] [modules]\n");
|
||||
|
||||
printf("\nbasic options:\n\n");
|
||||
|
||||
printf(" --help this message\n");
|
||||
printf(" --about print bomtool version and license to stdout\n");
|
||||
printf(" --version print bomtool version to stdout\n");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ret = EXIT_SUCCESS;
|
||||
pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER;
|
||||
unsigned int want_client_flags = PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
|
||||
pkgconf_cross_personality_t *personality = pkgconf_cross_personality_default();
|
||||
pkgconf_pkg_t world = {
|
||||
.id = "virtual:world",
|
||||
.realname = "virtual world package",
|
||||
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
|
||||
};
|
||||
|
||||
error_msgout = stderr;
|
||||
|
||||
struct pkg_option options[] = {
|
||||
{ "version", no_argument, &want_flags, PKG_VERSION, },
|
||||
{ "about", no_argument, &want_flags, PKG_ABOUT, },
|
||||
{ "help", no_argument, &want_flags, PKG_HELP, },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case '?':
|
||||
case ':':
|
||||
return EXIT_FAILURE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pkgconf_client_init(&pkg_client, error_handler, NULL, personality);
|
||||
|
||||
/* we have determined what features we want most likely. in some cases, we override later. */
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags);
|
||||
|
||||
/* at this point, want_client_flags should be set, so build the dir list */
|
||||
pkgconf_client_dir_list_build(&pkg_client, personality);
|
||||
|
||||
if ((want_flags & PKG_ABOUT) == PKG_ABOUT)
|
||||
return about();
|
||||
|
||||
if ((want_flags & PKG_VERSION) == PKG_VERSION)
|
||||
return version();
|
||||
|
||||
if ((want_flags & PKG_HELP) == PKG_HELP)
|
||||
return usage();
|
||||
|
||||
while (1)
|
||||
{
|
||||
const char *package = argv[pkg_optind];
|
||||
|
||||
if (package == NULL)
|
||||
break;
|
||||
|
||||
/* check if there is a limit to the number of packages allowed to be included, if so and we have hit
|
||||
* the limit, stop adding packages to the queue.
|
||||
*/
|
||||
if (maximum_package_count > 0 && pkgq.length > maximum_package_count)
|
||||
break;
|
||||
|
||||
while (isspace((unsigned int)package[0]))
|
||||
package++;
|
||||
|
||||
/* skip empty packages */
|
||||
if (package[0] == '\0') {
|
||||
pkg_optind++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1])))
|
||||
{
|
||||
pkgconf_queue_push(&pkgq, package);
|
||||
pkg_optind++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char packagebuf[PKGCONF_BUFSIZE];
|
||||
|
||||
snprintf(packagebuf, sizeof packagebuf, "%s %s %s", package, argv[pkg_optind + 1], argv[pkg_optind + 2]);
|
||||
pkg_optind += 3;
|
||||
|
||||
pkgconf_queue_push(&pkgq, packagebuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (pkgq.head == NULL)
|
||||
{
|
||||
fprintf(stderr, "Please specify at least one package name on the command line.\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!generate_sbom_from_world(&pkg_client, &world))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
pkgconf_solution_free(&pkg_client, &world);
|
||||
pkgconf_queue_free(&pkgq);
|
||||
pkgconf_cross_personality_deinit(personality);
|
||||
pkgconf_client_deinit(&pkg_client);
|
||||
|
||||
return ret;
|
||||
}
|
127
cli/main.c
127
cli/main.c
|
@ -822,6 +822,11 @@ main(int argc, char *argv[])
|
|||
unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE;
|
||||
pkgconf_cross_personality_t *personality = NULL;
|
||||
bool opened_error_msgout = false;
|
||||
pkgconf_pkg_t world = {
|
||||
.id = "virtual:world",
|
||||
.realname = "virtual world package",
|
||||
.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
|
||||
};
|
||||
|
||||
want_flags = 0;
|
||||
|
||||
|
@ -1105,17 +1110,11 @@ main(int argc, char *argv[])
|
|||
if ((want_flags & PKG_INTERNAL_CFLAGS) == PKG_INTERNAL_CFLAGS)
|
||||
want_client_flags |= PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS;
|
||||
|
||||
#ifdef XXX_NOTYET
|
||||
/* if these selectors are used, it means that we are inquiring about a single package.
|
||||
* so signal to libpkgconf that we do not want to use the dependency resolver for more than one level,
|
||||
* and also limit the SAT problem to a single package.
|
||||
*
|
||||
* i disabled this because too many upstream maintainers are still invoking pkg-config correctly to have
|
||||
* the more sane behaviour as default. use --maximum-traverse-depth=1 or PKG_CONFIG_MAXIMUM_TRAVERSE_DEPTH
|
||||
* environment variable to get the same results in meantime.
|
||||
*/
|
||||
if ((want_flags & PKG_EXISTS) == 0 &&
|
||||
((want_flags & PKG_REQUIRES) == PKG_REQUIRES ||
|
||||
if (((want_flags & PKG_REQUIRES) == PKG_REQUIRES ||
|
||||
(want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
|
||||
(want_flags & PKG_PROVIDES) == PKG_PROVIDES ||
|
||||
(want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
|
||||
|
@ -1126,7 +1125,6 @@ main(int argc, char *argv[])
|
|||
maximum_package_count = 1;
|
||||
maximum_traverse_depth = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getenv("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") != NULL)
|
||||
want_flags |= PKG_KEEP_SYSTEM_CFLAGS;
|
||||
|
@ -1137,6 +1135,12 @@ main(int argc, char *argv[])
|
|||
if ((builddir = getenv("PKG_CONFIG_TOP_BUILD_DIR")) != NULL)
|
||||
pkgconf_client_set_buildroot_dir(&pkg_client, builddir);
|
||||
|
||||
if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
|
||||
(want_flags & PKG_CFLAGS))
|
||||
{
|
||||
want_client_flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
|
||||
}
|
||||
|
||||
if ((sysroot_dir = getenv("PKG_CONFIG_SYSROOT_DIR")) != NULL)
|
||||
{
|
||||
const char *destdir;
|
||||
|
@ -1357,86 +1361,62 @@ cleanup3:
|
|||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifndef PKGCONF_LITE
|
||||
if ((want_flags & PKG_SIMULATE) == PKG_SIMULATE)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ERRORS);
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_simulate, -1, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_simulate(&pkg_client, &world, NULL, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!pkgconf_queue_validate(&pkg_client, &pkgq, maximum_traverse_depth))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_VALIDATE) == PKG_VALIDATE)
|
||||
goto out;
|
||||
|
||||
if ((want_flags & PKG_DUMP_LICENSE) == PKG_DUMP_LICENSE)
|
||||
{
|
||||
pkgconf_queue_apply(&pkg_client, &pkgq, apply_license, maximum_traverse_depth, &ret);
|
||||
apply_license(&pkg_client, &world, &ret, maximum_traverse_depth);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_UNINSTALLED) == PKG_UNINSTALLED)
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
pkgconf_queue_apply(&pkg_client, &pkgq, apply_uninstalled, maximum_traverse_depth, &ret);
|
||||
apply_uninstalled(&pkg_client, &world, &ret, maximum_traverse_depth);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (want_env_prefix != NULL)
|
||||
{
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_env, maximum_traverse_depth, want_env_prefix))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
apply_env(&pkg_client, &world, want_env_prefix, maximum_traverse_depth);
|
||||
want_flags = 0;
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_PROVIDES) == PKG_PROVIDES)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_provides, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_provides(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
#ifndef PKGCONF_LITE
|
||||
if ((want_flags & PKG_DIGRAPH) == PKG_DIGRAPH)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_digraph, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_digraph(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((want_flags & PKG_MODVERSION) == PKG_MODVERSION)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_modversion, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_modversion(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_PATH) == PKG_PATH)
|
||||
|
@ -1444,22 +1424,13 @@ cleanup3:
|
|||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_path, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_path(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_VARIABLES) == PKG_VARIABLES)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_variables, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_variables(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if (want_variable)
|
||||
|
@ -1467,66 +1438,40 @@ cleanup3:
|
|||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_variable, maximum_traverse_depth, want_variable))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_variable(&pkg_client, &world, want_variable, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_REQUIRES) == PKG_REQUIRES)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_requires, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
apply_requires(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE)
|
||||
{
|
||||
want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_requires_private, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags);
|
||||
apply_requires_private(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_CFLAGS))
|
||||
{
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
|
||||
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_cflags, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out_println;
|
||||
}
|
||||
|
||||
pkgconf_client_set_flags(&pkg_client, want_client_flags);
|
||||
apply_cflags(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
if ((want_flags & PKG_LIBS))
|
||||
{
|
||||
if (!pkgconf_queue_apply(&pkg_client, &pkgq, apply_libs, maximum_traverse_depth, NULL))
|
||||
{
|
||||
ret = EXIT_FAILURE;
|
||||
goto out_println;
|
||||
}
|
||||
if (!(want_flags & PKG_STATIC))
|
||||
pkgconf_client_set_flags(&pkg_client, pkg_client.flags & ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
|
||||
|
||||
apply_libs(&pkg_client, &world, NULL, maximum_traverse_depth);
|
||||
}
|
||||
|
||||
out_println:
|
||||
if (want_flags & (PKG_CFLAGS|PKG_LIBS))
|
||||
printf("\n");
|
||||
|
||||
out:
|
||||
pkgconf_solution_free(&pkg_client, &world);
|
||||
pkgconf_queue_free(&pkgq);
|
||||
pkgconf_cross_personality_deinit(personality);
|
||||
pkgconf_client_deinit(&pkg_client);
|
||||
|
|
|
@ -149,7 +149,6 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
|
|||
{
|
||||
cnt = pkgconf_strlcpy(bptr, ".lib", buf_remaining);
|
||||
bptr += cnt;
|
||||
buf_remaining -= cnt;
|
||||
}
|
||||
|
||||
if (escape)
|
||||
|
|
|
@ -12,7 +12,7 @@ dnl implied. In no event shall the authors be liable for any damages arising
|
|||
dnl from the use of this software.
|
||||
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([pkgconf],[1.9.0],[https://github.com/pkgconf/pkgconf/issues/new])
|
||||
AC_INIT([pkgconf],[1.9.3],[https://github.com/pkgconf/pkgconf/issues/new])
|
||||
AC_CONFIG_SRCDIR([cli/main.c])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AX_CHECK_COMPILE_FLAG([-Wall], [CFLAGS="$CFLAGS -Wall"])
|
||||
|
|
|
@ -5,7 +5,8 @@ libdir=@libdir@
|
|||
|
||||
Name: libpkgconf
|
||||
Description: a library for accessing and manipulating development framework configuration
|
||||
URL: http://github.com/pkgconf/pkgconf
|
||||
URL: https://gitea.treehouse.systems/ariadne/pkgconf
|
||||
License: ISC
|
||||
Version: @PACKAGE_VERSION@
|
||||
CFlags: -I${includedir}/pkgconf
|
||||
Libs: -L${libdir} -lpkgconf
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libpkgconf/bsdstubs.h>
|
||||
#include <libpkgconf/config.h>
|
||||
|
|
|
@ -160,7 +160,7 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
|
|||
pkgconf_fragment_t *parent = list->tail->data;
|
||||
|
||||
/* only attempt to merge 'special' fragments together */
|
||||
if (!parent->type && pkgconf_fragment_is_unmergeable(parent->data))
|
||||
if (!parent->type && parent->data != NULL && pkgconf_fragment_is_unmergeable(parent->data))
|
||||
{
|
||||
size_t len;
|
||||
char *newdata;
|
||||
|
|
|
@ -79,8 +79,8 @@ typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
|
|||
#define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
|
||||
for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
|
||||
|
||||
#define LIBPKGCONF_VERSION 10900
|
||||
#define LIBPKGCONF_VERSION_STR "1.9.0"
|
||||
#define LIBPKGCONF_VERSION 10903
|
||||
#define LIBPKGCONF_VERSION_STR "1.9.3"
|
||||
|
||||
struct pkgconf_fragment_ {
|
||||
pkgconf_node_t iter;
|
||||
|
@ -111,8 +111,12 @@ struct pkgconf_tuple_ {
|
|||
|
||||
char *key;
|
||||
char *value;
|
||||
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#define PKGCONF_PKG_TUPLEF_OVERRIDE 0x1
|
||||
|
||||
struct pkgconf_path_ {
|
||||
pkgconf_node_t lnode;
|
||||
|
||||
|
@ -137,6 +141,8 @@ struct pkgconf_pkg_ {
|
|||
char *url;
|
||||
char *pc_filedir;
|
||||
char *license;
|
||||
char *maintainer;
|
||||
char *copyright;
|
||||
|
||||
pkgconf_list_t libs;
|
||||
pkgconf_list_t libs_private;
|
||||
|
@ -266,6 +272,7 @@ PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *p
|
|||
#define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES 0x10000
|
||||
|
||||
#define PKGCONF_PKG_DEPF_INTERNAL 0x1
|
||||
#define PKGCONF_PKG_DEPF_PRIVATE 0x2
|
||||
|
||||
#define PKGCONF_PKG_ERRF_OK 0x0
|
||||
#define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1
|
||||
|
@ -377,9 +384,11 @@ PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const cha
|
|||
/* queue.c */
|
||||
PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
|
||||
PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
|
||||
PKGCONF_API bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth);
|
||||
PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list);
|
||||
PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data);
|
||||
PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth);
|
||||
PKGCONF_API void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world);
|
||||
|
||||
/* cache.c */
|
||||
PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id);
|
||||
|
|
|
@ -154,20 +154,34 @@ pkgconf_pkg_parser_internal_dependency_func(pkgconf_client_t *client, pkgconf_pk
|
|||
pkgconf_dependency_parse(client, pkg, dest, value, PKGCONF_PKG_DEPF_INTERNAL);
|
||||
}
|
||||
|
||||
/* a variant of pkgconf_pkg_parser_dependency_func which colors the dependency node as an "internal" dependency. */
|
||||
static void
|
||||
pkgconf_pkg_parser_private_dependency_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
|
||||
{
|
||||
(void) keyword;
|
||||
(void) lineno;
|
||||
|
||||
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
|
||||
pkgconf_dependency_parse(client, pkg, dest, value, PKGCONF_PKG_DEPF_PRIVATE);
|
||||
}
|
||||
|
||||
/* keep this in alphabetical order */
|
||||
static const pkgconf_pkg_parser_keyword_pair_t pkgconf_pkg_parser_keyword_funcs[] = {
|
||||
{"CFLAGS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags)},
|
||||
{"CFLAGS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, cflags_private)},
|
||||
{"Conflicts", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, conflicts)},
|
||||
{"Copyright", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, copyright)},
|
||||
{"Description", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, description)},
|
||||
{"LIBS", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs)},
|
||||
{"LIBS.private", pkgconf_pkg_parser_fragment_func, offsetof(pkgconf_pkg_t, libs_private)},
|
||||
{"License", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, license)},
|
||||
{"Maintainer", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, maintainer)},
|
||||
{"Name", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, realname)},
|
||||
{"Provides", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, provides)},
|
||||
{"Requires", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, required)},
|
||||
{"Requires.internal", pkgconf_pkg_parser_internal_dependency_func, offsetof(pkgconf_pkg_t, requires_private)},
|
||||
{"Requires.private", pkgconf_pkg_parser_dependency_func, offsetof(pkgconf_pkg_t, requires_private)},
|
||||
{"Requires.private", pkgconf_pkg_parser_private_dependency_func, offsetof(pkgconf_pkg_t, requires_private)},
|
||||
{"URL", pkgconf_pkg_parser_tuple_func, offsetof(pkgconf_pkg_t, url)},
|
||||
{"Version", pkgconf_pkg_parser_version_func, offsetof(pkgconf_pkg_t, version)},
|
||||
};
|
||||
|
||||
|
@ -516,6 +530,15 @@ pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg)
|
|||
if (pkg->pc_filedir != NULL)
|
||||
free(pkg->pc_filedir);
|
||||
|
||||
if (pkg->license != NULL)
|
||||
free(pkg->license);
|
||||
|
||||
if (pkg->maintainer != NULL)
|
||||
free(pkg->maintainer);
|
||||
|
||||
if (pkg->copyright != NULL)
|
||||
free(pkg->copyright);
|
||||
|
||||
free(pkg);
|
||||
}
|
||||
|
||||
|
@ -829,8 +852,8 @@ pkgconf_compare_version(const char *a, const char *b)
|
|||
pkgconf_strlcpy(buf1, a, sizeof buf1);
|
||||
pkgconf_strlcpy(buf2, b, sizeof buf2);
|
||||
|
||||
one = str1 = buf1;
|
||||
two = str2 = buf2;
|
||||
one = buf1;
|
||||
two = buf2;
|
||||
|
||||
while (*one || *two)
|
||||
{
|
||||
|
@ -1478,12 +1501,20 @@ pkgconf_pkg_walk_list(pkgconf_client_t *client,
|
|||
* the list, so that we dont create a situation where
|
||||
* memory is leaked due to circular ownership.
|
||||
* i.e: A owns B owns A
|
||||
*
|
||||
* TODO(ariadne): Breaking circular references between Requires and Requires.private
|
||||
* lists causes problems. Find a way to refactor the Requires.private list out.
|
||||
*/
|
||||
if (!(depnode->flags & PKGCONF_PKG_DEPF_PRIVATE) &&
|
||||
!(parent->flags & PKGCONF_PKG_PROPF_VIRTUAL))
|
||||
{
|
||||
pkgconf_warn(client, "%s: breaking circular reference (%s -> %s -> %s)\n",
|
||||
parent->id, parent->id, pkgdep->id, parent->id);
|
||||
|
||||
pkgconf_node_delete(node, deplist);
|
||||
pkgconf_dependency_unref(client, depnode);
|
||||
}
|
||||
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
@ -1622,6 +1653,7 @@ pkgconf_pkg_traverse(pkgconf_client_t *client,
|
|||
int maxdepth,
|
||||
unsigned int skip_flags)
|
||||
{
|
||||
if (root->flags & PKGCONF_PKG_PROPF_VIRTUAL)
|
||||
client->serial++;
|
||||
|
||||
return pkgconf_pkg_traverse_main(client, root, func, data, maxdepth, skip_flags);
|
||||
|
|
|
@ -116,8 +116,6 @@ pkgconf_queue_collect_dependents(pkgconf_client_t *client, pkgconf_pkg_t *pkg, v
|
|||
if (pkg == world)
|
||||
return;
|
||||
|
||||
if (!(pkg->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE))
|
||||
{
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
|
||||
{
|
||||
pkgconf_dependency_t *flattened_dep;
|
||||
|
@ -126,8 +124,8 @@ pkgconf_queue_collect_dependents(pkgconf_client_t *client, pkgconf_pkg_t *pkg, v
|
|||
|
||||
pkgconf_node_insert(&flattened_dep->iter, flattened_dep, &world->required);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (client->flags & PKGCONF_PKG_PKGF_SEARCH_PRIVATE)
|
||||
{
|
||||
PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
|
||||
{
|
||||
|
@ -215,10 +213,13 @@ next:
|
|||
{
|
||||
pkgconf_dependency_t *dep = deps[i];
|
||||
|
||||
if (dep->match == NULL)
|
||||
continue;
|
||||
|
||||
memset(&dep->iter, '\0', sizeof (dep->iter));
|
||||
pkgconf_node_insert(&dep->iter, dep, list);
|
||||
|
||||
PKGCONF_TRACE(client, "slot %zu: dep %s matched to %p<%s> hits %lu", i, dep->package, dep->match, dep->match == NULL ? "NULL" : dep->match->id, dep->match->hits);
|
||||
PKGCONF_TRACE(client, "slot %zu: dep %s matched to %p<%s> hits %lu", i, dep->package, dep->match, dep->match->id, dep->match->hits);
|
||||
}
|
||||
|
||||
free(deps);
|
||||
|
@ -254,6 +255,53 @@ pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_lis
|
|||
return PKGCONF_PKG_ERRF_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth)
|
||||
*
|
||||
* Removes references to package nodes contained in a solution.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
|
||||
* :param pkgconf_pkg_t* world: The root for the generated dependency graph. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
|
||||
* :returns: nothing
|
||||
*/
|
||||
void
|
||||
pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world)
|
||||
{
|
||||
(void) client;
|
||||
|
||||
if (world->flags & PKGCONF_PKG_PROPF_VIRTUAL)
|
||||
{
|
||||
pkgconf_dependency_free(&world->required);
|
||||
pkgconf_dependency_free(&world->requires_private);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
* .. c:function:: bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
|
||||
*
|
||||
* Solves and flattens the dependency graph for the supplied dependency list.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
|
||||
* :param pkgconf_list_t* list: The list of dependency requests to consider.
|
||||
* :param pkgconf_pkg_t* world: The root for the generated dependency graph, provided by the caller. Should have PKGCONF_PKG_PROPF_VIRTUAL flag.
|
||||
* :param int maxdepth: The maximum allowed depth for the dependency resolver. A depth of -1 means unlimited.
|
||||
* :returns: true if the dependency resolver found a solution, otherwise false.
|
||||
* :rtype: bool
|
||||
*/
|
||||
bool
|
||||
pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth)
|
||||
{
|
||||
/* if maxdepth is one, then we will not traverse deeper than our virtual package. */
|
||||
if (!maxdepth)
|
||||
maxdepth = -1;
|
||||
|
||||
return pkgconf_queue_verify(client, world, list, maxdepth) == PKGCONF_PKG_ERRF_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
|
@ -262,6 +310,8 @@ pkgconf_queue_verify(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_lis
|
|||
* Attempt to compile a dependency resolution queue into a dependency resolution problem, then attempt to solve the problem and
|
||||
* feed the solution to a callback function if a complete dependency graph is found.
|
||||
*
|
||||
* This function should not be used in new code. Use pkgconf_queue_solve instead.
|
||||
*
|
||||
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
|
||||
* :param pkgconf_list_t* list: The list of dependency requests to consider.
|
||||
* :param pkgconf_queue_apply_func_t func: The callback function to call if a solution is found by the dependency resolver.
|
||||
|
@ -284,7 +334,7 @@ pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queu
|
|||
if (!maxdepth)
|
||||
maxdepth = -1;
|
||||
|
||||
if (pkgconf_queue_verify(client, &world, list, maxdepth) != PKGCONF_PKG_ERRF_OK)
|
||||
if (!pkgconf_queue_solve(client, list, &world, maxdepth))
|
||||
goto cleanup;
|
||||
|
||||
/* the world dependency set is flattened after it is returned from pkgconf_queue_verify */
|
||||
|
|
|
@ -48,6 +48,22 @@ pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *
|
|||
pkgconf_tuple_add(client, &client->global_vars, key, value, false, 0);
|
||||
}
|
||||
|
||||
static pkgconf_tuple_t *
|
||||
lookup_global_tuple(const pkgconf_client_t *client, const char *key)
|
||||
{
|
||||
pkgconf_node_t *node;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
|
||||
{
|
||||
pkgconf_tuple_t *tuple = node->data;
|
||||
|
||||
if (!strcmp(tuple->key, key))
|
||||
return tuple;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* !doc
|
||||
*
|
||||
|
@ -63,17 +79,13 @@ pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *
|
|||
char *
|
||||
pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key)
|
||||
{
|
||||
pkgconf_node_t *node;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(client->global_vars.head, node)
|
||||
{
|
||||
pkgconf_tuple_t *tuple = node->data;
|
||||
|
||||
if (!strcmp(tuple->key, key))
|
||||
return tuple->value;
|
||||
}
|
||||
pkgconf_tuple_t *tuple;
|
||||
|
||||
tuple = lookup_global_tuple(client, key);
|
||||
if (tuple == NULL)
|
||||
return NULL;
|
||||
|
||||
return tuple->value;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -108,13 +120,18 @@ pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv)
|
|||
{
|
||||
char *workbuf = strdup(kv);
|
||||
char *value;
|
||||
pkgconf_tuple_t *tuple;
|
||||
|
||||
value = strchr(workbuf, '=');
|
||||
if (value == NULL)
|
||||
goto out;
|
||||
|
||||
*value++ = '\0';
|
||||
pkgconf_tuple_add_global(client, workbuf, value);
|
||||
|
||||
tuple = pkgconf_tuple_add(client, &client->global_vars, workbuf, value, false, 0);
|
||||
if (tuple != NULL)
|
||||
tuple->flags = PKGCONF_PKG_TUPLEF_OVERRIDE;
|
||||
|
||||
out:
|
||||
free(workbuf);
|
||||
}
|
||||
|
@ -257,6 +274,11 @@ char *
|
|||
pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key)
|
||||
{
|
||||
pkgconf_node_t *node;
|
||||
pkgconf_tuple_t *global_tuple;
|
||||
|
||||
global_tuple = lookup_global_tuple(client, key);
|
||||
if (global_tuple != NULL && global_tuple->flags & PKGCONF_PKG_TUPLEF_OVERRIDE)
|
||||
return global_tuple->value;
|
||||
|
||||
PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
|
||||
{
|
||||
|
@ -266,7 +288,10 @@ pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const c
|
|||
return tuple->value;
|
||||
}
|
||||
|
||||
return pkgconf_tuple_find_global(client, key);
|
||||
if (global_tuple != NULL)
|
||||
return global_tuple->value;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
10
man/pc.5
10
man/pc.5
|
@ -99,6 +99,9 @@ These flags are always used, regardless of whether static compilation is request
|
|||
.It Cflags.private
|
||||
Required compiler flags for static compilation.
|
||||
(optional; fragment list; pkgconf extension)
|
||||
.It Copyright
|
||||
A copyright attestation statement.
|
||||
(optional; literal; pkgconf extension)
|
||||
.It Libs
|
||||
Required linking flags for this package.
|
||||
Libraries this package depends on for linking against it, which are not
|
||||
|
@ -113,6 +116,10 @@ not described as dependencies should be specified here.
|
|||
.It License
|
||||
The asserted SPDX license tag that should be applied to the given package.
|
||||
(optional; literal; pkgconf extension)
|
||||
.It Maintainer
|
||||
The preferred contact for the maintainer. This should be in the format of a
|
||||
name followed by an e-mail address or website.
|
||||
(optional; literal; pkgconf extension)
|
||||
.It Requires
|
||||
Required dependencies that must be met for the package to be usable.
|
||||
All dependencies must be satisfied or the pkg-config implementation must not use
|
||||
|
@ -154,6 +161,9 @@ includedir=${prefix}/include
|
|||
|
||||
Name: libfoo # human-readable name
|
||||
Description: an example library called libfoo # human-readable description
|
||||
Copyright: Copyright (c) 2022 pkgconf project authors
|
||||
License: Apache-2.0
|
||||
Maintainer: the pkgconf project <http://www.pkgconf.org>
|
||||
Version: 1.0
|
||||
URL: http://www.pkgconf.org
|
||||
Requires: libbar > 2.0.0
|
||||
|
|
17
meson.build
17
meson.build
|
@ -1,7 +1,7 @@
|
|||
project('pkgconf', 'c',
|
||||
version : '1.9.0',
|
||||
version : '1.9.3',
|
||||
license : 'ISC',
|
||||
meson_version : '>=0.47',
|
||||
meson_version : '>=0.49',
|
||||
default_options : ['c_std=c99'],
|
||||
)
|
||||
|
||||
|
@ -117,13 +117,12 @@ pkgconf_exe = executable('pkgconf',
|
|||
c_args: build_static,
|
||||
install : true)
|
||||
|
||||
if get_option('tests')
|
||||
kyua_exe = find_program('kyua')
|
||||
atf_sh_exe = find_program('atf-sh')
|
||||
kyuafile = configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata)
|
||||
test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile', kyuafile, '--build-root', meson.current_build_dir()])
|
||||
subdir('tests')
|
||||
endif
|
||||
with_tests = get_option('tests')
|
||||
kyua_exe = find_program('kyua', required : with_tests, disabler : true)
|
||||
atf_sh_exe = find_program('atf-sh', required : with_tests, disabler : true)
|
||||
kyuafile = configure_file(input : 'Kyuafile.in', output : 'Kyuafile', configuration : cdata)
|
||||
test('kyua', kyua_exe, args : ['--config=none', 'test', '--kyuafile', kyuafile, '--build-root', meson.current_build_dir()])
|
||||
subdir('tests')
|
||||
|
||||
install_man('man/pkgconf.1')
|
||||
install_man('man/pkg.m4.7')
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
option('tests', type: 'boolean', value: true,
|
||||
description: 'Build tests which depends upon the kyua framework'
|
||||
option(
|
||||
'tests',
|
||||
type: 'feature',
|
||||
description: 'Build tests which depends upon the kyua framework',
|
||||
)
|
|
@ -31,6 +31,7 @@ tests_init \
|
|||
libs_static_ordering \
|
||||
license_isc \
|
||||
license_noassertion \
|
||||
modversion_noflatten \
|
||||
pkg_config_path \
|
||||
nolibs \
|
||||
nocflags \
|
||||
|
@ -323,3 +324,10 @@ license_noassertion_body()
|
|||
-o inline:"bar: NOASSERTION\nfoo: ISC\n" \
|
||||
pkgconf --with-path=${selfdir}/lib1 --license bar
|
||||
}
|
||||
|
||||
modversion_noflatten_body()
|
||||
{
|
||||
atf_check \
|
||||
-o inline:"1.3\n" \
|
||||
pkgconf --with-path=${selfdir}/lib1 --modversion bar
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
Name: metapackage-1
|
||||
Version: 0.1
|
||||
Description: metapackage for testing purposes
|
||||
Requires.private: metapackage-2
|
||||
Libs: -lmetapackage-1
|
||||
Cflags: -I/metapackage-1
|
|
@ -0,0 +1,5 @@
|
|||
Name: metapackage-2
|
||||
Version: 0.1
|
||||
Description: metapackage for testing purposes
|
||||
Libs: -lmetapackage-2
|
||||
Cflags: -I/metapackage-2
|
|
@ -0,0 +1,4 @@
|
|||
Name: metapackage
|
||||
Version: 0.1
|
||||
Description: metapackage for testing purposes
|
||||
Requires: metapackage-1, metapackage-2
|
|
@ -8,6 +8,7 @@ tests_init \
|
|||
depgraph_break_2 \
|
||||
depgraph_break_3 \
|
||||
define_variable \
|
||||
define_variable_override \
|
||||
variable \
|
||||
keep_system_libs \
|
||||
libs \
|
||||
|
@ -28,7 +29,8 @@ tests_init \
|
|||
malformed_1 \
|
||||
malformed_quoting \
|
||||
explicit_sysroot \
|
||||
empty_tuple
|
||||
empty_tuple \
|
||||
solver_requires_private_debounce
|
||||
|
||||
# sysroot_munge \
|
||||
|
||||
|
@ -71,6 +73,13 @@ define_variable_body()
|
|||
pkgconf --variable=typelibdir --define-variable='libdir=\${libdir}' typelibdir
|
||||
}
|
||||
|
||||
define_variable_override_body()
|
||||
{
|
||||
export PKG_CONFIG_PATH="${selfdir}/lib1"
|
||||
atf_check -o inline:"/test\n" \
|
||||
pkgconf --variable=prefix --define-variable='prefix=/test' typelibdir
|
||||
}
|
||||
|
||||
variable_body()
|
||||
{
|
||||
export PKG_CONFIG_PATH="${selfdir}/lib1"
|
||||
|
@ -251,3 +260,9 @@ empty_tuple_body()
|
|||
atf_check -o inline:"\n" \
|
||||
pkgconf --with-path="${selfdir}/lib1" --cflags empty-tuple
|
||||
}
|
||||
|
||||
solver_requires_private_debounce_body()
|
||||
{
|
||||
atf_check -o inline:"-I/metapackage-1 -I/metapackage-2 -lmetapackage-1 -lmetapackage-2 \n" \
|
||||
pkgconf --with-path="${selfdir}/lib1" --cflags --libs metapackage
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ missing_body()
|
|||
atf_check \
|
||||
-s exit:1 \
|
||||
-e ignore \
|
||||
-o inline:"\n" \
|
||||
-o ignore \
|
||||
pkgconf --cflags missing-require
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue