I maintain a couple build tools based on Clang's Tooling framework. The tools are built and used directly out of the CMake binary directory (i.e. not installed in a meaningful way).
This non-installed setup causes issues when finding the GCC Toolchain and using the resulting system include paths. A normally-installed clang -v outputs the following:
clang version 5.0.1 (tags/RELEASE_501/final) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/bin Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.1 Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.1 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Selected multilib: .;@m64
But my build-tree tool outputs this:
clang version 5.0.1 (tags/RELEASE_501/final) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: Found candidate GCC installation: /../lib/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.1 Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.1 Selected GCC installation: /../lib64/gcc/x86_64-pc-linux-gnu/7.2.1
InstalledDir is empty, which is fine, but the resulting candidate selection is undesirable. The /usr rooted candidate strikes me as a much more stable option. Granted /../lib64/gcc/x86_64-pc-linux-gnu/7.2.1 works, but on a rather hackish technicality where /../ == / and symlink exists at /lib64.
This creates problems with dependency files consumed by Ninja (which is unable to canonicalize paths that feature a mix of .. and multi-level symlinks as explained in D37954). For example: /../lib64/gcc/x86_64-pc-linux-gnu/7.2.1/../../../../include/c++/7.2.1/cstdlib which ninja "canonicalizes" as /../include/c++/7.2.1/cstdlib, but is actually /usr/include/c++/7.2.1/cstdlib when taking symlinks into account.
If clang were to use the /usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.1 candidate instead, the result would be /usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.1/../../../../include/c++/7.2.1/cstdlib which Ninja can correctly canonicalize to /usr/include/c++/7.2.1/cstdlib.
I'm not trying to force clang to produce canonical paths as output; rather avoid the obviously problematic /../ candidate in the first place.