Merge branch 'requires-internal' into 'master'

Add Require.internal field

See merge request pkg-config/pkg-config!8
This commit is contained in:
Xavier Claessens 2021-02-04 00:40:05 +00:00
commit 585e0cc6b9
12 changed files with 263 additions and 177 deletions

View file

@ -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

View file

@ -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
View 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

View 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

View file

@ -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

View file

@ -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
View file

@ -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
View file

@ -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);
}

View file

@ -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);

View file

@ -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
=, &lt;, &gt;, &lt;= or &gt;=.</li>
=, &lt;, &gt;, &lt;= or &gt;=. 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
View file

@ -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
View file

@ -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;