pkg: add support for 'simple' Provides rule entries (#95)

pull/100/head
William Pitcock 2016-09-08 22:10:24 -05:00
parent 322a4f6002
commit d304d9cb2e
5 changed files with 83 additions and 8 deletions

View File

@ -55,7 +55,8 @@ EXTRA_DIST = \
tests/lib1/isystem.pc \ tests/lib1/isystem.pc \
tests/lib1/depgraph-break.pc \ tests/lib1/depgraph-break.pc \
tests/lib1/cflags-whitespace.pc \ tests/lib1/cflags-whitespace.pc \
tests/lib1/provides.pc tests/lib1/provides.pc \
tests/lib1/provides-request-simple.pc
pkginclude_HEADERS = libpkgconf/bsdstubs.h libpkgconf/iter.h libpkgconf/libpkgconf.h libpkgconf/stdinc.h pkginclude_HEADERS = libpkgconf/bsdstubs.h libpkgconf/iter.h libpkgconf/libpkgconf.h libpkgconf/stdinc.h
libpkgconf_la_SOURCES = \ libpkgconf_la_SOURCES = \

View File

@ -119,6 +119,7 @@ struct pkgconf_pkg_ {
#define PKGCONF_PKG_PKGF_MUNGE_SYSROOT_PREFIX 0x080 #define PKGCONF_PKG_PKGF_MUNGE_SYSROOT_PREFIX 0x080
#define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x100 #define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x100
#define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x200 #define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x200
#define PKGCONF_PKG_PKGF_SKIP_PROVIDES 0x400
#define PKGCONF_PKG_ERRF_OK 0x0 #define PKGCONF_PKG_ERRF_OK 0x0
#define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1 #define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1

View File

@ -876,6 +876,65 @@ pkgconf_pkg_comparator_lookup_by_name(const char *name)
return (p != NULL) ? p->compare : PKGCONF_CMP_ANY; return (p != NULL) ? p->compare : PKGCONF_CMP_ANY;
} }
typedef struct {
pkgconf_dependency_t *pkgdep;
unsigned int flags;
} pkgconf_pkg_scan_providers_ctx_t;
/*
* pkgconf_pkg_scan_provides_entry(pkg, ctx)
*
* attempt to match a single package's Provides rules against the requested dependency node.
*
* XXX: implement support for version comparisons using backwards dependency version checks,
* right now, we only support Provides rules that are PKGCONF_CMP_ANY as this is still
* proof-of-concept.
*/
static bool
pkgconf_pkg_scan_provides_entry(const pkgconf_pkg_t *pkg, const pkgconf_pkg_scan_providers_ctx_t *ctx)
{
const pkgconf_dependency_t *pkgdep = ctx->pkgdep;
pkgconf_node_t *node;
switch (pkgdep->compare)
{
case PKGCONF_CMP_ANY:
PKGCONF_FOREACH_LIST_ENTRY(pkg->provides.head, node)
{
const pkgconf_dependency_t *provider = node->data;
if (!strcmp(provider->package, pkgdep->package))
return true;
}
break;
}
return false;
}
/*
* pkgconf_pkg_scan_providers(pkgdep, flags, eflags)
*
* scan all available packages to see if a Provides rule matches the pkgdep.
*/
static pkgconf_pkg_t *
pkgconf_pkg_scan_providers(pkgconf_dependency_t *pkgdep, unsigned int flags, unsigned int *eflags)
{
pkgconf_pkg_t *pkg;
pkgconf_pkg_scan_providers_ctx_t ctx = {
.pkgdep = pkgdep,
.flags = flags
};
pkg = pkgconf_scan_all(&ctx, (pkgconf_pkg_iteration_func_t) pkgconf_pkg_scan_provides_entry);
if (pkg != NULL)
return pkg;
if (eflags != NULL)
*eflags |= PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND;
return NULL;
}
/* /*
* pkg_verify_dependency(pkgdep, flags) * pkg_verify_dependency(pkgdep, flags)
* *
@ -892,6 +951,8 @@ pkgconf_pkg_verify_dependency(pkgconf_dependency_t *pkgdep, unsigned int flags,
pkg = pkgconf_pkg_find(pkgdep->package, flags); pkg = pkgconf_pkg_find(pkgdep->package, flags);
if (pkg == NULL) if (pkg == NULL)
{
if (flags & PKGCONF_PKG_PKGF_SKIP_PROVIDES)
{ {
if (eflags != NULL) if (eflags != NULL)
*eflags |= PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND; *eflags |= PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND;
@ -899,6 +960,9 @@ pkgconf_pkg_verify_dependency(pkgconf_dependency_t *pkgdep, unsigned int flags,
return NULL; return NULL;
} }
return pkgconf_pkg_scan_providers(pkgdep, flags, eflags);
}
if (pkg->id == NULL) if (pkg->id == NULL)
pkg->id = strdup(pkgdep->package); pkg->id = strdup(pkgdep->package);

View File

@ -0,0 +1,6 @@
Name: provides-request-simple
Description: A testing pkg-config file
Version: 1.2.3
Libs: -lfoo
Cflags: -I/usr/include/foo
Requires: provides-test-foo

View File

@ -286,16 +286,19 @@ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --cflags prefix-foo1 prefix-foo
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=typelibdir --define-variable='libdir=\${libdir}' typelibdir" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --variable=typelibdir --define-variable='libdir=\${libdir}' typelibdir" \
"\${libdir}/typelibdir" "\${libdir}/typelibdir"
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --print-provides provides" \
"provides = 1.2.3" "provides-test-foo = 1.0.0" "provides-test-baz >= 1.1.0" "provides-test-moo <= 1.2.0"
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/test' ${1} --cflags isystem" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/test' ${1} --cflags isystem" \
"-isystem /test/opt/bad/include" "-isystem /test/opt/bad/include"
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/test' ${1} --cflags cflags-whitespace" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' PKG_CONFIG_SYSROOT_DIR='/test' ${1} --cflags cflags-whitespace" \
"-I /test/opt/bad/include" "-I /test/opt/bad/include"
# 10) tests for internal getopt implementation with options at the end # 10) tests for Provides system
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --print-provides provides" \
"provides = 1.2.3" "provides-test-foo = 1.0.0" "provides-test-baz >= 1.1.0" "provides-test-moo <= 1.2.0"
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} --libs provides-request-simple" \
"-lfoo"
# 11) tests for internal getopt implementation with options at the end
if [ "x@STRICT_MODE@" = "xno" ]; then if [ "x@STRICT_MODE@" = "xno" ]; then
run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} foo --libs" \ run_test "PKG_CONFIG_PATH='${selfdir}/lib1' ${1} foo --libs" \
'-lfoo' '-lfoo'