[ccache] CCACHE_BASEDIR sometimes result in unnecessary recompilation

Joel Rosdahl joel at rosdahl.net
Wed Apr 9 14:12:13 MDT 2014


Hi Douglas,

Thanks for the patch! I've applied a very similar fix along with a test
case.

Regards,
-- Joel


On 14 March 2014 00:59, Douglas Graham <douglas.graham at ericsson.com> wrote:

> 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
>
> _______________________________________________
> ccache mailing list
> ccache at lists.samba.org
> https://lists.samba.org/mailman/listinfo/ccache
>


More information about the ccache mailing list