public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* MAX_PATH problems with mingw gcc
@ 2013-05-28 16:32 Simonov, Vladimir
  2013-10-16  8:52 ` Vladimir Simonov
  0 siblings, 1 reply; 2+ messages in thread
From: Simonov, Vladimir @ 2013-05-28 16:32 UTC (permalink / raw)
  To: gcc-help

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

Hi all,

Constructions #include "../../some_module/some_header.h" are quite
popular in our project. They lead to funny for Linux user problem
which becomes real headache when we build the project by mingw based
cross gcc.

Several levels of such "include" may easy exceed Windows MAX_PATH
limitation for file I/O functions (260 symbols).

For example
g:/w/project1/product1/bundle/console/mv_system/centralized/dialogs/selectors/../../../../machines/dialogs/selectors/../../../components/machines/browsers/tree_based_group_browser/../../../hierarchy_model_browser/hierarchy_model_browser.h:37:61: fatal error: ../../remote/async_invokers/client/async_action.h: No such file or directory
 #include "../../remote/async_invokers/client/async_action.h"

As you see gcc tries to open 
g:/w/project1/product1/bundle/console/mv_system/centralized/dialogs/selectors/../../../../machines/dialogs/selectors/../../../components/machines/browsers/tree_based_group_browser/../../../hierarchy_model_browser/../../remote/async_invokers/client/async_action.h
which length is 263 symbols.

IMO the best solution would be to switch on Unicode version of
file IO functions in libiberty but it is quite radical change.

Attaching patch which works for me many years and illustrates another approach.
Its main idea is to simplify paths in some key places working with filenames
(libcpp, parse_include in directives.c and find_file_in_dir in files.c).
With this patch code above compiles OK.

There are many pro and contras, i.e. it adds additional, probably unnecessary
work on Linux time but makes filenames shorter, it affects libiberty which is
shared between gcc/binutils/gdb, but it may be useful in other packages, etc., etc.

Anyway I'll be glad to hear any comments and may be to see some fix for above
problem in gcc code.

Best regards
Vladimir Simonov


[-- Attachment #2: gcc-4.8.0-filename-normalize.patch --]
[-- Type: application/octet-stream, Size: 3841 bytes --]

--- gcc-4.8.0/include/filenames.h.orig	2013-05-21 00:29:29.852193269 +0400
+++ gcc-4.8.0/include/filenames.h	2013-05-21 00:31:02.498193187 +0400
@@ -86,6 +86,9 @@
 extern int filename_ncmp (const char *s1, const char *s2,
 			  size_t n);
 
+extern void filename_normalize (char *f);
+#define FILENAME_NORMALIZE(f)  filename_normalize(f)
+
 extern hashval_t filename_hash (const void *s);
 
 extern int filename_eq (const void *s1, const void *s2);
--- gcc-4.8.0/libiberty/filename_cmp.c.orig	2013-05-21 00:31:38.417200064 +0400
+++ gcc-4.8.0/libiberty/filename_cmp.c	2013-05-21 00:36:44.331191266 +0400
@@ -142,6 +142,118 @@
 #endif
 }
 
+#ifdef HAVE_MEMMOVE
+#define memmove_left memmove
+#else
+static void *
+memmove_left (void *dest, const void *src, int n)
+{
+  char *d;
+  const char *s;
+  int i;
+  for (d = (char *)dest, s = (const char *)src, i = 0; i < n; i++)
+    *d++ = *s++;
+}
+#endif
+
+/*
+
+@deftypefn Extension void filename_normalize (char *@var{fn})
+
+This function tries to normalize files names inplace.
+
+@end deftypefn
+
+*/
+
+#ifndef HAVE_DOS_BASED_FILE_SYSTEM
+void
+filename_normalize (char *fn)
+#else
+static void
+filename_normalize_unix (char *fn)
+#endif
+{
+  char *p;
+  int rest;
+
+  rest = strlen (fn) + 1;
+  for (p = fn; *p != '\0' ; p++, rest--)
+    {
+      char *next;
+      const char *next2;
+      const char *next3;
+
+      next = p + 1;
+      if (*next == '\0')
+        break;
+      if (!IS_DIR_SEPARATOR( *p))
+          continue;
+      next2 = p + 2;
+      next3 = p + 3;
+      *p = '/';
+      /* don't handle some special cases, i.e. "//C/" on Microsoft Windows */
+      if (IS_DIR_SEPARATOR (*next))
+        {
+          memmove_left (next, next2, rest - 2);
+          p--;
+          continue;
+        }
+      if (*next != '.' || *next2 == '\0' || *next3 == '\0')
+          continue;
+      /* simplify "./" case */
+      if (IS_DIR_SEPARATOR (*next2))
+        {
+          memmove_left (next, next3, rest - 3);
+          rest--;
+          p--;
+          continue;
+        }
+      if (*next2 != '.' || ! IS_DIR_SEPARATOR (*next3))
+        continue;
+      while (--p >= fn)
+        {
+          if (*p == '/')
+            break;
+        }
+      if (p < fn)
+        {
+          if (*fn == '/')
+              memmove_left (p + 2, next3 + 1, rest - 4);
+          else if (*fn != '.')
+              memmove_left (p + 1, next3 + 1, rest - 4);
+          else
+            {
+              p = next - 1;
+              continue;
+            }
+        }
+      else if (*(p + 1) != '.')
+        {
+          memmove_left (p + 1, next3 + 1, rest - 4);
+          p--;
+        }
+      else
+        {
+          p = next - 1;
+          continue;
+        }
+      rest -= 2;
+    }
+}
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+void
+filename_normalize (char *fn)
+{
+  if (IS_DIR_SEPARATOR (fn[0]) || ! IS_ABSOLUTE_PATH (fn))
+    /* Absolute path in Unix style or relative path */
+    filename_normalize_unix (fn);
+  else if (fn[1] != '\0')
+    filename_normalize_unix (fn + 2);
+}
+#endif
+
 /*
 
 @deftypefn Extension hashval_t filename_hash (const void *@var{s})
--- gcc-4.8.0/libcpp/directives.c.orig	2013-05-21 00:37:42.314192589 +0400
+++ gcc-4.8.0/libcpp/directives.c	2013-05-21 00:39:41.656192831 +0400
@@ -729,6 +729,7 @@
       return NULL;
     }
 
+  FILENAME_NORMALIZE (fname);
   if (pfile->directive == &dtable[T_PRAGMA])
     {
       /* This pragma allows extra tokens after the file name.  */
--- gcc-4.8.0/libcpp/files.c.orig	2013-05-27 11:41:07 +0400
+++ gcc-4.8.0/libcpp/files.c	2013-05-27 11:11:18 +0400
@@ -387,6 +387,7 @@
       char *copy;
       void **pp;
 
+      FILENAME_NORMALIZE (path);
       /* We try to canonicalize system headers.  */
       if (CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp)
 	{

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

* RE: MAX_PATH problems with mingw gcc
  2013-05-28 16:32 MAX_PATH problems with mingw gcc Simonov, Vladimir
@ 2013-10-16  8:52 ` Vladimir Simonov
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir Simonov @ 2013-10-16  8:52 UTC (permalink / raw)
  To: Jiri Dobry, 'gcc-help@gcc.gnu.org'

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

Hi all,

Sending new version of filename-normalize patch because people asking to make it public.

This version also fixes problems with gcov support of Linux binaries crosscompiled on Windows.
Problem: If you do crossbuild with gcov support, binaries refer gcda files like C:\Myproject\Mydir\Myobj.gcda.
After run on Linux files with names  like "C:\Myproject\Mydir\Myobj.gcda" are created.
No any directory tree.
The last chunk of new patch fixes this.

Best regards
Vladimir Simonov

-----Original Message-----
From: Simonov, Vladimir 
Sent: Monday, May 27, 2013 8:15 PM
To: gcc-help@gcc.gnu.org
Subject: MAX_PATH problems with mingw gcc

Hi all,

Constructions #include "../../some_module/some_header.h" are quite popular in our project. They lead to funny for Linux user problem which becomes real headache when we build the project by mingw based cross gcc.

Several levels of such "include" may easy exceed Windows MAX_PATH limitation for file I/O functions (260 symbols).

For example
g:/w/project1/product1/bundle/console/mv_system/centralized/dialogs/selectors/../../../../machines/dialogs/selectors/../../../components/machines/browsers/tree_based_group_browser/../../../hierarchy_model_browser/hierarchy_model_browser.h:37:61: fatal error: ../../remote/async_invokers/client/async_action.h: No such file or directory  #include "../../remote/async_invokers/client/async_action.h"

As you see gcc tries to open
g:/w/project1/product1/bundle/console/mv_system/centralized/dialogs/selectors/../../../../machines/dialogs/selectors/../../../components/machines/browsers/tree_based_group_browser/../../../hierarchy_model_browser/../../remote/async_invokers/client/async_action.h
which length is 263 symbols.

IMO the best solution would be to switch on Unicode version of file IO functions in libiberty but it is quite radical change.

Attaching patch which works for me many years and illustrates another approach.
Its main idea is to simplify paths in some key places working with filenames (libcpp, parse_include in directives.c and find_file_in_dir in files.c).
With this patch code above compiles OK.

There are many pro and contras, i.e. it adds additional, probably unnecessary work on Linux time but makes filenames shorter, it affects libiberty which is shared between gcc/binutils/gdb, but it may be useful in other packages, etc., etc.

Anyway I'll be glad to hear any comments and may be to see some fix for above problem in gcc code.

Best regards
Vladimir Simonov


[-- Attachment #2: gcc-4.8.1-filename-normalize.patch --]
[-- Type: application/octet-stream, Size: 4354 bytes --]

--- gcc-4.8.0/include/filenames.h.orig	2013-05-21 00:29:29.852193269 +0400
+++ gcc-4.8.0/include/filenames.h	2013-05-21 00:31:02.498193187 +0400
@@ -86,6 +86,9 @@
 extern int filename_ncmp (const char *s1, const char *s2,
 			  size_t n);
 
+extern void filename_normalize (char *f);
+#define FILENAME_NORMALIZE(f)  filename_normalize(f)
+
 extern hashval_t filename_hash (const void *s);
 
 extern int filename_eq (const void *s1, const void *s2);
--- gcc-4.8.0/libiberty/filename_cmp.c.orig	2013-05-21 00:31:38.417200064 +0400
+++ gcc-4.8.0/libiberty/filename_cmp.c	2013-05-21 00:36:44.331191266 +0400
@@ -142,6 +142,118 @@
 #endif
 }
 
+#ifdef HAVE_MEMMOVE
+#define memmove_left memmove
+#else
+static void *
+memmove_left (void *dest, const void *src, int n)
+{
+  char *d;
+  const char *s;
+  int i;
+  for (d = (char *)dest, s = (const char *)src, i = 0; i < n; i++)
+    *d++ = *s++;
+}
+#endif
+
+/*
+
+@deftypefn Extension void filename_normalize (char *@var{fn})
+
+This function tries to normalize files names inplace.
+
+@end deftypefn
+
+*/
+
+#ifndef HAVE_DOS_BASED_FILE_SYSTEM
+void
+filename_normalize (char *fn)
+#else
+static void
+filename_normalize_unix (char *fn)
+#endif
+{
+  char *p;
+  int rest;
+
+  rest = strlen (fn) + 1;
+  for (p = fn; *p != '\0' ; p++, rest--)
+    {
+      char *next;
+      const char *next2;
+      const char *next3;
+
+      next = p + 1;
+      if (*next == '\0')
+        break;
+      if (!IS_DIR_SEPARATOR( *p))
+          continue;
+      next2 = p + 2;
+      next3 = p + 3;
+      *p = '/';
+      /* don't handle some special cases, i.e. "//C/" on Microsoft Windows */
+      if (IS_DIR_SEPARATOR (*next))
+        {
+          memmove_left (next, next2, rest - 2);
+          p--;
+          continue;
+        }
+      if (*next != '.' || *next2 == '\0' || *next3 == '\0')
+          continue;
+      /* simplify "./" case */
+      if (IS_DIR_SEPARATOR (*next2))
+        {
+          memmove_left (next, next3, rest - 3);
+          rest--;
+          p--;
+          continue;
+        }
+      if (*next2 != '.' || ! IS_DIR_SEPARATOR (*next3))
+        continue;
+      while (--p >= fn)
+        {
+          if (*p == '/')
+            break;
+        }
+      if (p < fn)
+        {
+          if (*fn == '/')
+              memmove_left (p + 2, next3 + 1, rest - 4);
+          else if (*fn != '.')
+              memmove_left (p + 1, next3 + 1, rest - 4);
+          else
+            {
+              p = next - 1;
+              continue;
+            }
+        }
+      else if (*(p + 1) != '.')
+        {
+          memmove_left (p + 1, next3 + 1, rest - 4);
+          p--;
+        }
+      else
+        {
+          p = next - 1;
+          continue;
+        }
+      rest -= 2;
+    }
+}
+
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+void
+filename_normalize (char *fn)
+{
+  if (IS_DIR_SEPARATOR (fn[0]) || ! IS_ABSOLUTE_PATH (fn))
+    /* Absolute path in Unix style or relative path */
+    filename_normalize_unix (fn);
+  else if (fn[1] != '\0')
+    filename_normalize_unix (fn + 2);
+}
+#endif
+
 /*
 
 @deftypefn Extension hashval_t filename_hash (const void *@var{s})
--- gcc-4.8.0/libcpp/directives.c.orig	2013-05-21 00:37:42.314192589 +0400
+++ gcc-4.8.0/libcpp/directives.c	2013-05-21 00:39:41.656192831 +0400
@@ -729,6 +729,7 @@
       return NULL;
     }
 
+  FILENAME_NORMALIZE (fname);
   if (pfile->directive == &dtable[T_PRAGMA])
     {
       /* This pragma allows extra tokens after the file name.  */
--- gcc-4.8.0/libcpp/files.c.orig	2013-05-27 11:41:07 +0400
+++ gcc-4.8.0/libcpp/files.c	2013-05-27 11:11:18 +0400
@@ -387,6 +387,7 @@
       char *copy;
       void **pp;
 
+      FILENAME_NORMALIZE (path);
       /* We try to canonicalize system headers.  */
       if (CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp)
 	{
--- gcc-4.8.1/libiberty/getpwd.c.orig	2005-05-25 00:48:25 +0400
+++ gcc-4.8.1/libiberty/getpwd.c	2013-08-23 23:21:04 +0400
@@ -107,6 +107,8 @@
 
 #else	/* VMS || _WIN32 && !__CYGWIN__ */
 
+#include "filenames.h"
+
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 255
 #endif
@@ -117,11 +119,15 @@
   static char *pwd = 0;
 
   if (!pwd)
+    {
     pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
 #ifdef VMS
 		  , 0
 #endif
 		  );
+    if (pwd)
+      FILENAME_NORMALIZE (pwd);
+    }
   return pwd;
 }
 

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

end of thread, other threads:[~2013-10-16  8:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-28 16:32 MAX_PATH problems with mingw gcc Simonov, Vladimir
2013-10-16  8:52 ` Vladimir Simonov

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).