[ccache] [PATCH] flag for using relative directories

2009-09-10 Thread yince

Hi, I'm new to ccache and was asking myself the question:
how ccache handles the -I directives.

Your solution is good.
I tough ccache would ignore the -I option since it affects 
only the preprocessor  and ccache use it to build the hash.

Would it be correct and safe to have an option to ignore -I option ?

Regards,
Vincent


Andrea Bittau wrote:
> 
> It is common for developers in a shared environment to compile the same
> code, but in a different location [e.g. their home] and furthermore, to
> use absolute path-names in their includes flags.  This results in two
> different outputs from the preprocessor, even though the same file is
> included [just different path], making it impossible to share a cache.
> CCACHE_UNIFY could be used to get rid of the comments from the
> preprocessor, but the problem here is of different nature: we do not
> wish to UNIFY, and have side-effects such as wrong line information, but
> rather just use relative paths so that the output of two preprocesses is
> the same.
> 
> I've added a new boolean, CCACHE_RELATIVE that will modify all the -I
> flags to be relative directories from where ccache is called.  An
> absolute pathname will be retained if the "common root" between the
> working directory and the included path is "/".  For example, the
> following command line:
> /home/sorbo$ gcc -I/common/stuff -I/home/sorbo/includes
> will be translated to:
> /home/sorbo$ gcc -I/common/stuff -Iincludes
> 
> Please consider applying this patch or implementing similar
> functionality.  This scenario is very common in many work places.  The
> patch is against ccache v2.4.
> 
> This has discussed on this mailing list to some extent, but I am unable
> to see attached patches from the web archive, so I had to code something
> myself.  Also, I don't know what happened to the proposed patches, so I
> just redid the work.  References:
> 
> 1) Steve Bennet "[ccache] [PATCH] Better cache reuse across builds in
> separate trees":
> http://lists.samba.org/archive/ccache/2005q2/000167.html
> 
> 2) Chris Swiedler "[ccache] ccache and -g"
> http://lists.samba.org/archive/ccache/2006q1/000201.html
> 
> ---
> 
> diff -rup ccache-2.4.orig/ccache.c ccache-2.4/ccache.c
> --- ccache-2.4.orig/ccache.c  2004-09-13 11:38:30.0 +0100
> +++ ccache-2.4/ccache.c   2007-06-18 15:10:05.0 +0100
> @@ -615,6 +615,119 @@ static const char *check_extension(const
>   return NULL;
>  }
>  
> +/* Transform an incldue path to relative, so that we get more hits */
> +static char *relative(char *path)
> +{
> + static char result[PATH_MAX];
> + static char *cwd;
> + char *proot, *pp;
> + char *croot, *cp;
> + char *rp;
> +
> + /* path is relative */
> + if (*path != '/')
> + return path;
> +
> + rp = x_realpath(path);
> + if (!rp) {
> + /* we got two options:
> +1) remove the -I.  gcc works with inexistent paths, but this
> +   will screw up our cache.
> +
> +2) Try our best, hoping that path is well formed and won't
> +   affect us.
> +
> +I do #2 for now, in order to keep compiler generality.  Else,
> +return NULL.  I prefer #1 though.
> + */
> +#if 1
> + rp = x_strdup(path);
> +#else
> + return NULL;
> +#endif
> + }
> +
> + /* init */
> + if (!cwd)  {
> + char *x = gnu_getcwd();
> +
> + cwd = x_realpath(x);
> + free(x);
> + }
> + result[0] = 0;
> +
> + /* step 1 - find common root */
> + cp = croot = cwd;
> + pp = proot = rp;
> + while (*pp && *cp) {
> + if (*pp != *cp)
> + break;
> + 
> + if (*pp == '/') {
> + proot = pp;
> + croot = cp;
> + }
> + pp++; cp++;
> + }
> +
> + /* common root is root - don't relativize */
> + if (croot == cwd) {
> + free(rp);
> + return path;
> + }
> +
> + /* same dir */  
> + if (*pp == 0 && *cp == 0) {
> + strcpy(result, ".");
> + free(rp);
> + return result;
> + }
> +
> + /* parent */
> + if (*pp == 0) {
> + int len = strlen(proot);
> +
> + if (strncmp(proot, croot, len) == 0 && croot[len] == '/') {
> + croot++;
> + proot = NULL;
> + }
> + }
> +
> + /* subdir */
> + if (*cp == 0) {
> + int len = strlen(croot);
> +
> + if (strncmp(croot, proot, len) == 0 && proot[len] == '/') {
> + croot = cp;
> + proot += len;
> + }
> + }
> +
> + /* step 2 - cd to common root */
> + while (*croot) {
> + if (*croot++ == '/') {
> + if (strlen(result) + 4 > sizeof(result)) {
> + cc_log("r

[ccache] [PATCH] flag for using relative directories

2007-06-18 Thread Andrea Bittau
It is common for developers in a shared environment to compile the same
code, but in a different location [e.g. their home] and furthermore, to
use absolute path-names in their includes flags.  This results in two
different outputs from the preprocessor, even though the same file is
included [just different path], making it impossible to share a cache.
CCACHE_UNIFY could be used to get rid of the comments from the
preprocessor, but the problem here is of different nature: we do not
wish to UNIFY, and have side-effects such as wrong line information, but
rather just use relative paths so that the output of two preprocesses is
the same.

I've added a new boolean, CCACHE_RELATIVE that will modify all the -I
flags to be relative directories from where ccache is called.  An
absolute pathname will be retained if the "common root" between the
working directory and the included path is "/".  For example, the
following command line:
/home/sorbo$ gcc -I/common/stuff -I/home/sorbo/includes
will be translated to:
/home/sorbo$ gcc -I/common/stuff -Iincludes

Please consider applying this patch or implementing similar
functionality.  This scenario is very common in many work places.  The
patch is against ccache v2.4.

This has discussed on this mailing list to some extent, but I am unable
to see attached patches from the web archive, so I had to code something
myself.  Also, I don't know what happened to the proposed patches, so I
just redid the work.  References:

1) Steve Bennet "[ccache] [PATCH] Better cache reuse across builds in
separate trees":
http://lists.samba.org/archive/ccache/2005q2/000167.html

2) Chris Swiedler "[ccache] ccache and -g"
http://lists.samba.org/archive/ccache/2006q1/000201.html

---

diff -rup ccache-2.4.orig/ccache.c ccache-2.4/ccache.c
--- ccache-2.4.orig/ccache.c2004-09-13 11:38:30.0 +0100
+++ ccache-2.4/ccache.c 2007-06-18 15:10:05.0 +0100
@@ -615,6 +615,119 @@ static const char *check_extension(const
return NULL;
 }
 
+/* Transform an incldue path to relative, so that we get more hits */
+static char *relative(char *path)
+{
+   static char result[PATH_MAX];
+   static char *cwd;
+   char *proot, *pp;
+   char *croot, *cp;
+   char *rp;
+
+   /* path is relative */
+   if (*path != '/')
+   return path;
+
+   rp = x_realpath(path);
+   if (!rp) {
+   /* we got two options:
+  1) remove the -I.  gcc works with inexistent paths, but this
+ will screw up our cache.
+
+  2) Try our best, hoping that path is well formed and won't
+ affect us.
+
+  I do #2 for now, in order to keep compiler generality.  Else,
+  return NULL.  I prefer #1 though.
+   */
+#if 1
+   rp = x_strdup(path);
+#else
+   return NULL;
+#endif
+   }
+
+   /* init */
+   if (!cwd)  {
+   char *x = gnu_getcwd();
+
+   cwd = x_realpath(x);
+   free(x);
+   }
+   result[0] = 0;
+
+   /* step 1 - find common root */
+   cp = croot = cwd;
+   pp = proot = rp;
+   while (*pp && *cp) {
+   if (*pp != *cp)
+   break;
+   
+   if (*pp == '/') {
+   proot = pp;
+   croot = cp;
+   }
+   pp++; cp++;
+   }
+
+   /* common root is root - don't relativize */
+   if (croot == cwd) {
+   free(rp);
+   return path;
+   }
+
+   /* same dir */  
+   if (*pp == 0 && *cp == 0) {
+   strcpy(result, ".");
+   free(rp);
+   return result;
+   }
+
+   /* parent */
+   if (*pp == 0) {
+   int len = strlen(proot);
+
+   if (strncmp(proot, croot, len) == 0 && croot[len] == '/') {
+   croot++;
+   proot = NULL;
+   }
+   }
+
+   /* subdir */
+   if (*cp == 0) {
+   int len = strlen(croot);
+
+   if (strncmp(croot, proot, len) == 0 && proot[len] == '/') {
+   croot = cp;
+   proot += len;
+   }
+   }
+
+   /* step 2 - cd to common root */
+   while (*croot) {
+   if (*croot++ == '/') {
+   if (strlen(result) + 4 > sizeof(result)) {
+   cc_log("relative: bad len");
+   failed();
+   }
+   strcat(result, "../");
+   }
+   }
+
+   /* step 3 - cd to child (if any) */
+   if (proot) {
+   proot++;
+   if (strlen(result) + strlen(proot) + 1 > sizeof(result)) {
+   cc_log("relative: bad len2");
+   failed();
+   }
+   strcat(result, proot);
+   }
+