2001-10-25 Tor Lillqvist <tml@iki.fi>

Author: tml
Date: 2001-10-24 21:22:33 GMT
2001-10-25  Tor Lillqvist  <tml@iki.fi>

	Improve Windows behaviour: Make it even easier to install
	developer packages in random locations, without having to modify
	the .pc files. Don't set "prefix" globally, instead override it
	for each .pc file parsed, if the path where the .pc file is seems
	to be the standard .../lib/pkgconfig.

	* main.c (main): Add search directories also from two Registry
	keys, in addition to the PKG_CONFIG_PATH environment
	variable. Don't define prefix globally.

	* parse.c (parse_line): Instead, if a .pc file is in
	/foo/bar/lib/pkgconfig, define prefix as /foo/bar for that package
	only.

	* pkg.c: Case-fold file names on Windows, in case they have been
	uppercasified by some tool.

	* pkg-config.1: Document Windows behaviour.
This commit is contained in:
Arch Librarian 2005-07-14 13:04:37 +00:00
parent 6fe682ad4f
commit d86ec30f0a
6 changed files with 173 additions and 36 deletions

View file

@ -1,3 +1,24 @@
2001-10-25 Tor Lillqvist <tml@iki.fi>
Improve Windows behaviour: Make it even easier to install
developer packages in random locations, without having to modify
the .pc files. Don't set "prefix" globally, instead override it
for each .pc file parsed, if the path where the .pc file is seems
to be the standard .../lib/pkgconfig.
* main.c (main): Add search directories also from two Registry
keys, in addition to the PKG_CONFIG_PATH environment
variable. Don't define prefix globally.
* parse.c (parse_line): Instead, if a .pc file is in
/foo/bar/lib/pkgconfig, define prefix as /foo/bar for that package
only.
* pkg.c: Case-fold file names on Windows, in case they have been
uppercasified by some tool.
* pkg-config.1: Document Windows behaviour.
2001-10-21 Tor Lillqvist <tml@iki.fi>
* Makefile.am (EXTRA_DIST): Distribute README.win32.

82
main.c
View file

@ -11,6 +11,12 @@
#include <ctype.h>
#include <stdio.h>
#ifdef G_OS_WIN32
#define STRICT
#include <windows.h>
#undef STRICT
#endif
static int want_debug_spew = 0;
static int want_verbose_errors = 0;
static int want_stdout_errors = 0;
@ -144,14 +150,12 @@ main (int argc, char **argv)
static int want_list = 0;
static int result;
static int want_uninstalled = 0;
static int dont_define_prefix = 0;
static char *variable_name = NULL;
static int want_exists = 0;
static char *required_atleast_version = NULL;
static char *required_exact_version = NULL;
static char *required_max_version = NULL;
static char *required_pkgconfig_version = NULL;
static char *prefix_variable = NULL;
static int want_silence_errors = 0;
GString *str;
GSList *packages = NULL;
@ -208,7 +212,8 @@ main (int argc, char **argv)
"print errors from --print-errors to stdout not stderr" },
#ifdef G_OS_WIN32
{ "dont-define-prefix", 0, POPT_ARG_NONE, &dont_define_prefix, 0,
"don't set the value of prefix based on where pkg-config.exe is installed" },
"don't try to override the value of prefix for each .pc file found with "
"a guesstimated value based on the location of the .pc file" },
{ "prefix-variable", 0, POPT_ARG_STRING, &prefix_variable, 0,
"set the name of the variable that pkg-config automatically sets", "PREFIX" },
#endif
@ -248,6 +253,57 @@ main (int argc, char **argv)
g_strfreev (search_dirs);
}
#ifdef G_OS_WIN32
{
/* Add search directories from the Registry */
HKEY roots[] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
gchar *root_names[] = { "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE" };
HKEY key;
int i;
gulong max_value_name_len, max_value_len;
for (i = 0; i < G_N_ELEMENTS (roots); i++)
{
key = NULL;
if (RegOpenKeyEx (roots[i], "Software\\" PACKAGE "\\PKG_CONFIG_PATH", 0,
KEY_QUERY_VALUE, &key) == ERROR_SUCCESS &&
RegQueryInfoKey (key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&max_value_name_len, &max_value_len,
NULL, NULL) == ERROR_SUCCESS)
{
int index = 0;
gchar *value_name = g_malloc (max_value_name_len + 1);
gchar *value = g_malloc (max_value_len + 1);
while (TRUE)
{
gulong type;
gulong value_name_len = max_value_name_len + 1;
gulong value_len = max_value_len + 1;
if (RegEnumValue (key, index++, value_name, &value_name_len,
NULL, &type,
value, &value_len) != ERROR_SUCCESS)
break;
if (type != REG_SZ)
continue;
value_name[value_name_len] = '\0';
value[value_len] = '\0';
debug_spew ("Adding directory '%s' from %s\\Software\\"
PACKAGE "\\PKG_CONFIG_PATH\\%s\n",
value, root_names[i], value_name);
add_search_dir (value);
}
}
if (key != NULL)
RegCloseKey (key);
}
}
#endif
pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
if (pcbuilddir)
{
@ -329,26 +385,6 @@ main (int argc, char **argv)
return 1;
}
#ifdef G_OS_WIN32
if (!dont_define_prefix)
{
gchar *prefix = g_win32_get_package_installation_directory (PACKAGE " " VERSION, NULL);
gchar *p = prefix;
/* Turn backslashes into slashes or poptParseArgvString() will eat
* them when ${prefix} has been expanded in parse_libs().
*/
while (*p)
{
if (*p == '\\')
*p = '/';
p++;
}
define_global_variable (prefix_variable ? prefix_variable : "prefix",
prefix);
}
#endif
package_init ();
if (want_list)

50
parse.c
View file

@ -14,6 +14,11 @@
#endif
#include <sys/types.h>
#ifdef G_OS_WIN32
int dont_define_prefix = FALSE;
char *prefix_variable = "prefix";
#endif
/**
* Read an entire line from a file into a buffer. Lines may
* be delimited with '\n', '\r', '\n\r', or '\r\n'. The delimiter
@ -817,6 +822,51 @@ parse_line (Package *pkg, const char *untrimmed, const char *path)
if (pkg->vars == NULL)
pkg->vars = g_hash_table_new (g_str_hash, g_str_equal);
#ifdef G_OS_WIN32
if (!dont_define_prefix && strcmp (tag, prefix_variable) == 0)
{
/* This is the prefix variable. Try to guesstimate a value for it
* for this package from the location of the .pc file.
*/
gchar *prefix = pkg->pcfiledir;
const int prefix_len = strlen (prefix);
const char *const lib_pkgconfig = "\\lib\\pkgconfig";
const int lib_pkgconfig_len = strlen (lib_pkgconfig);
if (strlen (prefix) > lib_pkgconfig_len &&
g_ascii_strcasecmp (prefix + prefix_len - lib_pkgconfig_len,
lib_pkgconfig) == 0)
{
/* It ends in lib\pkgconfig. Good. */
gchar *p;
prefix = g_strdup (prefix);
prefix[prefix_len - lib_pkgconfig_len] = '\0';
/* Turn backslashes into slashes or
* poptParseArgvString() will eat them when ${prefix}
* has been expanded in parse_libs().
*/
p = prefix;
while (*p)
{
if (*p == '\\')
*p = '/';
p++;
}
varname = g_strdup (tag);
debug_spew (" Variable declaration, '%s' overridden with '%s'\n",
tag, prefix);
g_hash_table_insert (pkg->vars, varname, prefix);
g_free (str);
g_free (tag);
return;
}
}
#endif
if (g_hash_table_lookup (pkg->vars, tag))
{
verbose_error ("Duplicate definition of variable '%s' in '%s'\n",

View file

@ -34,7 +34,8 @@ program: program.c
special metadata files. These files are named after the package,
with the extension \fI.pc\fP. By default, pkg-config looks in
the directory \fIprefix\fP/lib/pkgconfig for these files; it will also
look in the colon-separated list of directories specified by the
look in the colon-separated (on Windows, semicolon-separated)
list of directories specified by the
PKG_CONFIG_PATH environment variable.
.PP
@ -170,23 +171,20 @@ Remember to use \-\-print-errors if you want error messages.
.TP
.I "--dont-define-prefix"
This option is available only on Windows. It prevents \fIpkg-config\fP
from automatically setting the value of the variable "prefix" to the
directory where \fIpkg-config\fP was installed. (This directory is
determined by asking the system where \fIpkg-config.exe\fP is located,
and if that directory is called \fIbin\fP or \fIlib\fP, using its
parent directory, otherwise itself.)
from automatically trying to override the value of the variable
"prefix" in each .pc file.
.TP
.I "--prefix-variable=PREFIX"
Also this option is available only on Windows. It sets the name of the
variable that \fIpkg-config\fP automatically sets to its own
installation prefix.
variable that \fIpkg-config\fP automatically sets as described above.
.SH ENVIRONMENT VARIABLES
.TP
.I "PKG_CONFIG_PATH"
A colon-separated list of directories to search for .pc files.
A colon-separated (on Windows, semicolon-separated)
list of directories to search for .pc files.
The default directory will always be searched after searching the
path; the default is \fIlibdir\fP/pkgconfig where \fIlibdir\fP
is the libdir where \fIpkg-config\fP was installed.
@ -214,6 +212,20 @@ Normally if you request the package "foo" and the package
uninstalled packages. If this environment variable is set, it
disables said behavior.
.SH WINDOWS SPECIALITIES
If a .pc file is found in a path that corresponds to the usual
conventions (i.e., ends with lib\\pkgconfig), the prefix for that
package is assumed to be the grandparent of the directory where the .pc file
was found.
In addition to the \fIPKG_CONFIG_PATH\fP environment variable, the
Registry keys
\fIHKEY_CURRENT_USER\\Software\\pkgconfig\\PKG_CONFIG_PATH\fP and
\fIHKEY_LOCAL_MACHINE\\Software\\pkgconfig\\PKG_CONFIG_PATH\fP can be
used to specify dorectories to search for .pc files. Each (string)
value in these keys is treated as a directory where to look for .pc
files.
.SH AUTOCONF MACROS
.TP

18
pkg.c
View file

@ -22,12 +22,13 @@
#include <unistd.h>
#endif
#include <stdlib.h>
#include <ctype.h>
#ifdef G_OS_WIN32
/* No hardcoded paths in the binary, thanks */
#undef PKGLIBDIR
/* It's OK to leak this, as PKGLIBDIR is invoked only once */
#define PKGLIBDIR g_strconcat (g_win32_get_package_installation_directory (PACKAGE " " VERSION, NULL), "\\lib\\pkgconfig", NULL)
#define PKGLIBDIR g_strconcat (g_win32_get_package_installation_directory (PACKAGE, NULL), "\\lib\\pkgconfig", NULL)
#endif
static void verify_package (Package *pkg);
@ -45,6 +46,15 @@ add_search_dir (const char *path)
search_dirs = g_slist_prepend (search_dirs, g_strdup (path));
}
#ifdef G_OS_WIN32
/* Guard against .pc file being installed with UPPER CASE name */
# define FOLD(x) tolower(x)
# define FOLDCMP(a, b) g_ascii_strcasecmp (a, b)
#else
# define FOLD(x) (x)
# define FOLDCMP(a, b) strcmp (a, b)
#endif
#define EXT_LEN 3
static gboolean
@ -54,8 +64,8 @@ ends_in_dotpc (const char *str)
if (len > EXT_LEN &&
str[len - 3] == '.' &&
str[len - 2] == 'p' &&
str[len - 1] == 'c')
FOLD (str[len - 2]) == 'p' &&
FOLD (str[len - 1]) == 'c')
return TRUE;
else
return FALSE;
@ -70,7 +80,7 @@ name_ends_in_uninstalled (const char *str)
int len = strlen (str);
if (len > UNINSTALLED_LEN &&
strcmp ((str + len - UNINSTALLED_LEN), "uninstalled") == 0)
FOLDCMP ((str + len - UNINSTALLED_LEN), "uninstalled") == 0)
return TRUE;
else
return FALSE;

8
pkg.h
View file

@ -93,5 +93,13 @@ gboolean name_ends_in_uninstalled (const char *str);
/* If TRUE, do not automatically prefer uninstalled versions */
extern gboolean disable_uninstalled;
#ifdef G_OS_WIN32
/* If TRUE, do not automatically define "prefix" while
* parsing each .pc file */
extern int dont_define_prefix;
/* The name of the variable that acts as prefix, unless it is "prefix" */
extern char *prefix_variable;
#endif
#endif