gobject-introspection r503 - in trunk: . gir girepository giscanner tools



Author: tml
Date: Wed Aug 27 13:33:21 2008
New Revision: 503
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=503&view=rev

Log:
2008-08-27  Tor Lillqvist  <tml novell com>

	Make g-ir-scanner work on Windows. Still problems with the typelib
	code. Changes okayed by jdahlin.

	* configure.ac: Check for Windows, set Automake conditional
	OS_WIN32. Change backslashes to forward slashes in pyexecdir to
	avoid shell quoting issues
	
	* girepository/Makefile.am: Use -no-undefined so that libtool
	agrees to build a shared library on Windows.

	* girepository/girparser.c (backtrace_stderr): No backtrace() on
	Windows. Empty implementation on Windows so far.

	* girepository/gtypelib.c (g_typelib_check_sanity): Give more
	informative error message for the assertion failures. Tell also
	what the expected size of the struct is. Check all sizes first and
	fail afterwards if at least one size was different from expected.

	* tools/Makefile.am: Reorder libraries into proper logical
	dependency order.

	* tools/generate.c: Don't include <dlfcn.h>, not used.

	* giscanner/Makefile.am: On Windows, link with the Python library,
	and install the module DLL as _giscanner.pyd. Remove the
	unnecessary import library and libtool library that libtool has
	installed.

	* giscanner/scannerlexer.l: Recognize the gcc __attribute__ syntax
	and just skip it. Recognize also two "l" suffixes for long long
	constants. Recognize also __inline__.

	* giscanner/grealpath.h (g_realpath): Implement on Windows, using
	GetFullPathName(). As such, GetFullPathName() does more than the
	UNIX realpath(). It also changes relative paths into absolute
	paths. But for our purposes that shouldn't matter.

	* giscanner/giscannermodule.c (pygi_source_scanner_parse_file): On
	Windows the file descriptor passed to us is from Python. Python
	Python2.5 uses the msvcr71.dll C library, while mingw-built code
	uses msvcrt.dll. On Windows, file descriptors are specific to
	which C library is used. So we must find out what underlying OS
	handle corresponds to the file descriptor Python passes us, and
	then make that into a file descriptor valid for the C library this
	code uses.

	* giscanner/sourcescanner.py (_parse): Don't need to bypass
	__attribute__ as the lexer now handles it. The definition as empty
	was ineffective for mingw anyway, as mingw's _mingw.h undefines
	__attribute__. Close the temp file before unlinking it.

	* giscanner/cgobject.py: Use correct library name for the gobject
	DLL on Windows.

	* gir/Makefile.am: Must pass the full basename of the DLLs on
	Windows to g-ir-scanner. It's a bit ugly that we have to "know"
	that the names of the GLib DLLs are like libglib-2.0-0.dll, but in
	reality they won't change, until there is a GLib 3, and then also
	the Unix code here needs changing.

	Must pass CPPFLAGS to g-ir-scanner when building GLib.gir so that
	libintl.h is found.



Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/gir/Makefile.am
   trunk/girepository/Makefile.am
   trunk/girepository/girparser.c
   trunk/girepository/gtypelib.c
   trunk/giscanner/Makefile.am
   trunk/giscanner/cgobject.py
   trunk/giscanner/giscannermodule.c
   trunk/giscanner/grealpath.h
   trunk/giscanner/scannerlexer.l
   trunk/giscanner/sourcescanner.py
   trunk/tools/Makefile.am
   trunk/tools/generate.c

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Wed Aug 27 13:33:21 2008
@@ -9,6 +9,20 @@
 
 AC_CONFIG_MACRO_DIR([m4])
 
+# Check for Win32
+AC_CANONICAL_HOST
+AC_MSG_CHECKING([for Win32])
+case "$host" in
+*-*-mingw*)
+	os_win32=yes
+	;;
+*)
+	os_win32=no
+	;;
+esac
+AC_MSG_RESULT([$os_win32])
+AM_CONDITIONAL(OS_WIN32, [test "$os_win32" = "yes"])
+
 # Checks for programs.
 AC_PROG_CC
 AM_PROG_CC_C_O
@@ -95,6 +109,13 @@
 AC_MSG_CHECKING([whether Python support is requested])
 
 AM_PATH_PYTHON([2.5])
+case "$host" in
+*-*-mingw*)
+	# Change backslashes to forward slashes in pyexecdir to avoid
+	# quoting issues
+	pyexecdir=`echo $pyexecdir | tr '\\\\' '/'`
+	;;
+esac
 AM_CHECK_PYTHON_HEADERS
 
 AC_CONFIG_FILES([

Modified: trunk/gir/Makefile.am
==============================================================================
--- trunk/gir/Makefile.am	(original)
+++ trunk/gir/Makefile.am	Wed Aug 27 13:33:21 2008
@@ -7,13 +7,21 @@
 # glib
 GLIB_INCLUDEDIR=`pkg-config --variable=includedir glib-2.0`/glib-2.0
 GLIB_LIBDIR=`pkg-config --variable=libdir glib-2.0`
+
+if OS_WIN32
+GLIB_LIBRARY=libglib-2.0-0
+else
+GLIB_LIBRARY=glib-2.0
+endif
+
 GLib.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
 	PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \
 	    -v --namespace GLib \
 	    --noclosure \
 	    --output $@ \
 	    --strip-prefix=g \
-	    --library=glib-2.0 \
+	    --library=$(GLIB_LIBRARY) \
+	    $(CPPFLAGS) \
 	    -I$(GLIB_INCLUDEDIR) \
 	    -I$(GLIB_LIBDIR)/glib-2.0/include \
 	    -DGETTEXT_PACKAGE=Dummy \
@@ -25,6 +33,13 @@
 # gobject
 GOBJECT_INCLUDEDIR=`pkg-config --variable=includedir gobject-2.0`/glib-2.0
 GOBJECT_LIBDIR=`pkg-config --variable=libdir gobject-2.0`
+
+if OS_WIN32
+GOBJECT_LIBRARY=libgobject-2.0-0
+else
+GOBJECT_LIBRARY=gobject-2.0
+endif
+
 GObject.gir: GLib.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
 	PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \
 	    -v --namespace GObject \
@@ -32,7 +47,7 @@
 	    --output $@ \
 	    --strip-prefix=g \
             --include=$(top_builddir)/gir/GLib.gir \
-	    --library=gobject-2.0 \
+	    --library=$(GOBJECT_LIBRARY) \
 	    -I$(GOBJECT_INCLUDEDIR) \
 	    -I$(GOBJECT_LIBDIR)/glib-2.0/include \
 	    -DGOBJECT_COMPILATION \
@@ -43,6 +58,13 @@
 # gio
 GIO_INCLUDEDIR=`pkg-config --variable=includedir gio-2.0`/glib-2.0
 GIO_LIBDIR=`pkg-config --variable=libdir gio-2.0`
+
+if OS_WIN32
+GIO_LIBRARY=libgio-2.0-0
+else
+GIO_LIBRARY=gio-2.0
+endif
+
 Gio.gir: GObject.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
 	PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \
 	    -v --namespace Gio \
@@ -50,7 +72,7 @@
 	    --output $@ \
 	    --strip-prefix=g \
             --include=$(top_builddir)/gir/GObject.gir \
-	    --library=gio-2.0 \
+	    --library=$(GIO_LIBRARY) \
 	    -I$(GIO_INCLUDEDIR) \
 	    -I$(GIO_LIBDIR)/glib-2.0/include \
 	    -DGIO_COMPILATION \
@@ -63,8 +85,8 @@
 girdir=$(datadir)/gir
 dist_gir_DATA = $(BUILT_SOURCES)
 
-%.typelib: %.gir $(top_builddir)/tools/g-ir-compiler
-	$(DEBUG) $(top_builddir)/tools/g-ir-compiler $< -o $@
+%.typelib: %.gir $(top_builddir)/tools/g-ir-compiler$(EXEEXT)
+	$(DEBUG) $(top_builddir)/tools/g-ir-compiler$(EXEEXT) $< -o $@
 
 typelibsdir = $(datadir)/girepository
 typelibs_DATA = GLib.typelib GObject.typelib Gio.typelib

Modified: trunk/girepository/Makefile.am
==============================================================================
--- trunk/girepository/Makefile.am	(original)
+++ trunk/girepository/Makefile.am	Wed Aug 27 13:33:21 2008
@@ -16,6 +16,7 @@
 	ginvoke.c
 libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS)
 libgirepository_la_LIBADD = $(GIREPO_LIBS)
+libgirepository_la_LDFLAGS = -no-undefined
 
 libgirepository_parser_la_SOURCES =		\
 	girmodule.c				\

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Wed Aug 27 13:33:21 2008
@@ -91,6 +91,7 @@
 static void
 backtrace_stderr (void)
 {
+#ifndef _WIN32
   void *array[50];
   int size;
   char **strings;
@@ -107,6 +108,7 @@
   fprintf (stderr, "--- END BACKTRACE ---\n", size);
 
   free (strings);
+#endif
 }
 
 

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Wed Aug 27 13:33:21 2008
@@ -141,31 +141,45 @@
 g_typelib_check_sanity (void)
 {
   /* Check that struct layout is as we expect */
-  g_assert (sizeof (Header) == 100);
-  g_assert (sizeof (DirEntry) == 12);
-  g_assert (sizeof (SimpleTypeBlob) == 4);
-  g_assert (sizeof (ArgBlob) == 12);
-  g_assert (sizeof (SignatureBlob) == 8);
-  g_assert (sizeof (CommonBlob) == 8);
-  g_assert (sizeof (FunctionBlob) == 16);
-  g_assert (sizeof (InterfaceTypeBlob) == 4);
-  g_assert (sizeof (ArrayTypeBlob) == 8);
-  g_assert (sizeof (ParamTypeBlob) == 4);
-  g_assert (sizeof (ErrorTypeBlob) == 4);
-  g_assert (sizeof (ErrorDomainBlob) == 16);
-  g_assert (sizeof (ValueBlob) == 12);
-  g_assert (sizeof (FieldBlob) == 12);
-  g_assert (sizeof (RegisteredTypeBlob) == 16);
-  g_assert (sizeof (StructBlob) == 20);
-  g_assert (sizeof (EnumBlob) == 20);
-  g_assert (sizeof (PropertyBlob) == 12);
-  g_assert (sizeof (SignalBlob) == 12);
-  g_assert (sizeof (VFuncBlob) == 16);
-  g_assert (sizeof (ObjectBlob) == 32);
-  g_assert (sizeof (InterfaceBlob) == 28);
-  g_assert (sizeof (ConstantBlob) == 20);
-  g_assert (sizeof (AnnotationBlob) == 12);
-  g_assert (sizeof (UnionBlob) == 28);
+
+  gboolean size_check_ok = TRUE;
+
+#define CHECK_SIZE(s,n) \
+  if (sizeof(s) != n) \
+    { \
+      g_printerr ("sizeof("#s") is expected to be %d but is %"G_GSIZE_FORMAT".\n", \
+		  n, sizeof (s));					\
+      size_check_ok = FALSE; \
+    }
+  
+  CHECK_SIZE (Header, 100);
+  CHECK_SIZE (DirEntry, 12);
+  CHECK_SIZE (SimpleTypeBlob, 4);
+  CHECK_SIZE (ArgBlob, 12);
+  CHECK_SIZE (SignatureBlob, 8);
+  CHECK_SIZE (CommonBlob, 8);
+  CHECK_SIZE (FunctionBlob, 16);
+  CHECK_SIZE (InterfaceTypeBlob, 4);
+  CHECK_SIZE (ArrayTypeBlob, 8);
+  CHECK_SIZE (ParamTypeBlob, 4);
+  CHECK_SIZE (ErrorTypeBlob, 4);
+  CHECK_SIZE (ErrorDomainBlob, 16);
+  CHECK_SIZE (ValueBlob, 12);
+  CHECK_SIZE (FieldBlob, 12);
+  CHECK_SIZE (RegisteredTypeBlob, 16);
+  CHECK_SIZE (StructBlob, 20);
+  CHECK_SIZE (EnumBlob, 20);
+  CHECK_SIZE (PropertyBlob, 12);
+  CHECK_SIZE (SignalBlob, 12);
+  CHECK_SIZE (VFuncBlob, 16);
+  CHECK_SIZE (ObjectBlob, 32);
+  CHECK_SIZE (InterfaceBlob, 28);
+  CHECK_SIZE (ConstantBlob, 20);
+  CHECK_SIZE (AnnotationBlob, 12);
+  CHECK_SIZE (UnionBlob, 28);
+#undef CHECK_SIZE
+
+  g_assert (size_check_ok);
 }
 
 

Modified: trunk/giscanner/Makefile.am
==============================================================================
--- trunk/giscanner/Makefile.am	(original)
+++ trunk/giscanner/Makefile.am	Wed Aug 27 13:33:21 2008
@@ -55,12 +55,33 @@
 	$(GOBJECT_CFLAGS) \
 	-I$(top_srcdir)/giscanner
 _giscanner_la_LIBADD = $(GOBJECT_LIBS) libgiscanner.la
+
 _giscanner_la_LDFLAGS = \
-	-module -avoid-version -export-symbols-regex init_giscanner
+	-module -avoid-version -export-symbols-regex init_giscanner -no-undefined
+
+if OS_WIN32
+# Yuck. Probably there is a way to get this from Python, but I don't
+# know how. Use -Wl to avoid libtool crack.
+_giscanner_la_LDFLAGS += -Wl,$(pyexecdir)/../../libs/libpython25.a
+endif
+
 _giscanner_la_SOURCES = giscannermodule.c
 
+if OS_WIN32
+BUILT_SOURCES += _giscanner.pyd
+CLEANFILES += _giscanner.pyd
+
+_giscanner.pyd: _giscanner.la
+	cp .libs/_giscanner.dll $@
+
+install-exec-hook:
+	mv $(pkgpyexecdir)/_giscanner.dll $(pkgpyexecdir)/_giscanner.pyd
+	rm $(pkgpyexecdir)/_giscanner.dll.a
+	rm $(pkgpyexecdir)/_giscanner.la
+else
 BUILT_SOURCES += _giscanner.so
 CLEANFILES += _giscanner.so
+endif
 
 # Yuck, ugly but...
 _giscanner.so: _giscanner.la

Modified: trunk/giscanner/cgobject.py
==============================================================================
--- trunk/giscanner/cgobject.py	(original)
+++ trunk/giscanner/cgobject.py	Wed Aug 27 13:33:21 2008
@@ -29,6 +29,7 @@
 # based on defsgen.py (C) 2006 John Finlay
 #
 
+import os
 import ctypes
 from ctypes.util import find_library
 
@@ -124,7 +125,10 @@
             yield self.param_types[i]
 
 
-_library_path = find_library('gobject-2.0')
+if os.name == 'nt':
+    _library_path = find_library('libgobject-2.0-0')
+else:
+    _library_path = find_library('gobject-2.0')
 if not _library_path:
     raise ImportError("Could not find gobject-2.0 library")
 _gobj = ctypes.CDLL(_library_path, ctypes.RTLD_GLOBAL)

Modified: trunk/giscanner/giscannermodule.c
==============================================================================
--- trunk/giscanner/giscannermodule.c	(original)
+++ trunk/giscanner/giscannermodule.c	Wed Aug 27 13:33:21 2008
@@ -25,6 +25,14 @@
 #include "sourcescanner.h"
 #include <Python.h>
 
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#define WIN32_LEAN_AND_MEAN
+#define STRICT
+#include <windows.h>
+#endif
+
 #define NEW_CLASS(ctype, name, cname)	      \
 static const PyMethodDef _Py##cname##_methods[];    \
 PyTypeObject Py##cname##_Type = {             \
@@ -393,6 +401,47 @@
   if (!PyArg_ParseTuple (args, "i:SourceScanner.parse_file", &fd))
     return NULL;
 
+#ifdef _WIN32
+  /* The file descriptor passed to us is from the C library Python
+   * uses. That is msvcr71.dll at least for Python 2.5. This code, at
+   * least if compiled with mingw, uses msvcrt.dll, so we cannot use
+   * the file descriptor directly. So perform appropriate magic.
+   */
+  {
+    HMODULE msvcr71;
+    int (*p__get_osfhandle) (int);
+    HANDLE handle;
+
+    msvcr71 = GetModuleHandle ("msvcr71.dll");
+    if (!msvcr71)
+      {
+	g_print ("No msvcr71.dll loaded.\n");
+	return NULL;
+      }
+
+    p__get_osfhandle = GetProcAddress (msvcr71, "_get_osfhandle");
+    if (!p__get_osfhandle)
+      {
+	g_print ("No _get_osfhandle found in msvcr71.dll.\n");
+	return NULL;
+      }
+
+    handle = p__get_osfhandle (fd);
+    if (!p__get_osfhandle)
+      {
+	g_print ("Could not get OS handle from msvcr71 fd.\n");
+	return NULL;
+      }
+    
+    fd = _open_osfhandle (handle, _O_RDONLY);
+    if (fd == -1)
+      {
+	g_print ("Could not open C fd from OS handle.\n");
+	return NULL;
+      }
+  }
+#endif
+
   fp = fdopen (fd, "r");
   if (!fp)
     {

Modified: trunk/giscanner/grealpath.h
==============================================================================
--- trunk/giscanner/grealpath.h	(original)
+++ trunk/giscanner/grealpath.h	Wed Aug 27 13:33:21 2008
@@ -10,11 +10,44 @@
 static inline gchar*
 g_realpath (const char *path)
 {
+#ifndef _WIN32
 	char buffer [PATH_MAX];
 	if (realpath(path, buffer))
 		return g_strdup(buffer);
 	else
 		return NULL;
+#else
+	/* We don't want to include <windows.h> as it clashes horribly
+	 * with token names from scannerparser.h. So just declare
+	 * GetFullPathNameA() here.
+	 */
+	extern __stdcall GetFullPathNameA(const char*, int, char*, char**);
+	char *buffer;
+	char dummy;
+	int rc, len;
+
+	rc = GetFullPathNameA(path, 1, &dummy, NULL);
+
+	if (rc == 0)
+	  {
+	    /* Weird failure, so just return the input path as such */
+	    return g_strdup(path);
+	  }
+
+	len = rc + 1;
+	buffer = g_malloc(len);
+
+	rc = GetFullPathNameA(path, len, buffer, NULL);
+
+	if (rc == 0 || rc > len)
+	  {
+	    /* Weird failure again */
+	    g_free(buffer);
+	    return g_strdup(path);
+	  }
+
+	return buffer;
+#endif
 }
 
 #endif

Modified: trunk/giscanner/scannerlexer.l
==============================================================================
--- trunk/giscanner/scannerlexer.l	(original)
+++ trunk/giscanner/scannerlexer.l	Wed Aug 27 13:33:21 2008
@@ -44,9 +44,10 @@
 static void parse_comment (GISourceScanner *scanner);
 static void process_directive (GISourceScanner *scanner);
 static int check_identifier (GISourceScanner *scanner, const char *);
+static int parse_attribute (void);
 %}
 
-intsuffix				([uU][lL]?)|([lL][uU]?)
+intsuffix				([uU][lL]?[lL]?)|([lL][lL]?[uU]?)
 fracconst				([0-9]*\.[0-9]+)|([0-9]+\.)
 exppart					[eE][-+]?[0-9]+
 floatsuffix				[fFlL]
@@ -117,6 +118,8 @@
 ","					{ return ','; }
 "->"					{ return ARROW; }
 
+"__attribute__" 			{ if (!parse_attribute()) REJECT; }
+
 [a-zA-Z_][a-zA-Z_0-9]*			{ if (scanner->macro_scan) return IDENTIFIER; else REJECT; }
 
 "auto"					{ return AUTO; }
@@ -137,6 +140,7 @@
 "goto"					{ return GOTO; }
 "if"					{ return IF; }
 "inline"				{ return INLINE; }
+"__inline__"				{ return INLINE; }
 "int"					{ return INT; }
 "long"					{ return LONG; }
 "register"				{ return REGISTER; }
@@ -405,3 +409,49 @@
 	g_string_free (filename_builder, TRUE);
 }
 
+static int
+parse_attribute (void)
+{
+	int c;
+	int nest;
+
+	while ((c = input ()) != EOF && isspace (c))
+		;
+	if (c != '(')
+		return FALSE;
+	while ((c = input ()) != EOF && isspace (c))
+		;
+	if (c != '(')
+		return FALSE;
+
+	nest = 0;
+	while ((c = input ()) != EOF && (nest > 0 || c != ')')) {
+		if (c == '(')
+			nest++;
+		else if (c == ')')
+			nest--;
+		else if (c == '"') {
+			while ((c = input ()) != EOF && c != '"') {
+				if (c == '\\')
+					c = input ();
+			}
+		} else if (c == '\'') {
+			c = input ();
+			if (c == '\\')
+				c = input ();
+			else if (c == '\'')
+				return FALSE;
+			c = input ();
+			if (c != '\'')
+				return FALSE;
+		} else if (c == '\n')
+			lineno++;
+	}
+
+	while ((c = input ()) != EOF && isspace (c))
+		;
+	if (c != ')')
+		return FALSE;
+
+	return TRUE;
+}

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Wed Aug 27 13:33:21 2008
@@ -231,7 +231,6 @@
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE)
 
-        proc.stdin.write('#define __attribute__(x)\n')
         proc.stdin.write('#define __const\n')
         proc.stdin.write('#define __extension__\n')
         proc.stdin.write('#define __inline\n')
@@ -260,4 +259,5 @@
         fp.seek(0, 0)
         assert proc, 'Proc was none'
         self._scanner.parse_file(fp.fileno())
+        fp.close()
         os.unlink(tmp)

Modified: trunk/tools/Makefile.am
==============================================================================
--- trunk/tools/Makefile.am	(original)
+++ trunk/tools/Makefile.am	Wed Aug 27 13:33:21 2008
@@ -10,15 +10,15 @@
 g_ir_compiler_SOURCES = compiler.c	
 g_ir_compiler_CFLAGS = $(GIREPO_CFLAGS)
 g_ir_compiler_LDADD = \
-	$(GIREPO_LIBS) \
+	$(top_builddir)/girepository/libgirepository-parser.la \
 	$(top_builddir)/girepository/libgirepository.la \
-	$(top_builddir)/girepository/libgirepository-parser.la
+	$(GIREPO_LIBS)
 
 g_ir_generate_SOURCES = generate.c
 g_ir_generate_CFLAGS = $(GIREPO_CFLAGS)
 g_ir_generate_LDADD = \
-	$(GIREPO_LIBS) \
-	$(top_builddir)/girepository/libgirepository.la
+	$(top_builddir)/girepository/libgirepository.la \
+	$(GIREPO_LIBS)
 
 GCOVSOURCES =					\
 	$(g_ir_compiler_SOURCES)		\

Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c	(original)
+++ trunk/tools/generate.c	Wed Aug 27 13:33:21 2008
@@ -20,7 +20,6 @@
  */
 
 #include <errno.h>
-#include <dlfcn.h>
 #include <string.h>
 
 #include <glib.h>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]