Package: guile;
Reported by: Andy Wingo <wingo <at> pobox.com>
Date: Tue, 10 Jan 2012 21:59:02 UTC
Severity: normal
Done: Andy Wingo <wingo <at> pobox.com>
Bug is archived. No further changes may be made.
Message #14 received at 10474 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: wingo <at> pobox.com, commander.sirow <at> googlemail.com Cc: 10474 <at> debbugs.gnu.org Subject: Re: bug#10474: Building guile 2.x under mingw + msys Date: Tue, 17 Jan 2012 20:14:58 +0200
> Date: Tue, 17 Jan 2012 10:09:21 +0200 > From: Eli Zaretskii <eliz <at> gnu.org> > CC: commander.sirow <at> googlemail.com, 10474 <at> debbugs.gnu.org > > The problem, AFAIK, is entirely different and quite mundane: > canonicalize_file_name simply does not support Windows-style > D:/foo/bar file names, nor does it support backslashes as separators > in file names. > > My evidence is that I added an fprintf to canonicalize-path where it > calls canonicalize_file_name, and the file name passed to it was > entirely reasonable, something like > > D:\path\to\guile-2.03/module/ice-9/boot-9.scm > > (or some such, I'm writing this from my faulty memory). > > I think I know how to fix canonicalize_file_name, and I will send a > tentative patch later, perhaps even today, when I have it working and > get past this abort. The patch to fix canonicalize_file_name is below. It gets me through the "GEN guile-procedures.texi" step. The next failure is this: GEN guile-procedures.texi Backtrace: In unknown file: ?: 3 [boot-closure #t #<catch-closure 2903300> ...] ?: 2 [catch-closure] ?: 1 [primitive-eval ((@ # %) (begin # # #))] ?: 0 [primitive-load-path "d:\\usr\\eli\\utils\\guile-2.0.3\\libguile/d:/usr/eli/utils/guile-2.0.3/meta/guild"] ERROR: In procedure primitive-load-path: ERROR: In procedure canonicalize-path: No such file or directory which again looks like failure to treat d:/foo/bar file names as absolute. Some random poking around reveals this in ice-9/boot-9.scm: (define (absolute-path? path) (string-prefix? "/" path)) which looks a likely culprit. Changing it to recognize d:/foo/bar absolute file names indeed solves this problem. (I'm too embarrassed to show the changes I did for that, as I know nothing about Scheme, and my code is too ugly to go into upstream. I don't even know how to condition the change on the underlying platform being MS-Windows.) The next problem is here: GUILEC ice-9/eval.go Backtrace: In unknown file: ?: 5 [boot-closure #t #<catch-closure 231fd40> ...] ?: 4 [catch-closure] ?: 3 [primitive-eval ((@ # %) (begin # # #))] ?: 2 [chmod #<input-output: ice-9/eval.go.9IiPxC 6> 438] ?: 1 [boot-closure system-error "chmod" ...] ?: 0 [delete-file "ice-9/eval.go.9IiPxC"] ERROR: In procedure delete-file: ERROR: In procedure delete-file: Permission denied This happens because Guile calls fchmod, which is #define'd to -1 on MinGW. Solution: #define it to zero, since chmod is mostly a no-op on Windows anyway. This passes the eval.go step (and then fails while compiling psyntax-pp.go; to be continued...). As an aside, if this kind of operation is a frequent one, I'd suggest to change the caller so that it never uses fchmod on MS-Windows, because this function cannot be implemented there, except on the latest versions (Windows 7 etc.). Use chmod instead, even if that is less efficient. Btw, why doesn't the backtrace show file names, but says "unknown file"? Is this expected during the build, or is there another bug to look for? If the latter, any hints as to where to look for the reason(s)? Here's the patch for canonicalize-lgpl.c to make it Windows-friendly. I will send it to the gnulib developers as well. --- lib/canonicalize-lgpl.c~0 2011-10-22 16:19:34.000000000 +0200 +++ lib/canonicalize-lgpl.c 2012-01-17 13:10:52.608428500 +0200 @@ -51,6 +51,7 @@ # define __realpath realpath # include "pathmax.h" # include "malloca.h" +# include "dosname.h" # if HAVE_GETCWD # if IN_RELOCWRAPPER /* When building the relocatable program wrapper, use the system's getcwd @@ -101,6 +102,7 @@ __realpath (const char *name, char *reso const char *start, *end, *rpath_limit; long int path_max; int num_links = 0; + size_t prefix_len; if (name == NULL) { @@ -143,7 +145,11 @@ __realpath (const char *name, char *reso rpath = resolved; rpath_limit = rpath + path_max; - if (name[0] != '/') + /* This is always zero for Posix hosts, but can be 2 for MS-Windows + and MS-DOS X:/foo/bar file names. */ + prefix_len = FILE_SYSTEM_PREFIX_LEN (name); + + if (!IS_ABSOLUTE_FILE_NAME (name)) { if (!__getcwd (rpath, path_max)) { @@ -154,13 +160,19 @@ __realpath (const char *name, char *reso } else { - rpath[0] = '/'; - dest = rpath + 1; - if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/') + dest = rpath; + if (prefix_len) + { + memcpy (rpath, name, prefix_len); + dest += prefix_len; + } + *dest++ = '/'; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && ISSLASH (name[1]) + && !prefix_len) *dest++ = '/'; } - for (start = end = name; *start; start = end) + for (start = end = name + prefix_len; *start; start = end) { #ifdef _LIBC struct stat64 st; @@ -170,11 +182,11 @@ __realpath (const char *name, char *reso int n; /* Skip sequence of multiple path-separators. */ - while (*start == '/') + while (ISSLASH (*start)) ++start; /* Find end of path component. */ - for (end = start; *end && *end != '/'; ++end) + for (end = start; *end && !ISSLASH (*end); ++end) /* Nothing. */; if (end - start == 0) @@ -184,7 +196,7 @@ __realpath (const char *name, char *reso else if (end - start == 2 && start[0] == '.' && start[1] == '.') { /* Back up to previous component, ignore if at root already. */ - if (dest > rpath + 1) + if (dest > rpath + prefix_len + 1) while ((--dest)[-1] != '/'); if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && *dest == '/') @@ -205,7 +217,7 @@ __realpath (const char *name, char *reso if (resolved) { __set_errno (ENAMETOOLONG); - if (dest > rpath + 1) + if (dest > rpath + prefix_len + 1) dest--; *dest = '\0'; goto error; @@ -295,17 +307,25 @@ __realpath (const char *name, char *reso memmove (&extra_buf[n], end, len + 1); name = end = memcpy (extra_buf, buf, n); - if (buf[0] == '/') + if (IS_ABSOLUTE_FILE_NAME (buf)) { - dest = rpath + 1; /* It's an absolute symlink */ - if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/') + size_t pfxlen = FILE_SYSTEM_PREFIX_LEN (buf); + + if (pfxlen) + memcpy (rpath, buf, pfxlen); + dest = rpath + pfxlen; /* It's an absolute symlink. */ + *dest++ = '/'; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && ISSLASH (buf[1]) + && pfxlen == 0) *dest++ = '/'; + /* Install the new prefix to be in effect hereafter. */ + prefix_len = pfxlen; } else { /* Back up to previous component, ignore if at root already: */ - if (dest > rpath + 1) + if (dest > rpath + prefix_len + 1) while ((--dest)[-1] != '/'); if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && *dest == '/') @@ -319,7 +339,7 @@ __realpath (const char *name, char *reso } } } - if (dest > rpath + 1 && dest[-1] == '/') + if (dest > rpath + prefix_len + 1 && dest[-1] == '/') --dest; if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && *dest == '/') dest++;
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.