[cfe-dev] Using Clang 5.0.0 RC2 with MSVC dev builds
don hinton via cfe-dev
cfe-dev at lists.llvm.org
Wed Aug 16 20:03:06 PDT 2017
On Wed, Aug 16, 2017 at 6:49 PM, Stephan T. Lavavej <
stl at exchange.microsoft.com> wrote:
> [Reid Kleckner]
> > The vcvars* / VsDevCmd.bat scripts all set VCINSTALLDIR which
> short-circuits all that validation logic.
>
> I managed to build and debug into Clang, so I have a better idea of what
> it's doing now. While I could easily set an environment variable like
> VCINSTALLDIR, there are problems beyond validation.
>
Don't these scripts set a bunch of environment variables, e.g., PATH, TMP,
INCLUDE, LIB, and LIBPATH as well as LINK?
If clang were to honor these variables instead of trying to reconstruct
them on the fly based on some root, be it VCINSTALLDIR or based on finding
cl.exe in the PATH, you could set them to whatever you want/need.
>
> findVCToolChainViaEnvironment() indeed finds cl.exe and link.exe on the
> path but performs too much validation. If I skip the validation (by jumping
> into the `if (llvm::sys::path::filename(ParentPath) == "VC")` branch
> which sets Path = ParentPath; and IsVS2017OrNewer = false; before returning
> - I know that's an inaccurate value for IsVS2017OrNewer but I wanted to see
> how far I could get), I think I've found an additional part of the problem.
>
> MSVCToolChain::computeMSVCVersion() calls MSVCToolChain::getSubDirectoryPath()
> which has directory structure assumptions that don't apply to this
> development build. If I get here with VCToolChainPath set to
> "C:\\Temp\\binaries\\x86ret", it executes this code:
>
> case SubDirectoryType::Bin:
> if (IsVS2017OrNewer) {
> bool HostIsX64 =
> llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
> llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" :
> "HostX86"),
> llvmArchToWindowsSDKArch(TargetArch));
>
> } else {
> llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(
> TargetArch));
> }
>
> The IsVS2017OrNewer codepath is not applicable to the dev build. The
> !IsVS2017OrNewer codepath is ALMOST applicable, but here the TargetArch is
> x86. This leads us to:
>
> static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
> using ArchType = llvm::Triple::ArchType;
> switch (Arch) {
> case ArchType::x86:
> // x86 is default in legacy VC toolchains.
> // e.g. x86 libs are directly in /lib as opposed to /lib/x86.
> return "";
> case ArchType::x86_64:
> return "amd64";
> case ArchType::arm:
> return "arm";
> default:
> return "";
> }
> }
>
> So this emits the empty string. However, in the dev build, the compiler is
> located at C:\Temp\binaries\x86ret\bin\i386\cl.exe , i.e. it lives in an
> i386 subdirectory.
>
> (Yes, I am endlessly screaming at all of:
> * The varying names for x86/i386 and x64/amd64
> * The varying directory structures between dev, pre-2017, and 2017+
> * The continued persistence of 32-bit ANYTHING in this day and age)
>
> I believe that this is why when Don Hinton asked me "Could you try
> renaming x86ret and amd64ret to VC and try it again?", the x86 dev build
> still failed but the amd64 dev build began working, because the compiler's
> path C:\Temp\binaries\amd64ret\bin\amd64\cl.exe lives in an "amd64"
> subdirectory like llvmArchToLegacyVCArch() expects.
>
> So beyond the too-strict validation, the problem here seems to be that
> Clang is finding cl.exe on the path, but then attempting to regenerate that
> information, and the regeneration isn't lossless. (
> findVCToolChainViaEnvironment() accidentally handles the dev build's i386
> subdirectory due to "// Strip any architecture subdir like "amd64"." logic.)
>
> I am not sure how to fix any of this (I am amazed that I was able to get
> this far), but hopefully this info will help.
>
> Thanks,
> STL
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170816/f6a9838e/attachment.html>
More information about the cfe-dev
mailing list