mirror of
https://gitlab.freedesktop.org/pkg-config/pkg-config.git
synced 2025-12-20 04:20:04 +01:00
Support circular Requires loops
After the packages are parsed, pkg-config recurses through all the required packages to generate one list. Before descending another level, check to see if the package has already been handled and skip it. This allows packages to require each other circularly by breaking the loop. A test has been added resolving a two level deep circular dependency. Freedesktop #7331
This commit is contained in:
parent
3f1f6e79b7
commit
6d6dd43e75
6 changed files with 64 additions and 1 deletions
|
|
@ -8,6 +8,7 @@ TESTS = \
|
|||
check-define-variable \
|
||||
check-libs-private \
|
||||
check-requires-private \
|
||||
check-circular-requires \
|
||||
check-includedir \
|
||||
check-conflicts \
|
||||
check-missing \
|
||||
|
|
@ -45,4 +46,7 @@ EXTRA_DIST = \
|
|||
requires-version-2.pc \
|
||||
requires-version-3.pc \
|
||||
non-l.pc \
|
||||
non-l-required.pc
|
||||
non-l-required.pc \
|
||||
circular-1.pc \
|
||||
circular-2.pc \
|
||||
circular-3.pc
|
||||
|
|
|
|||
8
check/check-circular-requires
Executable file
8
check/check-circular-requires
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
. ${srcdir}/common
|
||||
|
||||
RESULT="-lcirc1 -lcirc2 -lcirc3"
|
||||
run_test --libs circular-1
|
||||
11
check/circular-1.pc
Normal file
11
check/circular-1.pc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include/circ1
|
||||
|
||||
Name: Circular Requires test 1
|
||||
Description: Dummy package for testing circular Requires
|
||||
Version: 1.0.0
|
||||
Requires: circular-2
|
||||
Libs: -lcirc1
|
||||
Cflags: -I${includedir}
|
||||
11
check/circular-2.pc
Normal file
11
check/circular-2.pc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include/circ2
|
||||
|
||||
Name: Circular Requires test 2
|
||||
Description: Dummy package for testing circular Requires
|
||||
Version: 1.0.0
|
||||
Requires: circular-3
|
||||
Libs: -lcirc2
|
||||
Cflags: -I${includedir}
|
||||
11
check/circular-3.pc
Normal file
11
check/circular-3.pc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include/circ3
|
||||
|
||||
Name: Circular Requires test 3
|
||||
Description: Dummy package for testing circular Requires
|
||||
Version: 1.0.0
|
||||
Requires: circular-1
|
||||
Libs: -lcirc3
|
||||
Cflags: -I${includedir}
|
||||
18
pkg.c
18
pkg.c
|
|
@ -626,6 +626,7 @@ static void
|
|||
recursive_fill_list (Package *pkg, GetListFunc func, GSList **listp)
|
||||
{
|
||||
GSList *tmp;
|
||||
static GSList *chain = NULL;
|
||||
|
||||
/*
|
||||
* This function should only be called to resolve Requires or
|
||||
|
|
@ -633,10 +634,27 @@ recursive_fill_list (Package *pkg, GetListFunc func, GSList **listp)
|
|||
*/
|
||||
g_assert (func == get_requires || func == get_requires_private);
|
||||
|
||||
/*
|
||||
* If the package is one of the parents, we can skip it. This allows
|
||||
* circular requires loops to be broken.
|
||||
*/
|
||||
if (g_slist_find (chain, pkg) != NULL)
|
||||
{
|
||||
debug_spew ("Package %s already in requires chain, skipping\n",
|
||||
pkg->key);
|
||||
return;
|
||||
}
|
||||
|
||||
/* record this package in the dependency chain */
|
||||
chain = g_slist_prepend (chain, pkg);
|
||||
|
||||
for (tmp = (*func) (pkg); tmp != NULL; tmp = g_slist_next (tmp))
|
||||
recursive_fill_list (tmp->data, func, listp);
|
||||
|
||||
*listp = g_slist_prepend (*listp, pkg);
|
||||
|
||||
/* remove this package from the dependency chain now that we've unwound */
|
||||
chain = g_slist_remove (chain, pkg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue