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