+2001-09-30 Tor Lillqvist <tml@iki.fi>
+
+ Changes for "pure" Win32 (without Cygwin or similar) support. The
+ most important differences compared to pkg-config on Unix are:
+
+ We don't use hardcoded PKGLIBDIR paths but deduce the
+ installation prefix at runtime.
+
+ Use the normal GLib DLL, not a private copy. Yes, this does
+ introduce a circular dependency, but that can be worked around.
+
+ * README.win32: New file.
+
+ * configure.in: Check for Win32. If so, define USE_INSTALLED_GLIB,
+ and don't configure in the included glib-1.2.8. Set GLIB_CFLAGS
+ and GLIB_LIBS assuming that GLib is installed in the same location
+ pkgconfig will be. Check for dirent.h, unistd.h and sys/wait.h
+ headers.
+
+ * Makefile.am: If USE_INSTALLED_GLIB, use the GLIB_* values set
+ above, and don't make in the glib-1.2.8 subdir.
+
+ * autogen.sh: Use perl -p -i.bak, works better on Win32 (and Cygwin).
+
+ * *.c: Conditionalize inclusions of unistd.h and sys/wait.h.
+
+ * findme.c: Define X_OK on Win32 if necessary.
+
+ * parse.c
+ * popthelp.c: Minor Win32 portability ifdefs.
+
+ * parse.c: No need to include <windows.h>.
+
+ * pkg.c: Don't hardcode PKGLIBDIR, but use
+ g_win32_get_package_installation_directory() to deduce it.
+ (scan_dir): Make a temp copy of dirname with potential superfluous
+ trailing slash removed. The Win32 opendir implementation doesn't
+ always like those.
+
+ * pkg.h: If USE_INSTALLED_GLIB, include <glib.h> instead of
+ partial-glib.h.
+
+ * popt.c (execCommand): Don't compile on Win32.
+
+ * poptconfig.c (configLine): Don't bother with the "exec" stuff on
+ Win32, too complex to port, at least for now.
+ (poptReadDefaultConfig) Don't bother compiling on Win32, this
+ function isn't even called.
+
2001-07-11 Havoc Pennington <hp@redhat.com>
* pkg.c: include sys/types.h to avoid warnings about dirent on
+if USE_INSTALLED_GLIB
+pkg_config_CFLAGS = @GLIB_CFLAGS@
+pkg_config_LDFLAGS = @GLIB_LIBS@
+else
SUBDIRS = glib-1.2.8
+included_glib_includes = -I./glib-1.2.8
+pkg_config_LDADD=glib-1.2.8/libglib.la
+endif
m4dir = $(datadir)/aclocal
m4_DATA = pkg.m4
bin_PROGRAMS = pkg-config
-INCLUDES=-DPKGLIBDIR="\"$(pkglibdir)\"" -I./glib-1.2.8
+INCLUDES=-DPKGLIBDIR="\"$(pkglibdir)\"" $(included_glib_includes)
pkg_config_SOURCES= \
pkg.h \
poptint.h \
poptparse.c
-pkg_config_LDADD=glib-1.2.8/libglib.la
--- /dev/null
+pkg-config on Win32
+===================
+
+This file describes pkg-config for "pure" Win32. (With Cygwin,
+pkg-config 0.8.0 builds fine right out of the box. Cygwin is just
+another Unix variant, as far as pkg-config is concerned.) I hesitate
+to call this "pure" Win32 target mingw, as the ideal would be for
+pkg-config to be usable also by MSVC users. This will require the
+addition of an option to print out the flags in the form used by MSVC,
+however, which isn't done yet. Anyway, libraries like GLib, Pango, GTK
+that are described by pkgconfig files definitely are supposed to be
+usable both for MSVC users and gcc ("mingw") users.
+
+There should be no compile-time paths built into the executable of
+pkg-config. Likewise, not in the libraries it describes either.
+
+We use one optional entry in the Registry: The path to the pkgconfig
+installation prefix. (This can be either user-specific (in
+HKEY_CURRENT_USER) or for the whole machine (in HKEY_LOCAL_MACHINE).)
+If pkg-config.exe is invoked from the "bin" subdirectory of a
+directory with a lib/pkgconfig subdirectory, no Registry entry is even
+needed, as pkgconfig (actually, the
+g_win32_get_package_installation_directory() function in GLib) figures
+out the directory by itself.
+
+The intention is that a developer package for some library being
+desribed by a .pc file is installed using some simple installer, that
+edits the user-selected installation directory into the .pc file
+before storing the .pc file where pkg-config can find it.
+
+On Unix, pkg-config is built using its own copy of GLib 1.2.8. On
+Windows, we use the normal GLib available for Windows (1.3.9
+currently). Yes, this does introduce a circular dependency, but that
+can be worked around. The circular dependency only appears if one uses
+the configure mechanism to build GLib. GLib's configure script checks
+for pkg-config. pkg-config depends on GLib. Thus, starting from
+scratch, with no GLib and no pkg-config, using configure, there would
+indeed be a Catch-22 situation. However, GLib can be built just fine
+using the manually written makefiles for mingw or MSVC. And if
+somebody does want to build GLib on Win32 using configure, she can
+first install a prebuilt pkgconfig.
exit 1
}
-perl -pi -e "s/lib_LTLIBRARIES/noinst_LTLIBRARIES/g" `find glib-1.2.8 -name Makefile.am`
-perl -pi -e "s/bin_SCRIPTS/noinst_SCRIPTS/g" `find glib-1.2.8 -name Makefile.am`
-perl -pi -e "s/include_HEADERS/noinst_HEADERS/g" `find glib-1.2.8 -name Makefile.am`
-perl -pi -e "s/[a-zA-Z0-9]+_DATA/noinst_DATA/g" `find glib-1.2.8 -name Makefile.am`
-perl -pi -e "s/info_TEXINFOS/noinst_TEXINFOS/g" `find glib-1.2.8 -name Makefile.am`
-perl -pi -e "s/man_MANS/noinst_MANS/g" `find glib-1.2.8 -name Makefile.am`
+chmod +w `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/lib_LTLIBRARIES/noinst_LTLIBRARIES/g" `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/bin_SCRIPTS/noinst_SCRIPTS/g" `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/include_HEADERS/noinst_HEADERS/g" `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/[a-zA-Z0-9]+_DATA/noinst_DATA/g" `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/info_TEXINFOS/noinst_TEXINFOS/g" `find glib-1.2.8 -name Makefile.am`
+perl -p -i.bak -e "s/man_MANS/noinst_MANS/g" `find glib-1.2.8 -name Makefile.am`
(cd glib-1.2.8 && automake)
AC_INIT(pkg-config.1)
-AC_CONFIG_SUBDIRS(glib-1.2.8)
+AC_MSG_CHECKING([for Win32])
+case "$host" in
+ *-*-mingw*)
+ native_win32=yes
+ AC_DEFINE(USE_INSTALLED_GLIB, 1, [We are using an installed GLib])
+ ;;
+ *)
+ native_win32=no
+esac
+AC_MSG_RESULT([$native_win32])
+AM_CONDITIONAL(USE_INSTALLED_GLIB, test x$native_win32 = xyes)
+
+if test x$native_win32 = xyes; then
+ # On Win32, use the normal installed GLib. Yes, this is a circular
+ # dependency. But then, only experienced hackers that presumably can
+ # work around that will be building pkg-config and GLib on Win32
+ # anyway (especially using the auto*/configure/libtool
+ # mechanism). Others use prebuilt versions.
+ #
+ # These are correct for GLib 1.3.9
+ GLIB_CFLAGS="-I$includedir/glib-2.0 -I$libdir/glib-2.0/include"
+ GLIB_LIBS="-L$libdir -lglib-1.3 -liconv -lintl"
+
+ AC_SUBST(GLIB_LIBS)
+ AC_SUBST(GLIB_CFLAGS)
+
+ AC_CONFIG_AUX_DIR(.)
+else
+ AC_CONFIG_SUBDIRS(glib-1.2.8)
+fi # !native_win32
AM_INIT_AUTOMAKE(pkgconfig, 0.8.0)
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(setresuid setreuid,break)
+AC_CHECK_HEADERS([dirent.h unistd.h sys/wait.h])
AC_OUTPUT([Makefile])
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#ifdef __NeXT
/* access macros are not declared in non posix mode in unistd.h -
don't try to use posix on NeXTstep 3.3 ! */
#include "findme.h"
+#if defined(G_OS_WIN32) && !defined(X_OK)
+#define X_OK 1
+#endif
+
char * findProgramPath(char * argv0) {
char * path = getenv("PATH");
char * pathbuf;
char **search_dirs;
char **iter;
- search_dirs = g_strsplit (search_path, ":", -1);
+ search_dirs = g_strsplit (search_path, G_SEARCHPATH_SEPARATOR_S, -1);
iter = search_dirs;
while (*iter)
#include <stdlib.h>
#include <ctype.h>
#include "popt.h"
+#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
-#include <sys/types.h>
-
-#ifdef NATIVE_WIN32
-
-#define STRICT
-#include <windows.h>
-
#endif
+#include <sys/types.h>
/**
* Read an entire line from a file into a buffer. Lines may
int status;
char *munged;
+#ifdef G_OS_WIN32
+ munged = g_strdup_printf ("%s > NUL", command);
+#else
munged = g_strdup_printf ("%s > /dev/null 2>&1", command);
+#endif
status = system (munged);
g_free (munged);
+#ifdef G_OS_WIN32
+ return status == 0;
+#else
return WIFEXITED(status) && (WEXITSTATUS(status) == 0);
+#endif
}
Package *
#include <string.h>
#include <errno.h>
#include <stdio.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <stdlib.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)
+#endif
+
static void verify_package (Package *pkg);
static GHashTable *packages = NULL;
static void
scan_dir (const char *dirname)
{
- DIR *dir = opendir (dirname);
+ DIR *dir;
struct dirent *dent;
int dirnamelen = strlen (dirname);
+ /* Use a copy of dirname cause Win32 opendir doesn't like
+ * superfluous trailing (back)slashes in the directory name.
+ */
+ char *dirname_copy = strdup (dirname);
- if (dirnamelen > 0 && dirname[dirnamelen-1] == '/')
- dirnamelen--;
+ if (dirnamelen > 1 && dirname[dirnamelen-1] == G_DIR_SEPARATOR)
+ {
+ dirnamelen--;
+ dirname_copy[dirnamelen-1] = '\0';
+ }
+ dir = opendir (dirname_copy);
+ free (dirname_copy);
if (!dir)
{
debug_spew ("Cannot open directory '%s' in package search path: %s\n",
{
char *filename = g_malloc (dirnamelen + 1 + len + 1);
strncpy (filename, dirname, dirnamelen);
- filename[dirnamelen] = '/';
+ filename[dirnamelen] = G_DIR_SEPARATOR;
strcpy (filename + dirnamelen + 1, dent->d_name);
g_hash_table_insert (locations, pkgname, filename);
#ifndef PKG_CONFIG_PKG_H
#define PKG_CONFIG_PKG_H
+#ifdef USE_INSTALLED_GLIB
+#include <glib.h>
+#else
#include "partial-glib.h"
+#endif
typedef enum
{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include "findme.h"
#include "popt.h"
return 1;
}
+#ifndef _WIN32
+
static void execCommand(poptContext con) {
char ** argv;
int pos = 0;
execvp(argv[0], argv);
}
+#endif
+
static const struct poptOption * findOption(const struct poptOption * table,
const char * longName,
const char shortName,
con->os--;
if (!con->os->nextCharArg && con->os->next == con->os->argc) {
invokeCallbacks(con, con->options, 1);
+#ifndef _WIN32
if (con->doExec) execCommand(con);
+#endif
return -1;
}
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include "popt.h"
#include "poptint.h"
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
alias.longName = longName, alias.shortName = shortName;
poptAddAlias(con, alias, 0);
- } else if (!strcmp(entryType, "exec")) {
+ }
+#ifndef _WIN32 /* exec stuff too complex to be worthwhile to port */
+ else if (!strcmp(entryType, "exec")) {
con->execs = realloc(con->execs,
sizeof(*con->execs) * (con->numExecs + 1));
if (longName)
con->numExecs++;
}
+#endif /* !_WIN32 */
}
int poptReadConfigFile(poptContext con, char * fn) {
return 0;
}
+#ifndef _WIN32
+
int poptReadDefaultConfig(poptContext con, int useEnv) {
char * fn, * home;
int rc;
return 0;
}
+#endif /* !_WIN32 */
#include "popt.h"
#include "poptint.h"
+#ifdef _WIN32
+#define SLASH '\\'
+#else
+#define SLASH '/'
+#endif
+
static void displayArgs(poptContext con, enum poptCallbackReason foo,
struct poptOption * key,
const char * arg, void * data) {
fprintf(f, POPT_("Usage:"));
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
fn = con->optionStack->argv[0];
- if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
+ if (strchr(fn, SLASH)) fn = strchr(fn, SLASH) + 1;
fprintf(f, " %s", fn);
len += strlen(fn) + 1;
}