Keep Libs and Cflags together to maintain ordering

Instead of splitting to -l/-L/other and -I/other, keep the args together
and mark each argument with its type. Then we can maintain order all the
way through.
This commit is contained in:
Dan Nicholson 2012-11-19 08:19:48 -08:00
parent 05f319d3e5
commit 9bf6277b9c
3 changed files with 113 additions and 103 deletions

88
parse.c
View file

@ -615,6 +615,7 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
i = 0; i = 0;
while (i < argc) while (i < argc)
{ {
Flag *flag = g_new (Flag, 1);
char *tmp = trim_string (argv[i]); char *tmp = trim_string (argv[i]);
char *arg = strdup_escape_shell(tmp); char *arg = strdup_escape_shell(tmp);
char *p; char *p;
@ -631,9 +632,9 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
while (*p && isspace ((guchar)*p)) while (*p && isspace ((guchar)*p))
++p; ++p;
pkg->l_libs = g_list_prepend (pkg->l_libs, flag->type = LIBS_l;
g_strconcat (l_flag, p, lib_suffix, NULL)); flag->arg = g_strconcat (l_flag, p, lib_suffix, NULL);
pkg->libs = g_list_prepend (pkg->libs, flag);
} }
else if (p[0] == '-' && else if (p[0] == '-' &&
p[1] == 'L') p[1] == 'L')
@ -641,8 +642,10 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
p += 2; p += 2;
while (*p && isspace ((guchar)*p)) while (*p && isspace ((guchar)*p))
++p; ++p;
pkg->L_libs = g_list_prepend (pkg->L_libs,
g_strconcat (L_flag, p, NULL)); flag->type = LIBS_L;
flag->arg = g_strconcat (L_flag, p, lib_suffix, NULL);
pkg->libs = g_list_prepend (pkg->libs, flag);
} }
else if (strcmp("-framework",p) == 0 && i+1 < argc) else if (strcmp("-framework",p) == 0 && i+1 < argc)
{ {
@ -653,19 +656,23 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
*/ */
gchar *framework, *tmp = trim_string (argv[i+1]); gchar *framework, *tmp = trim_string (argv[i+1]);
framework = strdup_escape_shell(tmp); framework = strdup_escape_shell(tmp);
pkg->other_libs = g_list_prepend (pkg->other_libs, flag->type = LIBS_OTHER;
g_strconcat(arg, " ", framework, NULL)); flag->arg = g_strconcat (arg, " ", framework, NULL);
pkg->libs = g_list_prepend (pkg->libs, flag);
i++; i++;
g_free(framework); g_free (framework);
g_free(tmp); g_free (tmp);
}
else if (*arg != '\0')
{
flag->type = LIBS_OTHER;
flag->arg = g_strdup (arg);
pkg->libs = g_list_prepend (pkg->libs, flag);
} }
else else
{ /* flag wasn't used */
if (*arg != '\0') g_free (flag);
pkg->other_libs = g_list_prepend (pkg->other_libs,
g_strdup (arg));
}
g_free (arg); g_free (arg);
@ -765,7 +772,7 @@ parse_cflags (Package *pkg, const char *str, const char *path)
GError *error = NULL; GError *error = NULL;
int i; int i;
if (pkg->I_cflags || pkg->other_cflags) if (pkg->cflags)
{ {
verbose_error ("Cflags field occurs twice in '%s'\n", path); verbose_error ("Cflags field occurs twice in '%s'\n", path);
@ -785,6 +792,7 @@ parse_cflags (Package *pkg, const char *str, const char *path)
i = 0; i = 0;
while (i < argc) while (i < argc)
{ {
Flag *flag = g_new (Flag, 1);
char *tmp = trim_string (argv[i]); char *tmp = trim_string (argv[i]);
char *arg = strdup_escape_shell(tmp); char *arg = strdup_escape_shell(tmp);
char *p = arg; char *p = arg;
@ -797,22 +805,32 @@ parse_cflags (Package *pkg, const char *str, const char *path)
while (*p && isspace ((guchar)*p)) while (*p && isspace ((guchar)*p))
++p; ++p;
pkg->I_cflags = g_list_prepend (pkg->I_cflags, flag->type = CFLAGS_I;
g_strconcat ("-I", p, NULL)); flag->arg = g_strconcat ("-I", p, NULL);
pkg->cflags = g_list_prepend (pkg->cflags, flag);
}
else if (strcmp("-idirafter", arg) == 0 && i+1 < argc)
{
char *dirafter, *tmp;
} else { tmp = trim_string (argv[i+1]);
if (*arg != '\0') dirafter = strdup_escape_shell (tmp);
pkg->other_cflags = g_list_prepend (pkg->other_cflags, flag->type = CFLAGS_OTHER;
g_strdup (arg)); flag->arg = g_strconcat (arg, " ", dirafter, NULL);
if (strcmp("-idirafter", arg) == 0) { pkg->cflags = g_list_prepend (pkg->cflags, flag);
char *n; i++;
g_free (dirafter);
tmp = trim_string(argv[++i]); g_free (tmp);
n = strdup_escape_shell(tmp); }
pkg->other_cflags = g_list_prepend (pkg->other_cflags, n); else if (*arg != '\0')
g_free(tmp); {
} flag->type = CFLAGS_OTHER;
} flag->arg = g_strdup (arg);
pkg->cflags = g_list_prepend (pkg->cflags, flag);
}
else
/* flag wasn't used */
g_free (flag);
g_free (arg); g_free (arg);
@ -1092,12 +1110,8 @@ parse_package_file (const char *path, gboolean ignore_requires,
g_string_free (str, TRUE); g_string_free (str, TRUE);
fclose(f); fclose(f);
pkg->I_cflags = g_list_reverse (pkg->I_cflags); pkg->cflags = g_list_reverse (pkg->cflags);
pkg->other_cflags = g_list_reverse (pkg->other_cflags); pkg->libs = g_list_reverse (pkg->libs);
pkg->l_libs = g_list_reverse (pkg->l_libs);
pkg->L_libs = g_list_reverse (pkg->L_libs);
pkg->other_libs = g_list_reverse (pkg->other_libs);
return pkg; return pkg;
} }

112
pkg.c
View file

@ -425,7 +425,7 @@ get_package_quiet (const char *name)
} }
static GList * static GList *
string_list_strip_duplicates (GList *list, gboolean forward) flag_list_strip_duplicates (GList *list, gboolean forward)
{ {
GHashTable *table; GHashTable *table;
GList *tmp; GList *tmp;
@ -435,26 +435,30 @@ string_list_strip_duplicates (GList *list, gboolean forward)
tmp != NULL; tmp != NULL;
tmp = forward ? g_list_next (tmp) : g_list_previous (tmp)) tmp = forward ? g_list_next (tmp) : g_list_previous (tmp))
{ {
if (!g_hash_table_lookup_extended (table, tmp->data, NULL, NULL)) Flag *flag = tmp->data;
debug_spew ("Seeing if arg %s is duplicate\n", flag->arg);
if (!g_hash_table_lookup_extended (table, flag->arg, NULL, NULL))
{ {
/* Unique string. Track it and and move to the next. */ /* Unique flag. Track it and and move to the next. */
g_hash_table_replace (table, tmp->data, tmp->data); g_hash_table_replace (table, flag->arg, flag->arg);
} }
else else
{ {
GList *dup = tmp; GList *dup = tmp;
/* Remove the duplicate string from the list and move to the last /* Remove the duplicate flag from the list and move to the last
* element to prepare for the next iteration. */ * element to prepare for the next iteration. */
if (forward) if (forward)
{ {
debug_spew (" removing duplicate \"%s\"\n", tmp->data); debug_spew (" removing duplicate \"%s\"\n", flag->arg);
tmp = g_list_previous (tmp); tmp = g_list_previous (tmp);
} }
else else
{ {
debug_spew (" removing duplicate (from back) \"%s\"\n", debug_spew (" removing duplicate (from back) \"%s\"\n",
tmp->data); flag->arg);
tmp = g_list_next (tmp); tmp = g_list_next (tmp);
} }
list = g_list_remove_link (list, dup); list = g_list_remove_link (list, dup);
@ -466,7 +470,7 @@ string_list_strip_duplicates (GList *list, gboolean forward)
} }
static char * static char *
string_list_to_string (GList *list) flag_list_to_string (GList *list)
{ {
GList *tmp; GList *tmp;
GString *str = g_string_new (""); GString *str = g_string_new ("");
@ -474,11 +478,10 @@ string_list_to_string (GList *list)
tmp = list; tmp = list;
while (tmp != NULL) { while (tmp != NULL) {
char *tmpstr = (char*) tmp->data; Flag *flag = tmp->data;
if (pcsysrootdir != NULL && char *tmpstr = flag->arg;
tmpstr[0] == '-' &&
(tmpstr[1] == 'I' || if (pcsysrootdir != NULL && flag->type & (CFLAGS_I | LIBS_L)) {
tmpstr[1] == 'L')) {
g_string_append_c (str, '-'); g_string_append_c (str, '-');
g_string_append_c (str, tmpstr[1]); g_string_append_c (str, tmpstr[1]);
g_string_append (str, pcsysrootdir); g_string_append (str, pcsysrootdir);
@ -578,41 +581,23 @@ merge_flag_lists (GList *packages, FlagType type)
for (; packages != NULL; packages = g_list_next (packages)) for (; packages != NULL; packages = g_list_next (packages))
{ {
Package *pkg = packages->data; Package *pkg = packages->data;
GList *flags; GList *flags = (type & LIBS_ANY) ? pkg->libs : pkg->cflags;
/* fetch the appropriate flags */
switch (type)
{
case CFLAGS_OTHER:
flags = pkg->other_cflags;
break;
case CFLAGS_I:
flags = pkg->I_cflags;
break;
case LIBS_OTHER:
flags = pkg->other_libs;
break;
case LIBS_L:
flags = pkg->L_libs;
break;
case LIBS_l:
flags = pkg->l_libs;
break;
default:
g_assert_not_reached ();
break;
}
/* manually copy the elements so we can keep track of the end */ /* manually copy the elements so we can keep track of the end */
for (; flags != NULL; flags = g_list_next (flags)) for (; flags != NULL; flags = g_list_next (flags))
{ {
if (last == NULL) Flag *flag = flags->data;
if (flag->type & type)
{ {
merged = g_list_prepend (NULL, flags->data); if (last == NULL)
last = merged; {
merged = g_list_prepend (NULL, flags->data);
last = merged;
}
else
last = g_list_next (g_list_append (last, flags->data));
} }
else
last = g_list_next (g_list_append (last, flags->data));
} }
} }
@ -850,15 +835,19 @@ verify_package (Package *pkg)
} }
count = 0; count = 0;
iter = pkg->I_cflags; for (iter = pkg->cflags; iter != NULL; iter = g_list_next (iter))
while (iter != NULL)
{ {
gint offset = 0; gint offset = 0;
Flag *flag = iter->data;
if (!(flag->type & CFLAGS_I))
continue;
/* we put things in canonical -I/usr/include (vs. -I /usr/include) format, /* we put things in canonical -I/usr/include (vs. -I /usr/include) format,
* but if someone changes it later we may as well be robust * but if someone changes it later we may as well be robust
*/ */
if (((strncmp (iter->data, "-I", 2) == 0) && (offset = 2))|| if (((strncmp (flag->arg, "-I", 2) == 0) && (offset = 2))||
((strncmp (iter->data, "-I ", 3) == 0) && (offset = 3))) ((strncmp (flag->arg, "-I ", 3) == 0) && (offset = 3)))
{ {
if (offset == 0) if (offset == 0)
{ {
@ -870,13 +859,14 @@ verify_package (Package *pkg)
while (system_dir_iter != NULL) while (system_dir_iter != NULL)
{ {
if (strcmp (system_dir_iter->data, if (strcmp (system_dir_iter->data,
((char*)iter->data) + offset) == 0) ((char*)flag->arg) + offset) == 0)
{ {
debug_spew ("Package %s has %s in Cflags\n", debug_spew ("Package %s has %s in Cflags\n",
pkg->key, (gchar *)iter->data); pkg->key, (gchar *)flag->arg);
if (g_getenv ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") == NULL) if (g_getenv ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS") == NULL)
{ {
debug_spew ("Removing %s from cflags for %s\n", iter->data, pkg->key); debug_spew ("Removing %s from cflags for %s\n",
flag->arg, pkg->key);
++count; ++count;
iter->data = NULL; iter->data = NULL;
@ -886,13 +876,11 @@ verify_package (Package *pkg)
system_dir_iter = system_dir_iter->next; system_dir_iter = system_dir_iter->next;
} }
} }
iter = iter->next;
} }
while (count) while (count)
{ {
pkg->I_cflags = g_list_remove (pkg->I_cflags, NULL); pkg->cflags = g_list_remove (pkg->cflags, NULL);
--count; --count;
} }
@ -911,15 +899,18 @@ verify_package (Package *pkg)
system_directories = add_env_variable_to_list (system_directories, search_path); system_directories = add_env_variable_to_list (system_directories, search_path);
count = 0; count = 0;
iter = pkg->L_libs; for (iter = pkg->libs; iter != NULL; iter = g_list_next (iter))
while (iter != NULL)
{ {
GList *system_dir_iter = system_directories; GList *system_dir_iter = system_directories;
Flag *flag = iter->data;
if (!(flag->type & LIBS_L))
continue;
while (system_dir_iter != NULL) while (system_dir_iter != NULL)
{ {
gboolean is_system = FALSE; gboolean is_system = FALSE;
const char *linker_arg = iter->data; const char *linker_arg = flag->arg;
const char *system_libpath = system_dir_iter->data; const char *system_libpath = system_dir_iter->data;
if (strncmp (linker_arg, "-L ", 3) == 0 && if (strncmp (linker_arg, "-L ", 3) == 0 &&
@ -936,7 +927,8 @@ verify_package (Package *pkg)
{ {
iter->data = NULL; iter->data = NULL;
++count; ++count;
debug_spew ("Removing -L %s from libs for %s\n", system_libpath, pkg->key); debug_spew ("Removing -L %s from libs for %s\n",
system_libpath, pkg->key);
break; break;
} }
} }
@ -948,7 +940,7 @@ verify_package (Package *pkg)
while (count) while (count)
{ {
pkg->L_libs = g_list_remove (pkg->L_libs, NULL); pkg->libs = g_list_remove (pkg->libs, NULL);
--count; --count;
} }
} }
@ -968,8 +960,8 @@ get_multi_merged (GList *pkgs, FlagType type, gboolean in_path_order,
char *retval; char *retval;
list = fill_list (pkgs, type, in_path_order, include_private); list = fill_list (pkgs, type, in_path_order, include_private);
list = string_list_strip_duplicates (list, in_path_order); list = flag_list_strip_duplicates (list, in_path_order);
retval = string_list_to_string (list); retval = flag_list_to_string (list);
g_list_free (list); g_list_free (list);
return retval; return retval;

14
pkg.h
View file

@ -45,9 +45,16 @@ typedef enum
ALWAYS_MATCH ALWAYS_MATCH
} ComparisonType; } ComparisonType;
typedef struct _Flag Flag;
typedef struct _Package Package; typedef struct _Package Package;
typedef struct _RequiredVersion RequiredVersion; typedef struct _RequiredVersion RequiredVersion;
struct _Flag
{
FlagType type;
char *arg;
};
struct _RequiredVersion struct _RequiredVersion
{ {
char *name; char *name;
@ -68,11 +75,8 @@ struct _Package
GList *requires; GList *requires;
GList *requires_private_entries; GList *requires_private_entries;
GList *requires_private; GList *requires_private;
GList *l_libs; GList *libs;
GList *L_libs; GList *cflags;
GList *other_libs;
GList *I_cflags;
GList *other_cflags;
GHashTable *vars; GHashTable *vars;
GHashTable *required_versions; /* hash from name to RequiredVersion */ GHashTable *required_versions; /* hash from name to RequiredVersion */
GList *conflicts; /* list of RequiredVersion */ GList *conflicts; /* list of RequiredVersion */