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.000000000 +0100 > +++ ccache-2.4/ccache.c 2007-06-18 15:10:05.000000000 +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); > + } > + > + free(rp); > + > + return result; > +} > > /* > process the compiler options to form the correct set of options > @@ -704,7 +817,7 @@ static void process_args(int argc, char > > /* options that take an argument */ > { > - const char *opts[] = {"-I", "-include", "-imacros", > "-iprefix", > + const char *opts[] = {"-include", "-imacros", > "-iprefix", > "-iwithprefix", > "-iwithprefixbefore", > "-L", "-D", "-U", "-x", "-MF", > "-MT", "-MQ", "-isystem", > "-aux-info", > @@ -730,6 +843,32 @@ static void process_args(int argc, char > if (opts[j]) continue; > } > > + /* transform paths to relative so that builds in different trees > + * hit > + */ > + if (strncmp(argv[i], "-I", 2) == 0) { > + char *arg = &argv[i][2]; > + > + /* see if arg is not glued */ > + if (*arg == 0) { > + if (i == argc-1) { > + cc_log("missing argument to -I\n"); > + stats_update(STATS_ARGS); > + failed(); > + } > + i++; > + arg = argv[i]; > + } > + > + if (getenv("CCACHE_RELATIVE")) > + arg = relative(arg); > + if (!arg) > + continue; > + args_add(stripped_args, "-I"); > + args_add(stripped_args, arg); > + continue; > + } > + > /* other options */ > if (argv[i][0] == '-') { > args_add(stripped_args, argv[i]); > _______________________________________________ > ccache mailing list > ccache at lists.samba.org > https://lists.samba.org/mailman/listinfo/ccache > > -- View this message in context: http://www.nabble.com/-PATCH--flag-for-using-relative-directories-tp11180996p25393416.html Sent from the ccache mailing list archive at Nabble.com.
