diff --git a/main.c b/main.c index 5e95d18..6ed8aba 100644 --- a/main.c +++ b/main.c @@ -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. */ diff --git a/parse.c b/parse.c index c96305b..02a4cf3 100644 --- a/parse.c +++ b/parse.c @@ -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) diff --git a/pkg.c b/pkg.c index e3e5830..47725d6 100644 --- a/pkg.c +++ b/pkg.c @@ -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); diff --git a/pkg.h b/pkg.h index 6373d9c..584a6e2 100644 --- a/pkg.h +++ b/pkg.h @@ -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;