Index: main.c --- main.c.orig 2012-07-11 14:24:23.000000000 +0200 +++ main.c 2012-07-12 08:29:20.000000000 +0200 @@ -204,7 +204,8 @@ static int want_I_cflags = 0; static int want_other_cflags = 0; static int want_list = 0; - static int want_static_lib_list = ENABLE_INDIRECT_DEPS; + static int want_static_lib_list = 0; + static int want_shared_lib_list = 0; static int want_short_errors = 0; static int want_uninstalled = 0; static char *variable_name = NULL; @@ -238,7 +239,9 @@ { "libs", 0, 0, G_OPTION_ARG_NONE, &want_libs, "output all linker flags", NULL }, { "static", 0, 0, G_OPTION_ARG_NONE, &want_static_lib_list, - "output linker flags for static linking", NULL }, + "output explicit linker flags for static linking", NULL }, + { "shared", 0, 0, G_OPTION_ARG_NONE, &want_shared_lib_list, + "output implicit linker flags for dynamic linking", NULL }, { "short-errors", 0, 0, G_OPTION_ARG_NONE, &want_short_errors, "print short errors", NULL }, { "libs-only-l", 0, 0, G_OPTION_ARG_NONE, &want_l_libs, @@ -415,6 +418,17 @@ else debug_spew ("Error printing disabled\n"); + /************************************************************************* + * if user explicitly specified only --static, then recurse. * + * if user explicitly specified both --static and --shared, then recurse. * + * * + * ...but if user did not explicitly specify either argument, then * + * obey the default logic as defined by ENABLE_INDIRECT_DEPS (as set * + * by the configure script with the --enable-indirect-deps argument). * + *************************************************************************/ + if (!want_static_lib_list && !want_shared_lib_list) + want_static_lib_list = ENABLE_INDIRECT_DEPS; + if (want_static_lib_list) enable_private_libs(); else @@ -740,7 +754,7 @@ if (want_l_libs) { - char *str = packages_get_l_libs (packages); + char *str = packages_get_l_libs (packages, want_static_lib_list); printf ("%s ", str); g_free (str); need_newline = TRUE; @@ -754,14 +768,14 @@ } else if (want_other_libs) { - char *str = packages_get_other_libs (packages); + char *str = packages_get_other_libs (packages, want_static_lib_list); printf ("%s ", str); g_free (str); need_newline = TRUE; } else if (want_libs) { - char *str = packages_get_all_libs (packages); + char *str = packages_get_all_libs (packages, want_static_lib_list); printf ("%s ", str); g_free (str); need_newline = TRUE; Index: pkg.c --- pkg.c.orig 2012-05-30 14:49:24.000000000 +0200 +++ pkg.c 2012-07-12 08:27:29.000000000 +0200 @@ -439,6 +439,58 @@ return nodups; } +static GSList* +string_list_strip_duplicates_from_middle (GSList *list) +{ + GHashTable *table_first; + GHashTable *table_last; + GList *dlist; + GList *dlelem; + GSList *slist; + GSList *selem; + + /* shuffle from single-linked list to double-linked list + in order to be able to go both forward and backward while + still having the element (not its data) as the identifier */ + dlist = NULL; + for (selem = list; selem != NULL; selem = g_slist_next(selem)) + dlist = g_list_prepend(dlist, selem->data); + dlist = g_list_reverse(dlist); + + /* determine first and last elements */ + table_first = g_hash_table_new (g_str_hash, g_str_equal); + table_last = g_hash_table_new (g_str_hash, g_str_equal); + for (dlelem = dlist; dlelem != NULL; dlelem = g_list_next(dlelem)) { + if (g_hash_table_lookup(table_first, dlelem->data) == NULL) + g_hash_table_insert(table_first, dlelem->data, dlelem); + } + for (dlelem = g_list_last(dlist); dlelem != NULL; dlelem = g_list_previous(dlelem)) { + if (g_hash_table_lookup(table_last, dlelem->data) == NULL) + g_hash_table_insert(table_last, dlelem->data, dlelem); + } + + /* remove duplicates */ + slist = NULL; + for (dlelem = dlist; dlelem != NULL; dlelem = g_list_next(dlelem)) { + if ( g_hash_table_lookup(table_first, dlelem->data) == dlelem + || g_hash_table_lookup(table_last, dlelem->data) == dlelem) { + slist = g_slist_append(slist, dlelem->data); + debug_spew("<%s>: TAKE\n", (char *)dlelem->data); + } + else { + debug_spew ("<%s>: REMOVE\n", (char *)dlelem->data); + // debug_spew (" removing duplicate (from middle) \"%s\"\n", dlelem->data); + } + } + + /* cleanup intermediate data structures */ + g_hash_table_destroy(table_first); + g_hash_table_destroy(table_last); + g_list_free(dlist); + + return slist; +} + static char * string_list_to_string (GSList *list) { @@ -974,6 +1026,28 @@ } static char* +get_merged_from_middle (Package *pkg, GetListFunc func, gboolean in_path_order, + gboolean include_private) +{ + GSList *list; + GSList *dups_list = NULL; + char *retval; + + fill_list_single_package (pkg, func, &dups_list, in_path_order, + include_private); + + list = string_list_strip_duplicates_from_middle (dups_list); + + g_slist_free (dups_list); + + retval = string_list_to_string (list); + + g_slist_free (list); + + return retval; +} + +static char* get_multi_merged (GSList *pkgs, GetListFunc func, gboolean in_path_order, gboolean include_private) { @@ -1015,13 +1089,39 @@ return retval; } +static char* +get_multi_merged_from_middle (GSList *pkgs, GetListFunc func, + gboolean in_path_order, gboolean include_private) +{ + GSList *tmp; + GSList *dups_list = NULL; + GSList *list; + char *retval; + + fill_list (pkgs, func, &dups_list, in_path_order, include_private); + + list = string_list_strip_duplicates_from_middle (dups_list); + + g_slist_free (dups_list); + + retval = string_list_to_string (list); + + g_slist_free (list); + + return retval; +} + char * -package_get_l_libs (Package *pkg) +package_get_l_libs (Package *pkg, int want_static_lib_list) { /* We don't want these in search path order, rather in dependency * order, so static linking works. */ if (pkg->l_libs_merged == NULL) + if (want_static_lib_list) + pkg->l_libs_merged = get_merged_from_middle (pkg, get_l_libs, FALSE, + !ignore_private_libs); + else pkg->l_libs_merged = get_merged_from_back (pkg, get_l_libs, FALSE, !ignore_private_libs); @@ -1029,8 +1129,12 @@ } char * -packages_get_l_libs (GSList *pkgs) +packages_get_l_libs (GSList *pkgs, int want_static_lib_list) { + if (want_static_lib_list) + return get_multi_merged_from_middle (pkgs, get_l_libs, FALSE, + !ignore_private_libs); + else return get_multi_merged_from_back (pkgs, get_l_libs, FALSE, !ignore_private_libs); } @@ -1053,9 +1157,13 @@ } char * -package_get_other_libs (Package *pkg) +package_get_other_libs (Package *pkg, int want_static_lib_list) { if (pkg->other_libs_merged == NULL) + if (want_static_lib_list) + pkg->other_libs_merged = get_merged_from_middle (pkg, get_other_libs, TRUE, + !ignore_private_libs); + else pkg->other_libs_merged = get_merged (pkg, get_other_libs, TRUE, !ignore_private_libs); @@ -1063,13 +1171,16 @@ } char * -packages_get_other_libs (GSList *pkgs) +packages_get_other_libs (GSList *pkgs, int want_static_lib_list) { + if (want_static_lib_list) + return get_multi_merged_from_middle (pkgs, get_other_libs, TRUE, !ignore_private_libs); + else return get_multi_merged (pkgs, get_other_libs, TRUE, !ignore_private_libs); } char * -packages_get_all_libs (GSList *pkgs) +packages_get_all_libs (GSList *pkgs, int want_static_lib_list) { char *l_libs; char *L_libs; @@ -1079,9 +1190,9 @@ str = g_string_new (""); - other_libs = packages_get_other_libs (pkgs); + other_libs = packages_get_other_libs (pkgs, want_static_lib_list); L_libs = packages_get_L_libs (pkgs); - l_libs = packages_get_l_libs (pkgs); + l_libs = packages_get_l_libs (pkgs, want_static_lib_list); if (other_libs) g_string_append (str, other_libs); Index: pkg.h --- pkg.h.orig 2012-05-30 14:49:24.000000000 +0200 +++ pkg.h 2012-07-12 08:27:29.000000000 +0200 @@ -75,13 +75,13 @@ Package *get_package (const char *name); Package *get_package_quiet (const char *name); -char * package_get_l_libs (Package *pkg); -char * packages_get_l_libs (GSList *pkgs); +char * package_get_l_libs (Package *pkg, int want_static_lib_list); +char * packages_get_l_libs (GSList *pkgs, int want_static_lib_list); char * package_get_L_libs (Package *pkg); char * packages_get_L_libs (GSList *pkgs); -char * package_get_other_libs (Package *pkg); -char * packages_get_other_libs (GSList *pkgs); -char * packages_get_all_libs (GSList *pkgs); +char * package_get_other_libs (Package *pkg, int want_static_lib_list); +char * packages_get_other_libs (GSList *pkgs, int want_static_lib_list); +char * packages_get_all_libs (GSList *pkgs, int want_static_lib_list); char * package_get_I_cflags (Package *pkg); char * packages_get_I_cflags (GSList *pkgs); char * package_get_other_cflags (Package *pkg);