Don’t use realpath(3) for normalization when computing relative paths
The current working directory (CWD) can come from two sources: Either
the return value of getcwd(3) (“actual CWD” below) or the environment
variable $PWD (“apparent CWD” below). The former is returned by e.g.
$(CURDIR) in Makefiles and by “pwd -P” and is always in normalized form
(no “.” or “..” parts or extra slashes). The latter is returned by “echo
$PWD” or “pwd” and can potentially be in unnormalized form on some
systems.
The actual CWD and apparent CWD may also differ if there are symlinks in
the path. Absolute paths to files given to ccache can therefore be based
on either of these CWD forms. When computing relative paths under the
base directory the CWD needs be in normalized form for the algorithm to
be reasonably simple.
2df269a3 solved a bug with an unnormalized apparent CWD by using
realpath(3) for normalization. Using realpath also makes the algorithm
correct in the presence of symlinks. It however also means that all
symlinks (both in CWD and in command line arguments) are dereferenced.
The downside of this is that if either of the symlink targets contain
specific names (such as build ID, date, username or similar) then the
relative paths will also contain those specific path names, leading to
cache misses.
Solve this by:
- Performing normalization without using realpath, i.e. without
expanding symlinks.
- Computing a relative path based on normalized CWD and normalized path.
- Checking whether the relative path resolves to the same i-node as the
original path. If it does, use it, otherwise just use the original
path (and take a potential cache miss).
- Doing the above calculation both for the actual and the apparent CWD
and choose the best one.
This solves the problem that PR #491 intended to address in a better
way.