From 9a6c72edca81d66ce2842f97b60b5663975dd409 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Mon, 21 Nov 2022 10:20:51 +0100 Subject: [PATCH] pkg: reintroduce less aggressive flags deduplication Stripping non-consecutives options was dropped in 9adfd9ebfcb8a, in order to prevent the alteration of the command semantics. To mitigate cases when the generated flags list is too long, the deduplication is reintroduced but limited only to a few cases (-L, -l, -I) for which semantics is not altered by a repetition of the same flag. Address issue: https://gitlab.freedesktop.org/pkg-config/pkg-config/-/issues/75 --- check/check-duplicate-flags | 2 +- check/check-gtk | 12 ++++++------ pkg.c | 39 ++++++++++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/check/check-duplicate-flags b/check/check-duplicate-flags index 110da5b..5d00b3a 100755 --- a/check/check-duplicate-flags +++ b/check/check-duplicate-flags @@ -9,7 +9,7 @@ run_test --cflags flag-dup-1 flag-dup-2 run_test --cflags flag-dup-2 flag-dup-1 RESULT="-L/path/lib -lpath2 -Wl,--whole-archive -lm --Wl,--no-whole-archive \ --Xlinker -R -Xlinker /path/lib -lpath1 -Wl,--whole-archive -lm \ +-Xlinker -R -Xlinker /path/lib -lpath1 -Wl,--whole-archive \ --Wl,--no-whole-archive -Xlinker -R -Xlinker /path/lib" run_test --libs flag-dup-1 flag-dup-2 run_test --libs flag-dup-2 flag-dup-1 diff --git a/check/check-gtk b/check/check-gtk index 7fd01bb..91bb014 100755 --- a/check/check-gtk +++ b/check/check-gtk @@ -16,8 +16,7 @@ PKG_CONFIG_LIBDIR=${srcdir}/gtk RESULT="-DGSEAL_ENABLE -pthread -I/gtk/include/gtk-3.0 \ -I/gtk/include/pango-1.0 -I/gtk/include/atk-1.0 -I/gtk/include/cairo \ -I/gtk/include/pixman-1 -I/gtk/include -I/gtk/include/gdk-pixbuf-2.0 \ --I/gtk/include -I/gtk/include/pango-1.0 -I/gtk/include/glib-2.0 \ --I/gtk/lib/glib-2.0/include -I/gtk/include/freetype2 -I/gtk/include" +-I/gtk/include/glib-2.0 -I/gtk/lib/glib-2.0/include -I/gtk/include/freetype2" run_test --cflags gtk+-3.0 run_test --cflags --static gtk+-3.0 @@ -29,8 +28,9 @@ run_test --cflags --static gtk+-3.0 # -lglib-2.0 RESULT="-L/gtk/lib -lgtk-3 -lgdk-3 -lpangocairo-1.0 -latk-1.0 -lcairo-gobject \ -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 \ --lgthread-2.0 -pthread -lrt -lgmodule-2.0 -pthread -lrt -lglib-2.0 -lfreetype \ +-lgthread-2.0 -pthread -lrt -lgmodule-2.0 -pthread -lglib-2.0 -lfreetype \ -lfontconfig" + if [ "$list_indirect_deps" = no ]; then run_test --libs gtk+-3.0 fi @@ -49,10 +49,10 @@ fi # -lpango-1.0 -lfontconfig -lexpat -lfreetype -lgobject-2.0 -lffi \ # -lgmodule-2.0 -ldl -lgthread-2.0 -lglib-2.0 -lrt RESULT="-L/gtk/lib -lgtk-3 -lgdk-3 -lpangocairo-1.0 -latk-1.0 -lcairo-gobject \ --lcairo -lz -lpixman-1 -lpng12 -lz -lm -lXrender -lX11 -lpthread -lxcb -lXau \ --lgdk_pixbuf-2.0 -lm -lpng12 -lz -lm -lgio-2.0 -lz -lresolv -lpangoft2-1.0 \ +-lcairo -lz -lpixman-1 -lpng12 -lm -lXrender -lX11 -lpthread -lxcb -lXau \ +-lgdk_pixbuf-2.0 -lgio-2.0 -lresolv -lpangoft2-1.0 \ -lpango-1.0 -lgobject-2.0 -lffi -lgthread-2.0 -pthread -lrt -lgmodule-2.0 \ --pthread -lrt -ldl -lglib-2.0 -lrt -lfreetype -lfontconfig -lexpat -lfreetype" +-pthread -ldl -lglib-2.0 -lfreetype -lfontconfig -lexpat" if [ "$list_indirect_deps" = yes ]; then run_test --libs gtk+-3.0 fi diff --git a/pkg.c b/pkg.c index 337dbfa..987746e 100644 --- a/pkg.c +++ b/pkg.c @@ -393,30 +393,55 @@ get_package_quiet (const char *name) return internal_get_package (name, FALSE); } +#define SAFE_DEDUPLICABLE_FLAGS "LlI" + /* Strip consecutive duplicate arguments in the flag list. */ static GList * flag_list_strip_duplicates (GList *list) { + GHashTable *table; GList *tmp; - /* Start at the 2nd element of the list so we don't have to check for an - * existing previous element. */ - for (tmp = g_list_next (list); tmp != NULL; tmp = g_list_next (tmp)) + table = g_hash_table_new (g_str_hash, g_str_equal); + for (tmp = list; tmp != NULL; tmp = g_list_next (tmp)) { - Flag *cur = tmp->data; - Flag *prev = tmp->prev->data; + Flag *flag = tmp->data; + Flag *prev_flag = tmp->prev ? tmp->prev->data : NULL; + gboolean remove = FALSE; - if (cur->type == prev->type && g_strcmp0 (cur->arg, prev->arg) == 0) + debug_spew ("Seeing if arg %s is duplicate\n", flag->arg); + + if (prev_flag && flag->type == prev_flag->type && + g_strcmp0 (flag->arg, prev_flag->arg) == 0) + { + remove = TRUE; + } + else if (flag->arg[0] != '-' || !strchr(SAFE_DEDUPLICABLE_FLAGS, flag->arg[1])) + { + debug_spew ("arg %s cannot be safely de-duplicated\n", flag->arg); + } + else if (!g_hash_table_lookup_extended (table, flag->arg, NULL, NULL)) + { + /* Unique flag. Track it and and move to the next. */ + g_hash_table_replace (table, flag->arg, flag->arg); + } + else + { + remove = TRUE; + } + + if (remove) { /* Remove the duplicate flag from the list and move to the last * element to prepare for the next iteration. */ GList *dup = tmp; - debug_spew (" removing duplicate \"%s\"\n", cur->arg); + debug_spew (" removing duplicate \"%s\"\n", flag->arg); tmp = g_list_previous (tmp); list = g_list_remove_link (list, dup); } } + g_hash_table_destroy (table); return list; }