Allow Windows prefix redefinition in any pkgconfig directory

The prefix redefinition feature on Windows to make packages relocatable
was being confined only to locations where the .pc file was in a
directory ending in lib/pkgconfig or share/pkgconfig. This is too
restrictive as it's quite common for the libdir to have a different name
such as lib64. This keeps the convention that the feature will only be
enabled when the .pc file is in a pkgconfig directory, and it continues
to define the prefix to the grandparent of the pkgconfig directory.

The path handling is switched over to standard glib functions
g_path_get_basename and g_path_get_dirname to avoid handrolled handling
of Windows paths.
This commit is contained in:
Dan Nicholson 2013-04-17 07:40:54 -07:00
parent 409ee76ce1
commit a65d5cff5f
2 changed files with 28 additions and 42 deletions

51
parse.c
View file

@ -857,20 +857,6 @@ parse_url (Package *pkg, const char *str, const char *path)
#ifdef G_OS_WIN32
static char *orig_prefix = NULL;
static int
pathnamecmp (const char *a,
const char *b)
{
while (*a && *b &&
((G_IS_DIR_SEPARATOR (*a) && G_IS_DIR_SEPARATOR (*b)) ||
g_ascii_toupper (*a) == g_ascii_toupper (*b)))
{
a++;
b++;
}
return g_ascii_toupper (*a) - g_ascii_toupper (*b);
}
#endif
static void
@ -973,31 +959,24 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
/* This is the prefix variable. Try to guesstimate a value for it
* for this package from the location of the .pc file.
*/
gchar *base;
gboolean is_pkgconfigdir;
gchar *prefix = pkg->pcfiledir;
const int prefix_len = strlen (prefix);
const char *const lib_pkgconfig = "\\lib\\pkgconfig";
const char *const share_pkgconfig = "\\share\\pkgconfig";
const int lib_pkgconfig_len = strlen (lib_pkgconfig);
const int share_pkgconfig_len = strlen (share_pkgconfig);
if ((strlen (prefix) > lib_pkgconfig_len &&
pathnamecmp (prefix + prefix_len - lib_pkgconfig_len, lib_pkgconfig) == 0) ||
(strlen (prefix) > share_pkgconfig_len &&
pathnamecmp (prefix + prefix_len - share_pkgconfig_len, share_pkgconfig) == 0))
{
/* It ends in lib\pkgconfig or share\pkgconfig. Good. */
base = g_path_get_basename (pkg->pcfiledir);
is_pkgconfigdir = g_ascii_strcasecmp (base, "pkgconfig") == 0;
g_free (base);
if (is_pkgconfigdir)
{
/* It ends in pkgconfig. Good. */
gchar *q;
gchar *prefix;
gchar *q;
orig_prefix = g_strdup (p);
orig_prefix = g_strdup (p);
prefix = g_strdup (prefix);
if (strlen (prefix) > lib_pkgconfig_len &&
pathnamecmp (prefix + prefix_len - lib_pkgconfig_len, lib_pkgconfig) == 0)
prefix[prefix_len - lib_pkgconfig_len] = '\0';
else
prefix[prefix_len - share_pkgconfig_len] = '\0';
/* Get grandparent directory for new prefix. */
q = g_path_get_dirname (pkg->pcfiledir);
prefix = g_path_get_dirname (q);
g_free (q);
/* Turn backslashes into slashes or
* g_shell_parse_argv() will eat them when ${prefix}

View file

@ -318,15 +318,22 @@ and
This can be augmented or replaced using the standard environment
variables described above.
If a .pc file is found in a directory that matches the usual
conventions (i.e., ends with \\lib\\pkgconfig or \\share\\pkgconfig),
If a .pc file is found in a directory named
.IR pkgconfig ,
the prefix for that package is assumed to be the grandparent of the
directory where the file was found, and the \fIprefix\fP variable is
overridden for that file accordingly.
directory where the file was found, and the
.I prefix
variable is overridden for that file accordingly.
If the value of a variable in a .pc file begins with the original,
non-overridden, value of the \fIprefix\fP variable, then the overridden
value of \fIprefix\fP is used instead.
non-overridden, value of the
.I prefix
variable, then the overridden value of
.I prefix
is used instead. This allows the feature to work even when the variables
have been expanded in the .pc file.
See the \-\-dont-define-prefix option for disabling this feature.
.\"
.SH AUTOCONF MACROS
.TP