mirror of
https://gitlab.freedesktop.org/pkg-config/pkg-config.git
synced 2026-05-20 07:48:10 +02:00
Merge branch 'requires-internal' into 'master'
Add Require.internal field See merge request pkg-config/pkg-config!8
This commit is contained in:
commit
585e0cc6b9
12 changed files with 263 additions and 177 deletions
|
|
@ -31,7 +31,8 @@ RESULT="public-dep >= 1"
|
|||
run_test --print-requires requires-test
|
||||
|
||||
# --print-requires-private
|
||||
RESULT="private-dep >= 1"
|
||||
RESULT="internal-dep >= 1
|
||||
private-dep >= 1"
|
||||
run_test --print-requires-private requires-test
|
||||
|
||||
# --list-all, limit to a subdirectory
|
||||
|
|
@ -51,6 +52,7 @@ run_test --modversion --version simple
|
|||
|
||||
# --print-requires/--print-requires-private allowed together
|
||||
RESULT="public-dep >= 1
|
||||
internal-dep >= 1
|
||||
private-dep >= 1"
|
||||
run_test --print-requires --print-requires-private requires-test
|
||||
run_test --print-requires-private --print-requires requires-test
|
||||
|
|
|
|||
|
|
@ -4,20 +4,23 @@ set -e
|
|||
|
||||
. ${srcdir}/common
|
||||
|
||||
# expect cflags from requires-test and public-dep
|
||||
# expect cflags from requires-test, public-dep and private-dep but not internal-dep
|
||||
RESULT="-I/requires-test/include -I/private-dep/include -I/public-dep/include"
|
||||
run_test --cflags requires-test
|
||||
run_test --cflags requires-notfound-test
|
||||
run_test --static --cflags requires-test
|
||||
run_test --static --cflags requires-notfound-test
|
||||
|
||||
# expect libs for just requires-test and public-dep
|
||||
RESULT="-L/requires-test/lib -L/public-dep/lib -lrequires-test -lpublic-dep"
|
||||
if [ "$list_indirect_deps" = no ]; then
|
||||
run_test --libs requires-test
|
||||
run_test --libs requires-notfound-test
|
||||
fi
|
||||
|
||||
# expect libs for requires-test, public-dep and private-dep in static case
|
||||
RESULT="-L/requires-test/lib -L/private-dep/lib -L/public-dep/lib \
|
||||
-lrequires-test -lprivate-dep -lpublic-dep"
|
||||
# expect libs for requires-test, public-dep, private-dep and internal-dep in static case
|
||||
RESULT="-L/requires-test/lib -L/internal-dep/lib -L/private-dep/lib -L/public-dep/lib \
|
||||
-lrequires-test -linternal-dep -lprivate-dep -lpublic-dep"
|
||||
if [ "$list_indirect_deps" = yes ]; then
|
||||
run_test --libs requires-test
|
||||
fi
|
||||
|
|
|
|||
6
check/internal-dep.pc
Normal file
6
check/internal-dep.pc
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Name: Requires test package
|
||||
Description: Dummy pkgconfig test package for testing Requires/Requires.private
|
||||
Version: 1.0.0
|
||||
Libs: -L/internal-dep/lib -linternal-dep
|
||||
Cflags: -I/internal-dep/include
|
||||
|
||||
9
check/requires-notfound-test.pc
Normal file
9
check/requires-notfound-test.pc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Name: Requires test package
|
||||
Description: Dummy pkgconfig test package for testing Requires/Requires.private
|
||||
Version: 1.0.0
|
||||
Requires: public-dep >= 1
|
||||
Requires.private: private-dep >= 1
|
||||
Requires.internal: notfound-dep >= 1
|
||||
Libs: -L/requires-test/lib -lrequires-test
|
||||
Cflags: -I/requires-test/include
|
||||
|
||||
|
|
@ -3,6 +3,7 @@ Description: Dummy pkgconfig test package for testing Requires/Requires.private
|
|||
Version: 1.0.0
|
||||
Requires: public-dep >= 1
|
||||
Requires.private: private-dep >= 1
|
||||
Requires.internal: internal-dep >= 1
|
||||
Libs: -L/requires-test/lib -lrequires-test
|
||||
Cflags: -I/requires-test/include
|
||||
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ msgstr ""
|
|||
# on various variables needed by the Makefile.in.in installed by
|
||||
# glib-gettextize.
|
||||
dnl
|
||||
glib_DEFUN([GLIB_GNU_GETTEXT],
|
||||
AU_DEFUN([GLIB_GNU_GETTEXT],
|
||||
[AC_REQUIRE([AC_PROG_CC])dnl
|
||||
|
||||
GLIB_LC_MESSAGES
|
||||
|
|
@ -383,7 +383,8 @@ glib_DEFUN([GLIB_GNU_GETTEXT],
|
|||
rm -f po/POTFILES
|
||||
sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
|
||||
< $srcdir/po/POTFILES.in > po/POTFILES
|
||||
])
|
||||
],
|
||||
[[$0: This macro is deprecated. You should use upstream gettext instead.]])
|
||||
|
||||
# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
|
||||
# -------------------------------
|
||||
|
|
|
|||
83
main.c
83
main.c
|
|
@ -483,6 +483,36 @@ static const GOptionEntry options_table[] = {
|
|||
{ NULL, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
print_requires (GList *packages, RequireType type)
|
||||
{
|
||||
GList *pkgtmp;
|
||||
for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
|
||||
{
|
||||
Package *pkg = pkgtmp->data;
|
||||
GList *reqtmp;
|
||||
|
||||
if (type == REQUIRE)
|
||||
reqtmp = pkg->requires;
|
||||
else if (type == REQUIRE_PRIVATE)
|
||||
reqtmp = pkg->requires_private;
|
||||
else
|
||||
reqtmp = pkg->requires_internal;
|
||||
|
||||
for (; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
|
||||
{
|
||||
RequiredVersion *req = reqtmp->data;
|
||||
Package *deppkg = req->package;
|
||||
if (req->comparison == ALWAYS_MATCH)
|
||||
printf ("%s\n", deppkg->key);
|
||||
else
|
||||
printf ("%s %s %s\n", deppkg->key,
|
||||
comparison_to_str(req->comparison),
|
||||
req->version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
|
|
@ -626,6 +656,10 @@ main (int argc, char **argv)
|
|||
(want_static_lib_list && (pkg_flags & LIBS_ANY)))
|
||||
enable_requires_private();
|
||||
|
||||
if (want_requires_private || want_exists ||
|
||||
(want_static_lib_list && (pkg_flags & LIBS_ANY)))
|
||||
enable_requires_internal();
|
||||
|
||||
/* ignore Requires if no Cflags or Libs are requested */
|
||||
|
||||
if (pkg_flags == 0 && !want_requires && !want_exists)
|
||||
|
|
@ -769,53 +803,16 @@ main (int argc, char **argv)
|
|||
|
||||
if (want_requires)
|
||||
{
|
||||
GList *pkgtmp;
|
||||
for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
|
||||
{
|
||||
Package *pkg = pkgtmp->data;
|
||||
GList *reqtmp;
|
||||
|
||||
/* process Requires: */
|
||||
for (reqtmp = pkg->requires; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
|
||||
{
|
||||
Package *deppkg = reqtmp->data;
|
||||
RequiredVersion *req;
|
||||
req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
|
||||
if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
|
||||
printf ("%s\n", deppkg->key);
|
||||
else
|
||||
printf ("%s %s %s\n", deppkg->key,
|
||||
comparison_to_str(req->comparison),
|
||||
req->version);
|
||||
}
|
||||
}
|
||||
/* process Requires: */
|
||||
print_requires (packages, REQUIRE);
|
||||
}
|
||||
if (want_requires_private)
|
||||
{
|
||||
GList *pkgtmp;
|
||||
for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
|
||||
{
|
||||
Package *pkg = pkgtmp->data;
|
||||
GList *reqtmp;
|
||||
/* process Requires.private: */
|
||||
for (reqtmp = pkg->requires_private; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
|
||||
{
|
||||
/* process Requires.internal: */
|
||||
print_requires (packages, REQUIRE_INTERNAL);
|
||||
|
||||
Package *deppkg = reqtmp->data;
|
||||
RequiredVersion *req;
|
||||
|
||||
if (g_list_find (pkg->requires, reqtmp->data))
|
||||
continue;
|
||||
|
||||
req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
|
||||
if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
|
||||
printf ("%s\n", deppkg->key);
|
||||
else
|
||||
printf ("%s %s %s\n", deppkg->key,
|
||||
comparison_to_str(req->comparison),
|
||||
req->version);
|
||||
}
|
||||
}
|
||||
/* process Requires.private: */
|
||||
print_requires (packages, REQUIRE_PRIVATE);
|
||||
}
|
||||
|
||||
/* Print all flags; then print a newline at the end. */
|
||||
|
|
|
|||
36
parse.c
36
parse.c
|
|
@ -546,7 +546,7 @@ parse_requires (Package *pkg, const char *str, const char *path)
|
|||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
pkg->requires_entries = parse_module_list (pkg, trimmed, path);
|
||||
pkg->requires = parse_module_list (pkg, trimmed, path);
|
||||
g_free (trimmed);
|
||||
}
|
||||
|
||||
|
|
@ -565,7 +565,26 @@ parse_requires_private (Package *pkg, const char *str, const char *path)
|
|||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
pkg->requires_private_entries = parse_module_list (pkg, trimmed, path);
|
||||
pkg->requires_private = parse_module_list (pkg, trimmed, path);
|
||||
g_free (trimmed);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_requires_internal (Package *pkg, const char *str, const char *path)
|
||||
{
|
||||
char *trimmed;
|
||||
|
||||
if (pkg->requires_internal)
|
||||
{
|
||||
verbose_error ("Requires.internal field occurs twice in '%s'\n", path);
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
pkg->requires_internal = parse_module_list (pkg, trimmed, path);
|
||||
g_free (trimmed);
|
||||
}
|
||||
|
||||
|
|
@ -907,7 +926,8 @@ parse_url (Package *pkg, const char *str, const char *path)
|
|||
static void
|
||||
parse_line (Package *pkg, const char *untrimmed, const char *path,
|
||||
gboolean ignore_requires, gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private)
|
||||
gboolean ignore_requires_private,
|
||||
gboolean ignore_requires_internal)
|
||||
{
|
||||
char *str;
|
||||
char *p;
|
||||
|
|
@ -955,6 +975,11 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
|
|||
if (!ignore_requires_private)
|
||||
parse_requires_private (pkg, p, path);
|
||||
}
|
||||
else if (strcmp (tag, "Requires.internal") == 0)
|
||||
{
|
||||
if (!ignore_requires_internal)
|
||||
parse_requires_internal (pkg, p, path);
|
||||
}
|
||||
else if (strcmp (tag, "Requires") == 0)
|
||||
{
|
||||
if (ignore_requires == FALSE)
|
||||
|
|
@ -1089,7 +1114,8 @@ Package*
|
|||
parse_package_file (const char *key, const char *path,
|
||||
gboolean ignore_requires,
|
||||
gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private)
|
||||
gboolean ignore_requires_private,
|
||||
gboolean ignore_requires_internal)
|
||||
{
|
||||
FILE *f;
|
||||
Package *pkg;
|
||||
|
|
@ -1134,7 +1160,7 @@ parse_package_file (const char *key, const char *path,
|
|||
one_line = TRUE;
|
||||
|
||||
parse_line (pkg, str->str, path, ignore_requires, ignore_private_libs,
|
||||
ignore_requires_private);
|
||||
ignore_requires_private, ignore_requires_internal);
|
||||
|
||||
g_string_truncate (str, 0);
|
||||
}
|
||||
|
|
|
|||
3
parse.h
3
parse.h
|
|
@ -25,7 +25,8 @@
|
|||
Package *parse_package_file (const char *key, const char *path,
|
||||
gboolean ignore_requires,
|
||||
gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private);
|
||||
gboolean ignore_requires_private,
|
||||
gboolean ignore_requires_internal);
|
||||
|
||||
GList *parse_module_list (Package *pkg, const char *str, const char *path);
|
||||
|
||||
|
|
|
|||
|
|
@ -121,13 +121,23 @@ Libs: -L${libdir} -lfoo</pre>
|
|||
|
||||
<li><b>Requires</b>: A list of packages required by this package. The
|
||||
versions of these packages may be specified using the comparison operators
|
||||
=, <, >, <= or >=.</li>
|
||||
=, <, >, <= or >=. This is to be used when an application
|
||||
using this package will have to use symbols and APIs from a dependent
|
||||
library. </li>
|
||||
|
||||
<li><b>Requires.private</b>: A list of private packages required by this
|
||||
package but not exposed to applications. The version specific rules from
|
||||
the <tt>Requires</tt> field also apply here.</li>
|
||||
the <tt>Requires</tt> field also apply here. This is to be used when an
|
||||
application using this package needs header files from a dependent library
|
||||
but is not likely to call any of their symbols.</li>
|
||||
|
||||
<li><b>Conflicts</b>: An optional field describing packages that this one
|
||||
<li><b>Requires.internal</b>: A list of internal packages required by this
|
||||
package but not exposed to applications. The version specific rules from
|
||||
the <tt>Requires</tt> field also apply here. This is to be used when
|
||||
this package uses a library as internal implementation detail but is not
|
||||
exposed neither in its API nor ABI.</li>
|
||||
|
||||
<li><b>Conflicts</b>: An op tional field describing packages that this one
|
||||
conflicts with. The version specific rules from the <tt>Requires</tt>
|
||||
field also apply here. This field also takes multiple instances of the
|
||||
same package. E.g., <tt>Conflicts: bar < 1.2.3, bar >= 1.3.0</tt>.</li>
|
||||
|
|
@ -186,25 +196,25 @@ includedir=${prefix}/include
|
|||
Cflags: -I${includedir}/foo</pre>
|
||||
|
||||
<p>The most important <tt>pkg-config</tt> metadata fields are
|
||||
<tt>Requires</tt>, <tt>Requires.private</tt>, <tt>Cflags</tt>, <tt>Libs</tt>
|
||||
and <tt>Libs.private</tt>. They will define the metadata used by external
|
||||
projects to compile and link with the library.</p>
|
||||
<tt>Requires</tt>, <tt>Requires.private</tt>, <tt>Requires.internal</tt>,
|
||||
<tt>Cflags</tt>, <tt>Libs</tt> and <tt>Libs.private</tt>. They will define
|
||||
the metadata used by external projects to compile and link with the library.</p>
|
||||
|
||||
<p><tt>Requires</tt> and <tt>Requires.private</tt> define other modules
|
||||
needed by the library. It is usually preferred to use the private variant of
|
||||
<tt>Requires</tt> to avoid exposing unnecessary libraries to the program
|
||||
that is linking with your library. If the program will not be using the
|
||||
symbols of the required library, it should not be linking directly to that
|
||||
library. See the discussion of
|
||||
<p><tt>Requires</tt>, <tt>Requires.private</tt> and <tt>Requires.internal</tt>
|
||||
define other modules needed by the library. It is usually preferred to use the
|
||||
private variant of <tt>Requires</tt> to avoid exposing unnecessary libraries
|
||||
to the program that is linking with your library. If the program will not be
|
||||
using the symbols of the required library, it should not be linking directly
|
||||
to that library. See the discussion of
|
||||
<a href="https://wiki.openmandriva.org/en/Overlinking_issues_in_packaging">overlinking</a>
|
||||
for a more thorough explanation.</p>
|
||||
|
||||
<p>Since <tt>pkg-config</tt> always exposes the link flags of the
|
||||
<tt>Requires</tt> libraries, these modules will become direct dependencies
|
||||
of the program. On the other hand, libraries from <tt>Requires.private</tt>
|
||||
will only be included when static linking. For this reason, it is usually
|
||||
only appropriate to add modules from the same package in <tt>Requires</tt>.
|
||||
</p>
|
||||
and <tt>Requires.internal</tt> will only be included when static linking. For
|
||||
this reason, it is usually only appropriate to add modules from the same
|
||||
package in <tt>Requires</tt>.</p>
|
||||
|
||||
<p>The <tt>Libs</tt> field contains the link flags necessary to use that
|
||||
library. In addition, <tt>Libs</tt> and <tt>Libs.private</tt> contain link
|
||||
|
|
@ -404,10 +414,10 @@ myapp_LDADD = $(X_LIBS)</pre>
|
|||
expose <tt>libx</tt> data types in its public API. What do I put in my
|
||||
<tt>z.pc</tt> file?</li>
|
||||
|
||||
<p>Again, add the module to <tt>Requires.private</tt> if it supports
|
||||
<tt>pkg-config</tt>. In this case, the compiler flags will be emitted
|
||||
unnecessarily, but it ensures that the linker flags will be present when
|
||||
linking statically. If <tt>libx</tt> does not support <tt>pkg-config</tt>,
|
||||
<p>Add the module to <tt>Requires.internal</tt> if it supports
|
||||
<tt>pkg-config</tt>. Unlike <tt>Requires.private</tt> the compiler flags
|
||||
will not be emitted, but it ensures that the linker flags will be present
|
||||
when linking statically. If <tt>libx</tt> does not support <tt>pkg-config</tt>,
|
||||
add the necessary linker flags to <tt>Libs.private</tt>.</p>
|
||||
</ol>
|
||||
|
||||
|
|
|
|||
215
pkg.c
215
pkg.c
|
|
@ -49,6 +49,7 @@ static GList *search_dirs = NULL;
|
|||
gboolean disable_uninstalled = FALSE;
|
||||
gboolean ignore_requires = FALSE;
|
||||
gboolean ignore_requires_private = TRUE;
|
||||
gboolean ignore_requires_internal = TRUE;
|
||||
gboolean ignore_private_libs = TRUE;
|
||||
|
||||
void
|
||||
|
|
@ -219,6 +220,24 @@ package_init (gboolean want_list)
|
|||
add_virtual_pkgconfig_package ();
|
||||
}
|
||||
|
||||
static void
|
||||
internal_get_package_foreach (gpointer data, gpointer user_data)
|
||||
{
|
||||
gboolean warn = GPOINTER_TO_INT (user_data);
|
||||
RequiredVersion *ver = data;
|
||||
Package *pkg = ver->owner;
|
||||
|
||||
debug_spew ("Searching for '%s' requirement '%s'\n",
|
||||
pkg->key, ver->name);
|
||||
ver->package = internal_get_package (ver->name, warn);
|
||||
if (ver->package == NULL)
|
||||
{
|
||||
verbose_error ("Package '%s', required by '%s', not found\n",
|
||||
ver->name, pkg->key);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static Package *
|
||||
internal_get_package (const char *name, gboolean warn)
|
||||
{
|
||||
|
|
@ -226,7 +245,6 @@ internal_get_package (const char *name, gboolean warn)
|
|||
char *key = NULL;
|
||||
char *location = NULL;
|
||||
unsigned int path_position = 0;
|
||||
GList *iter;
|
||||
GList *dir_iter;
|
||||
|
||||
pkg = g_hash_table_lookup (packages, name);
|
||||
|
|
@ -300,7 +318,8 @@ internal_get_package (const char *name, gboolean warn)
|
|||
|
||||
debug_spew ("Reading '%s' from file '%s'\n", name, location);
|
||||
pkg = parse_package_file (key, location, ignore_requires,
|
||||
ignore_private_libs, ignore_requires_private);
|
||||
ignore_private_libs, ignore_requires_private,
|
||||
ignore_requires_internal);
|
||||
g_free (key);
|
||||
|
||||
if (pkg != NULL && strstr (location, "uninstalled.pc"))
|
||||
|
|
@ -323,58 +342,15 @@ internal_get_package (const char *name, gboolean warn)
|
|||
g_hash_table_insert (packages, pkg->key, pkg);
|
||||
|
||||
/* pull in Requires packages */
|
||||
for (iter = pkg->requires_entries; iter != NULL; iter = g_list_next (iter))
|
||||
{
|
||||
Package *req;
|
||||
RequiredVersion *ver = iter->data;
|
||||
|
||||
debug_spew ("Searching for '%s' requirement '%s'\n",
|
||||
pkg->key, ver->name);
|
||||
req = internal_get_package (ver->name, warn);
|
||||
if (req == NULL)
|
||||
{
|
||||
verbose_error ("Package '%s', required by '%s', not found\n",
|
||||
ver->name, pkg->key);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (pkg->required_versions == NULL)
|
||||
pkg->required_versions = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert (pkg->required_versions, ver->name, ver);
|
||||
pkg->requires = g_list_prepend (pkg->requires, req);
|
||||
}
|
||||
|
||||
/* pull in Requires.private packages */
|
||||
for (iter = pkg->requires_private_entries; iter != NULL;
|
||||
iter = g_list_next (iter))
|
||||
{
|
||||
Package *req;
|
||||
RequiredVersion *ver = iter->data;
|
||||
|
||||
debug_spew ("Searching for '%s' private requirement '%s'\n",
|
||||
pkg->key, ver->name);
|
||||
req = internal_get_package (ver->name, warn);
|
||||
if (req == NULL)
|
||||
{
|
||||
verbose_error ("Package '%s', required by '%s', not found\n",
|
||||
ver->name, pkg->key);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (pkg->required_versions == NULL)
|
||||
pkg->required_versions = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert (pkg->required_versions, ver->name, ver);
|
||||
pkg->requires_private = g_list_prepend (pkg->requires_private, req);
|
||||
}
|
||||
|
||||
/* make requires_private include a copy of the public requires too */
|
||||
pkg->requires_private = g_list_concat (g_list_copy (pkg->requires),
|
||||
pkg->requires_private);
|
||||
|
||||
pkg->requires = g_list_reverse (pkg->requires);
|
||||
pkg->requires_private = g_list_reverse (pkg->requires_private);
|
||||
g_list_foreach (pkg->requires,
|
||||
internal_get_package_foreach,
|
||||
GINT_TO_POINTER (warn));
|
||||
g_list_foreach (pkg->requires_private,
|
||||
internal_get_package_foreach,
|
||||
GINT_TO_POINTER (warn));
|
||||
g_list_foreach (pkg->requires_internal,
|
||||
internal_get_package_foreach,
|
||||
GINT_TO_POINTER (warn));
|
||||
|
||||
verify_package (pkg);
|
||||
|
||||
|
|
@ -510,10 +486,15 @@ packages_sort_by_path_position (GList *list)
|
|||
* any package that it depends on.
|
||||
*/
|
||||
static void
|
||||
recursive_fill_list (Package *pkg, gboolean include_private,
|
||||
recursive_fill_list (Package *pkg, gboolean include_private, FlagType flags,
|
||||
GHashTable *visited, GList **listp)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *lists[N_REQUIRE_TYPES] = {
|
||||
pkg->requires,
|
||||
pkg->requires_private,
|
||||
pkg->requires_internal,
|
||||
};
|
||||
gint type;
|
||||
|
||||
/*
|
||||
* If the package has already been visited, then it is already in 'listp' and
|
||||
|
|
@ -532,11 +513,44 @@ recursive_fill_list (Package *pkg, gboolean include_private,
|
|||
g_hash_table_replace (visited, pkg->key, pkg->key);
|
||||
}
|
||||
|
||||
/* Start from the end of the required package list to maintain order since
|
||||
* the recursive list is built by prepending. */
|
||||
tmp = include_private ? pkg->requires_private : pkg->requires;
|
||||
for (tmp = g_list_last (tmp); tmp != NULL; tmp = g_list_previous (tmp))
|
||||
recursive_fill_list (tmp->data, include_private, visited, listp);
|
||||
for (type = 0; type < N_REQUIRE_TYPES; type++)
|
||||
{
|
||||
GList *iter;
|
||||
FlagType new_flags;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case REQUIRE:
|
||||
new_flags = flags;
|
||||
break;
|
||||
|
||||
case REQUIRE_PRIVATE:
|
||||
/* When we don't include private libs we still want to pull Cflags
|
||||
* from Require.private.
|
||||
* See https://bugs.freedesktop.org/show_bug.cgi?id=105572 */
|
||||
new_flags = include_private ? flags : flags & CFLAGS_ANY;
|
||||
break;
|
||||
|
||||
case REQUIRE_INTERNAL:
|
||||
/* Only pull Libs from Require.internal if we include private libs.
|
||||
* Don't pull anything otherwise.
|
||||
* See https://bugs.freedesktop.org/show_bug.cgi?id=105572 */
|
||||
new_flags = include_private ? flags & LIBS_ANY : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_flags == 0)
|
||||
continue;
|
||||
|
||||
/* Start from the end of the required package list to maintain order since
|
||||
* the recursive list is built by prepending. */
|
||||
for (iter = g_list_last (lists[type]); iter != NULL; iter = g_list_previous (iter))
|
||||
{
|
||||
RequiredVersion *ver = iter->data;
|
||||
if (ver->package != NULL)
|
||||
recursive_fill_list (ver->package, include_private, new_flags, visited, listp);
|
||||
}
|
||||
}
|
||||
|
||||
*listp = g_list_prepend (*listp, pkg);
|
||||
}
|
||||
|
|
@ -588,7 +602,7 @@ fill_list (GList *packages, FlagType type,
|
|||
* the recursive list is built by prepending. */
|
||||
visited = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
for (tmp = g_list_last (packages); tmp != NULL; tmp = g_list_previous (tmp))
|
||||
recursive_fill_list (tmp->data, include_private, visited, &expanded);
|
||||
recursive_fill_list (tmp->data, include_private, type, visited, &expanded);
|
||||
g_hash_table_destroy (visited);
|
||||
spew_package_list ("post-recurse", expanded);
|
||||
|
||||
|
|
@ -640,6 +654,29 @@ static const gchar *msvc_include_envvars[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
verify_version_foreach (gpointer data, gpointer user_data)
|
||||
{
|
||||
RequiredVersion *ver = data;
|
||||
Package *req = ver->package;
|
||||
Package *pkg = ver->owner;
|
||||
|
||||
if (!version_test (ver->comparison, req->version, ver->version))
|
||||
{
|
||||
verbose_error ("Package '%s' requires '%s %s %s' but version of %s is %s\n",
|
||||
pkg->key, req->key,
|
||||
comparison_to_str (ver->comparison),
|
||||
ver->version,
|
||||
req->key,
|
||||
req->version);
|
||||
if (req->url)
|
||||
verbose_error ("You may find new versions of %s at %s\n",
|
||||
req->name, req->url);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
verify_package (Package *pkg)
|
||||
{
|
||||
|
|
@ -687,44 +724,15 @@ verify_package (Package *pkg)
|
|||
}
|
||||
|
||||
/* Make sure we have the right version for all requirements */
|
||||
|
||||
iter = pkg->requires_private;
|
||||
|
||||
while (iter != NULL)
|
||||
{
|
||||
Package *req = iter->data;
|
||||
RequiredVersion *ver = NULL;
|
||||
|
||||
if (pkg->required_versions)
|
||||
ver = g_hash_table_lookup (pkg->required_versions,
|
||||
req->key);
|
||||
|
||||
if (ver)
|
||||
{
|
||||
if (!version_test (ver->comparison, req->version, ver->version))
|
||||
{
|
||||
verbose_error ("Package '%s' requires '%s %s %s' but version of %s is %s\n",
|
||||
pkg->key, req->key,
|
||||
comparison_to_str (ver->comparison),
|
||||
ver->version,
|
||||
req->key,
|
||||
req->version);
|
||||
if (req->url)
|
||||
verbose_error ("You may find new versions of %s at %s\n",
|
||||
req->name, req->url);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
iter = g_list_next (iter);
|
||||
}
|
||||
g_list_foreach (pkg->requires, verify_version_foreach, NULL);
|
||||
g_list_foreach (pkg->requires_private, verify_version_foreach, NULL);
|
||||
g_list_foreach (pkg->requires_internal, verify_version_foreach, NULL);
|
||||
|
||||
/* Make sure we didn't drag in any conflicts via Requires
|
||||
* (inefficient algorithm, who cares)
|
||||
*/
|
||||
visited = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
recursive_fill_list (pkg, TRUE, visited, &requires);
|
||||
recursive_fill_list (pkg, TRUE, FLAGS_ANY, visited, &requires);
|
||||
g_hash_table_destroy (visited);
|
||||
conflicts = pkg->conflicts;
|
||||
|
||||
|
|
@ -936,14 +944,14 @@ packages_get_flags (GList *pkgs, FlagType flags)
|
|||
/* sort packages in path order for -L/-I, dependency order otherwise */
|
||||
if (flags & CFLAGS_OTHER)
|
||||
{
|
||||
cur = get_multi_merged (pkgs, CFLAGS_OTHER, FALSE, TRUE);
|
||||
cur = get_multi_merged (pkgs, CFLAGS_OTHER, FALSE, !ignore_private_libs);
|
||||
debug_spew ("adding CFLAGS_OTHER string \"%s\"\n", cur);
|
||||
g_string_append (str, cur);
|
||||
g_free (cur);
|
||||
}
|
||||
if (flags & CFLAGS_I)
|
||||
{
|
||||
cur = get_multi_merged (pkgs, CFLAGS_I, TRUE, TRUE);
|
||||
cur = get_multi_merged (pkgs, CFLAGS_I, TRUE, !ignore_private_libs);
|
||||
debug_spew ("adding CFLAGS_I string \"%s\"\n", cur);
|
||||
g_string_append (str, cur);
|
||||
g_free (cur);
|
||||
|
|
@ -1181,6 +1189,7 @@ print_package_list (void)
|
|||
|
||||
ignore_requires = TRUE;
|
||||
ignore_requires_private = TRUE;
|
||||
ignore_requires_internal = TRUE;
|
||||
|
||||
/* Add the packages to a pointer array and sort by pkg->key first, to give
|
||||
* deterministic output. While doing that, work out the maximum key length
|
||||
|
|
@ -1246,3 +1255,15 @@ disable_requires_private(void)
|
|||
{
|
||||
ignore_requires_private = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
enable_requires_internal(void)
|
||||
{
|
||||
ignore_requires_internal = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
disable_requires_internal(void)
|
||||
{
|
||||
ignore_requires_internal = TRUE;
|
||||
}
|
||||
|
|
|
|||
19
pkg.h
19
pkg.h
|
|
@ -55,12 +55,21 @@ struct Flag_
|
|||
char *arg;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
REQUIRE,
|
||||
REQUIRE_PRIVATE,
|
||||
REQUIRE_INTERNAL,
|
||||
N_REQUIRE_TYPES
|
||||
} RequireType;
|
||||
|
||||
struct RequiredVersion_
|
||||
{
|
||||
char *name;
|
||||
ComparisonType comparison;
|
||||
char *version;
|
||||
Package *owner;
|
||||
Package *package;
|
||||
};
|
||||
|
||||
struct Package_
|
||||
|
|
@ -71,14 +80,12 @@ struct Package_
|
|||
char *description;
|
||||
char *url;
|
||||
char *pcfiledir; /* directory it was loaded from */
|
||||
GList *requires_entries;
|
||||
GList *requires;
|
||||
GList *requires_private_entries;
|
||||
GList *requires_private;
|
||||
GList *requires; /* list of RequiredVersion */
|
||||
GList *requires_private; /* list of RequiredVersion */
|
||||
GList *requires_internal; /* list of RequiredVersion */
|
||||
GList *libs;
|
||||
GList *cflags;
|
||||
GHashTable *vars;
|
||||
GHashTable *required_versions; /* hash from name to RequiredVersion */
|
||||
GList *conflicts; /* list of RequiredVersion */
|
||||
gboolean uninstalled; /* used the -uninstalled file */
|
||||
int path_position; /* used to order packages by position in path of their .pc file, lower number means earlier in path */
|
||||
|
|
@ -122,6 +129,8 @@ void enable_requires(void);
|
|||
void disable_requires(void);
|
||||
void enable_requires_private(void);
|
||||
void disable_requires_private(void);
|
||||
void enable_requires_internal(void);
|
||||
void disable_requires_internal(void);
|
||||
|
||||
/* If TRUE, do not automatically prefer uninstalled versions */
|
||||
extern gboolean disable_uninstalled;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue