unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Mingw support.
@ 2010-02-24 20:56 carlo.bramix
  2010-03-01 21:07 ` Neil Jerram
  0 siblings, 1 reply; 2+ messages in thread
From: carlo.bramix @ 2010-02-24 20:56 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 3105 bytes --]

Hello,
after an hard work I was able to get an almost working build of the most recent guile.
In the attached patch there are some little fixes and a bigger one, an almost complete and working implementation of posix mmap()/munmap() for Windows: this will allow you a single source code to be easily modified for both POSIX and WIN32 solutions.
This code has been also tested separately and I have not found any problem.
This patch corrects the most urgent problem but it is not enough for compiling guile completely working.
I found some difficult problems that I corrected with some hacks into the source and, obviously, not included in the attached patch.




libguile/dynl.c and libguile/foreing.c generate an error like this one:

../../guile-1.9.8/libguile/dynl.c:304: error: for each function it appears in.)
../../guile-1.9.8/libguile/dynl.c: In function 'scm_dynamic_args_call':
../../guile-1.9.8/libguile/dynl.c:334: error: 'SCM_FOREIGN_TYPE_void' undeclared
 (first use in this function)
make[3]: *** [dynl.lo] Error 1

This problem happens because the Windows includes declare the VOID macro to be an alias of void.
One line of code explains it better:

#define VOID    void

So, when combining with ## operator, SCM_FOREIGN_TYPE_ + VOID does not creates SCM_FOREIGN_TYPE_VOID but SCM_FOREIGN_TYPE_void.
There was no much that I could do to avoid this, except adding an "#undef VOID" after all inclusions.



After that, I got this error.

libtool: link: gcc -std=gnu99 -Wall -Wmissing-prototypes -Wdeclaration-after-statement -Wundef -Wswitch-enum -fvisibility=hidden -Ic:/mingw/include -g -O2 -o .libs/guile_filter_doc_snarfage.exe c-tokenize.o  -Lc:/mingw/lib /mingw/lib/libgc.dll.a /mingw/lib/libatomic_ops.dll.a /mingw/lib/libregex.dll.a /mingw/lib/libunistring.dll.a /mingw/lib/libiconv.dll.a -lcrypt -lws2_32 /mingw/lib/libltdl.dll.a -L/mingw/lib
c-tokenize.o: In function `yyalloc':
C:\msys\1.0\home\Carlo\guile\libguile/<stdout>:2177: undefined reference to `rpl_malloc'
collect2: ld returned 1 exit status

It seems to me that there is a missing libguile.la dependency.
I'm not sure where it would be better to touch, so I hacked generated Makefile without touching Makefile.am yet.
Anyways, adding libguile.la solved the trouble.




Finally, when all things seemed to work correctly, I got this message when compiling.

make[2]: Entering directory `/home/Carlo/guile/module'
GUILE_AUTO_COMPILE=0                                    \
        ../meta/uninstalled-env                 \
        guile-tools compile -Wunbound-variable -Warity-mismatch -o "ice-9/eval.g
o" "../../guile-1.9.8/module/ice-9/eval.scm"
ERROR: In procedure delete-file:
ERROR: Permission denied
make[2]: *** [ice-9/eval.go] Error 1

Actually, this just means to me that there is at least one file descriptor still open and valid when _unlink() function is called.
It could be a plain file handle or a memory mapped object.
Have you some suggestions to give me for testing this?




I hope all this will be useful.

Sincerely,

Carlo Bramini.


[-- Attachment #2: libguile-1.9.8.txt --]
[-- Type: text/plain, Size: 5810 bytes --]

diff -r -u guile-1.9.8-old/libguile/deprecated.c guile-1.9.8-new/libguile/deprecated.c
--- guile-1.9.8-old/libguile/deprecated.c	2010-01-22 09:16:50 +0000
+++ guile-1.9.8-new/libguile/deprecated.c	2010-02-22 17:12:20 +0000
@@ -1640,7 +1640,7 @@
 \f
 /* Networking.  */
 
-#ifdef HAVE_NETWORKING
+#if defined HAVE_NETWORKING && defined HAVE_IPV6
 
 SCM_DEFINE (scm_inet_aton, "inet-aton", 1, 0, 0,
             (SCM address),
diff -r -u guile-1.9.8-old/libguile/filesys.c guile-1.9.8-new/libguile/filesys.c
--- guile-1.9.8-old/libguile/filesys.c	2010-01-22 09:16:50 +0000
+++ guile-1.9.8-new/libguile/filesys.c	2010-02-24 20:06:47 +0000
@@ -117,7 +117,8 @@
 
 /* Some more definitions for the native Windows port. */
 #ifdef __MINGW32__
-# define mkdir(path, mode) mkdir (path)
+# undef mkdir
+# define mkdir(path, mode) _mkdir (path)
 # define fsync(fd) _commit (fd)
 # define fchmod(fd, mode) (-1)
 #endif /* __MINGW32__ */
@@ -515,6 +516,11 @@
  * under Windows. It differentiates between file, pipe and socket 
  * descriptors.
  */
+
+#ifndef _S_IFSOCK
+#define _S_IFSOCK   0140000
+#endif
+
 static int fstat_Win32 (int fdes, struct stat *buf)
 {
   int error, optlen = sizeof (int);
diff -r -u guile-1.9.8-old/libguile/objcodes.c guile-1.9.8-new/libguile/objcodes.c
--- guile-1.9.8-old/libguile/objcodes.c	2010-01-11 22:21:17 +0000
+++ guile-1.9.8-new/libguile/objcodes.c	2010-02-22 17:16:59 +0000
@@ -22,8 +22,10 @@
 
 #include <string.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
+#include <unistd.h>
+#if HAVE_SYS_MMAN_H
+#  include <sys/mman.h>
+#endif
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <assert.h>
@@ -38,6 +40,156 @@
 verify (((sizeof (SCM_OBJCODE_COOKIE) - 1) & 7) == 0);
 
 \f
+
+#ifdef _WIN32
+
+/*
+ * Implementation of mmap()/munmap() replacement for Windows.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define PROT_READ   0x0001
+#define PROT_WRITE  0x0002
+#define PROT_EXEC   0x0004
+#define PROT_NONE   0x0008
+
+#define MAP_SHARED  0x0001
+#define MAP_PRIVATE 0x0002
+#define MAP_FIXED   0x0004
+
+#define MAP_FAILED  ((void *)-1)
+
+typedef struct {
+    unsigned int prot_flag;
+    DWORD        win_flag;
+} Protection_Scheme_t;
+
+typedef struct _MapList_t {
+    HANDLE             hMap;
+    void              *Base;
+    struct _MapList_t *Next;
+} MapList_t;
+
+static const Protection_Scheme_t Protection_Scheme[] = {
+    { PROT_READ,                      PAGE_READONLY          },
+    { PROT_READ|PROT_WRITE,           PAGE_READWRITE         },
+    { PROT_READ|PROT_WRITE|PROT_EXEC, PAGE_EXECUTE_READWRITE },
+    { PROT_EXEC,                      PAGE_EXECUTE           },
+    { PROT_READ|PROT_EXEC,            PAGE_EXECUTE_READ      },
+};
+
+static MapList_t *MapList = NULL;
+
+static void *mmap(unsigned int address,
+                  unsigned int size,
+                  unsigned int protection,
+                  unsigned int flags,
+                  int          fd,
+                  int          offset)
+{
+  HANDLE       hFile, hMapFile;
+  DWORD        dwProtect, dwAccess;
+  void        *Base;
+  MapList_t   *Item;
+  unsigned int x;
+
+  /* Check if fd is valid */
+  if (fd == -1)
+    return MAP_FAILED;
+
+  /* Retrieve system handle from fd */
+  hFile = (HANDLE)_get_osfhandle(fd);
+  if (hFile == INVALID_HANDLE_VALUE)
+    return MAP_FAILED;
+
+  /* Search protection schemes */
+  for (dwProtect=PAGE_NOACCESS, x=0;
+       x < (sizeof(Protection_Scheme)/sizeof(Protection_Scheme_t));
+       x++)
+  {
+    if (Protection_Scheme[x].prot_flag == protection)
+    {
+      dwProtect = Protection_Scheme[x].win_flag;
+      break;
+    }
+  }
+
+  if (flags & MAP_PRIVATE) {
+    dwAccess = FILE_MAP_COPY;
+    dwProtect = PAGE_WRITECOPY;
+  } else
+  if ((protection & PROT_WRITE))
+    dwAccess = FILE_MAP_WRITE;
+  else
+    dwAccess = FILE_MAP_READ;
+
+  /* Create mapping object */
+  hMapFile = CreateFileMapping(hFile, NULL, dwProtect, 0, size, NULL);
+  if (hMapFile == INVALID_HANDLE_VALUE)
+    return MAP_FAILED;
+
+  /* Select which portions of the file we need (entire file) */
+  Base = MapViewOfFile(hMapFile, dwAccess, 0, offset, size);
+
+  if (Base == NULL) {
+    /* Free the mapping object */
+    CloseHandle(hMapFile);
+    return MAP_FAILED;
+  }
+
+  /* Allocate item for list mmaps... */
+  Item = (MapList_t *)malloc(sizeof(MapList_t));
+  if (Item == NULL) {
+    UnmapViewOfFile(Base);
+    CloseHandle(hMapFile);
+
+    return MAP_FAILED;
+  }
+
+  Item->hMap = hMapFile;
+  Item->Base = Base;
+  Item->Next = MapList;
+
+  if (MapList == NULL)
+    MapList = Item;
+
+  return Base;
+}
+
+static int munmap(void *addr, unsigned int size)
+{
+  MapList_t *Item, *Prev;
+
+  Prev = NULL;
+  Item = MapList;
+
+  while (Item != NULL) {
+    if (Item->Base == addr) {
+      UnmapViewOfFile(Item->Base);
+      CloseHandle(Item->hMap);
+
+      /* Delete this item from linked list */
+      if (Prev != NULL)
+        Prev->Next = Item->Next;
+      else
+        MapList = Item->Next;
+
+      free(Item);
+
+      return 0;
+    }
+    Prev = Item;
+    Item = Item->Next;
+  }
+
+  return -1;
+}
+
+#endif /* _WIN32 */
+
+
 /*
  * Objcode type
  */
diff -r -u guile-1.9.8-old/libguile/socket.c guile-1.9.8-new/libguile/socket.c
--- guile-1.9.8-old/libguile/socket.c	2009-11-26 09:18:09 +0000
+++ guile-1.9.8-new/libguile/socket.c	2010-02-22 17:17:50 +0000
@@ -56,6 +56,7 @@
 #include <sys/types.h>
 #ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
+#include <ws2tcpip.h>
 #else
 #include <sys/socket.h>
 #ifdef HAVE_UNIX_DOMAIN_SOCKETS


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-03-01 21:07 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-24 20:56 Mingw support carlo.bramix
2010-03-01 21:07 ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).