Add Require.internal field

This field is to be used for purely internal dependencies that are not
exposed into the API at all. Those packages are there only for static
link.

https://bugs.freedesktop.org/show_bug.cgi?id=105572
This commit is contained in:
Xavier Claessens 2018-03-18 15:34:57 -04:00
parent b8bcd4f749
commit 43cd3e7a02
4 changed files with 92 additions and 19 deletions

17
main.c
View file

@ -483,7 +483,7 @@ static const GOptionEntry options_table[] = {
};
static void
print_requires (GList *packages, gboolean private)
print_requires (GList *packages, RequireType type)
{
GList *pkgtmp;
for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
@ -491,7 +491,13 @@ print_requires (GList *packages, gboolean private)
Package *pkg = pkgtmp->data;
GList *reqtmp;
reqtmp = private ? pkg->requires_private : pkg->requires;
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;
@ -788,12 +794,15 @@ main (int argc, char **argv)
if (want_requires)
{
/* process Requires: */
print_requires (packages, FALSE);
print_requires (packages, REQUIRE);
}
if (want_requires_private)
{
/* process Requires.internal: */
print_requires (packages, REQUIRE_INTERNAL);
/* process Requires.private: */
print_requires (packages, TRUE);
print_requires (packages, REQUIRE_PRIVATE);
}
/* Print all flags; then print a newline at the end. */

24
parse.c
View file

@ -569,6 +569,25 @@ parse_requires_private (Package *pkg, const char *str, const char *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);
}
static void
parse_conflicts (Package *pkg, const char *str, const char *path)
{
@ -955,6 +974,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_private)
parse_requires_internal (pkg, p, path);
}
else if (strcmp (tag, "Requires") == 0)
{
if (ignore_requires == FALSE)

61
pkg.c
View file

@ -346,6 +346,9 @@ internal_get_package (const char *name, gboolean 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);
@ -481,11 +484,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 *lists[2];
guint i, nlists;
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
@ -504,19 +511,42 @@ 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. */
lists[0] = pkg->requires;
lists[1] = pkg->requires_private;
nlists = include_private ? 2 : 1;
for (i = 0; i < nlists; i++)
for (type = 0; type < N_REQUIRE_TYPES; type++)
{
GList *iter;
for (iter = g_list_last (lists[i]); iter != NULL; iter = g_list_previous (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, visited, listp);
recursive_fill_list (ver->package, include_private, new_flags, visited, listp);
}
}
@ -570,7 +600,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);
@ -694,12 +724,13 @@ verify_package (Package *pkg)
/* Make sure we have the right version for all requirements */
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;
@ -911,14 +942,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);

9
pkg.h
View file

@ -55,6 +55,14 @@ struct Flag_
char *arg;
};
typedef enum
{
REQUIRE,
REQUIRE_PRIVATE,
REQUIRE_INTERNAL,
N_REQUIRE_TYPES
} RequireType;
struct RequiredVersion_
{
char *name;
@ -74,6 +82,7 @@ struct Package_
char *pcfiledir; /* directory it was loaded from */
GList *requires; /* list of RequiredVersion */
GList *requires_private; /* list of RequiredVersion */
GList *requires_internal; /* list of RequiredVersion */
GList *libs;
GList *cflags;
GHashTable *vars;