From 43cd3e7a02f2a6d5f2aa204ed1867da877782e03 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Sun, 18 Mar 2018 15:34:57 -0400 Subject: [PATCH 2/2] 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 --- main.c | 17 +++++++++++++---- parse.c | 24 ++++++++++++++++++++++++ pkg.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++--------------- pkg.h | 9 +++++++++ 4 files changed, 92 insertions(+), 19 deletions(-) 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; -- 2.14.1