[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