[ccache] CCACHE_BASEDIR sometimes result in unnecessary recompilation

Douglas Graham douglas.graham at ericsson.com
Thu Mar 13 17:59:13 MDT 2014


Hello,

There is a bug in get_relative_path() in util.c where it will sometimes
return an incorrect path. This results in some unnecessary compilation when
CCACHE_BASEDIR is set.  This happens when one component of one of
the paths is a prefix of the corresponding component in the other.
For example,

get_relative_path("/func/lrciras/capabilities/src", "/func/lrci/if/RAS")

returns "../../if/RAS" when it should return "../../../lric/if/RAS".

This happens because "/func/lrci" is a prefix of "/func/lrciras".
The opposite direction is no better:

get_relative_path("/func/lrci/if/RAS", "/func/lrciras/capabilities/src")

returns "../../as/capabilities/src"

The bug is in common_dir_prefix_length().  Here's a patch:

diff -c -r1.1 util.c
*** util.c      2014/03/13 23:19:30     1.1
--- util.c      2014/03/13 23:57:30
***************
*** 984,1007 ****
                ++p1;
                ++p2;
        }
!       if (*p2 == '/') {
!               /* s2 starts with "s1/". */
!               return p1 - s1;
!       }
!       if (!*p2) {
!               /* s2 is equal to s1. */
!               if (p2 == s2 + 1) {
!                       /* Special case for s1 and s2 both being "/". */
!                       return 0;
!               } else {
!                       return p1 - s1;
!               }
!       }
!       /* Compute the common directory prefix */
!       while (p1 > s1 && *p1 != '/') {
                p1--;
                p2--;
        }
        return p1 - s1;
  }

--- 984,1000 ----
                ++p1;
                ++p2;
        }
! #define ISPATHSEP(c) ((c) == '/' || (c) == '\0')
!       while (!ISPATHSEP(*p1) || !ISPATHSEP(*p2)) {
                p1--;
                p2--;
        }
+ #undef ISPATHSEP
+       if (*p1 == '\0' && *p2 == '\0' && p2 == s2 + 1) {
+               /* Special case for s1 and s2 both being "/". */
+               return 0;
+       }
+
        return p1 - s1;
  }

--Doug



More information about the ccache mailing list