Merged to 5.0 in r311500.
On Mon, Aug 21, 2017 at 3:19 PM, Stephan T. Lavavej via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: stl_msft > Date: Mon Aug 21 15:19:33 2017 > New Revision: 311391 > > URL: http://llvm.org/viewvc/llvm-project?rev=311391&view=rev > Log: > [Driver] Recognize DevDiv internal builds of MSVC, with a different directory > structure. > > This is a reasonably non-intrusive change, which I've verified > works for both x86 and x64 DevDiv-internal builds. > > The idea is to change `bool IsVS2017OrNewer` into a 3-state > `ToolsetLayout VSLayout`. Either a build is DevDiv-internal, > released VS 2017 or newer, or released VS 2015 or older. When looking at > the directory structure, if instead of `"VC"` we see `"x86ret"`, `"x86chk"`, > `"amd64ret"`, or `"amd64chk"`, we recognize this as a DevDiv-internal build. > > After we get past the directory structure validation, we use this knowledge > to regenerate paths appropriately. `llvmArchToDevDivInternalArch()` knows how > we use `"i386"` subdirectories, and `MSVCToolChain::getSubDirectoryPath()` > uses that. It also knows that DevDiv-internal builds have an `"inc"` > subdirectory instead of `"include"`. > > This may still not be the "right" fix in any sense, but I believe that it's > non-intrusive in the sense that if the special directory names aren't found, > no codepaths are affected. (`ToolsetLayout::OlderVS` and > `ToolsetLayout::VS2017OrNewer` correspond to `IsVS2017OrNewer` being `false` > or `true`, respectively.) I searched for all references to `IsVS2017OrNewer`, > which are places where Clang cares about VS's directory structure, and the > only one that isn't being patched is some logic to deal with > cross-compilation. I'm fine with that not working for DevDiv-internal builds > for the moment (we typically test the native compilers), so I added a comment. > > Fixes D36860. > > Modified: > cfe/trunk/lib/Driver/ToolChains/MSVC.cpp > cfe/trunk/lib/Driver/ToolChains/MSVC.h > > Modified: cfe/trunk/lib/Driver/ToolChains/MSVC.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/MSVC.cpp?rev=311391&r1=311390&r2=311391&view=diff > ============================================================================== > --- cfe/trunk/lib/Driver/ToolChains/MSVC.cpp (original) > +++ cfe/trunk/lib/Driver/ToolChains/MSVC.cpp Mon Aug 21 15:19:33 2017 > @@ -76,7 +76,7 @@ static bool getSystemRegistryString(cons > > // Check various environment variables to try and find a toolchain. > static bool findVCToolChainViaEnvironment(std::string &Path, > - bool &IsVS2017OrNewer) { > + MSVCToolChain::ToolsetLayout > &VSLayout) { > // These variables are typically set by vcvarsall.bat > // when launching a developer command prompt. > if (llvm::Optional<std::string> VCToolsInstallDir = > @@ -84,7 +84,7 @@ static bool findVCToolChainViaEnvironmen > // This is only set by newer Visual Studios, and it leads straight to > // the toolchain directory. > Path = std::move(*VCToolsInstallDir); > - IsVS2017OrNewer = true; > + VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer; > return true; > } > if (llvm::Optional<std::string> VCInstallDir = > @@ -94,7 +94,7 @@ static bool findVCToolChainViaEnvironmen > // so this check has to appear second. > // In older Visual Studios, the VC directory is the toolchain. > Path = std::move(*VCInstallDir); > - IsVS2017OrNewer = false; > + VSLayout = MSVCToolChain::ToolsetLayout::OlderVS; > return true; > } > > @@ -134,9 +134,16 @@ static bool findVCToolChainViaEnvironmen > } > if (IsBin) { > llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath); > - if (llvm::sys::path::filename(ParentPath) == "VC") { > + llvm::StringRef ParentFilename = > llvm::sys::path::filename(ParentPath); > + if (ParentFilename == "VC") { > Path = ParentPath; > - IsVS2017OrNewer = false; > + VSLayout = MSVCToolChain::ToolsetLayout::OlderVS; > + return true; > + } > + if (ParentFilename == "x86ret" || ParentFilename == "x86chk" > + || ParentFilename == "amd64ret" || ParentFilename == "amd64chk") { > + Path = ParentPath; > + VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal; > return true; > } > > @@ -165,7 +172,7 @@ static bool findVCToolChainViaEnvironmen > ToolChainPath = llvm::sys::path::parent_path(ToolChainPath); > > Path = ToolChainPath; > - IsVS2017OrNewer = true; > + VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer; > return true; > } > > @@ -181,7 +188,7 @@ static bool findVCToolChainViaEnvironmen > // This is the preferred way to discover new Visual Studios, as they're no > // longer listed in the registry. > static bool findVCToolChainViaSetupConfig(std::string &Path, > - bool &IsVS2017OrNewer) { > + MSVCToolChain::ToolsetLayout > &VSLayout) { > #if !defined(USE_MSVC_SETUP_API) > return false; > #else > @@ -263,7 +270,7 @@ static bool findVCToolChainViaSetupConfi > return false; > > Path = ToolchainPath.str(); > - IsVS2017OrNewer = true; > + VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer; > return true; > #endif > } > @@ -272,7 +279,7 @@ static bool findVCToolChainViaSetupConfi > // a toolchain path. VS2017 and newer don't get added to the registry. > // So if we find something here, we know that it's an older version. > static bool findVCToolChainViaRegistry(std::string &Path, > - bool &IsVS2017OrNewer) { > + MSVCToolChain::ToolsetLayout > &VSLayout) { > std::string VSInstallPath; > if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)", > "InstallDir", VSInstallPath, nullptr) || > @@ -284,7 +291,7 @@ static bool findVCToolChainViaRegistry(s > llvm::sys::path::append(VCPath, "VC"); > > Path = VCPath.str(); > - IsVS2017OrNewer = false; > + VSLayout = MSVCToolChain::ToolsetLayout::OlderVS; > return true; > } > } > @@ -475,6 +482,7 @@ void visualstudio::Linker::ConstructJob( > // native target bin directory. > // e.g. when compiling for x86 on an x64 host, PATH should start with: > // /bin/HostX64/x86;/bin/HostX64/x64 > + // This doesn't attempt to handle ToolsetLayout::DevDivInternal. > if (TC.getIsVS2017OrNewer() && > llvm::Triple(llvm::sys::getProcessTriple()).getArch() != > TC.getArch()) { > auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch(); > @@ -677,9 +685,9 @@ MSVCToolChain::MSVCToolChain(const Drive > // what they want to use. > // Failing that, just try to find the newest Visual Studio version we can > // and use its default VC toolchain. > - findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) || > - findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) || > - findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer); > + findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) || > + findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) || > + findVCToolChainViaRegistry(VCToolChainPath, VSLayout); > } > > Tool *MSVCToolChain::buildLinker() const { > @@ -766,6 +774,21 @@ static const char *llvmArchToLegacyVCArc > } > } > > +// Similar to the above function, but for DevDiv internal builds. > +static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) > { > + using ArchType = llvm::Triple::ArchType; > + switch (Arch) { > + case ArchType::x86: > + return "i386"; > + case ArchType::x86_64: > + return "amd64"; > + case ArchType::arm: > + return "arm"; > + default: > + return ""; > + } > +} > + > // Get the path to a specific subdirectory in the current toolchain for > // a given target architecture. > // VS2017 changed the VC toolchain layout, so this should be used instead > @@ -773,26 +796,40 @@ static const char *llvmArchToLegacyVCArc > std::string > MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type, > llvm::Triple::ArchType TargetArch) const { > + const char *SubdirName; > + const char *IncludeName; > + switch (VSLayout) { > + case ToolsetLayout::OlderVS: > + SubdirName = llvmArchToLegacyVCArch(TargetArch); > + IncludeName = "include"; > + break; > + case ToolsetLayout::VS2017OrNewer: > + SubdirName = llvmArchToWindowsSDKArch(TargetArch); > + IncludeName = "include"; > + break; > + case ToolsetLayout::DevDivInternal: > + SubdirName = llvmArchToDevDivInternalArch(TargetArch); > + IncludeName = "inc"; > + break; > + } > + > llvm::SmallString<256> Path(VCToolChainPath); > switch (Type) { > case SubDirectoryType::Bin: > - if (IsVS2017OrNewer) { > - bool HostIsX64 = > + if (VSLayout == ToolsetLayout::VS2017OrNewer) { > + const 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)); > + const char *const HostName = HostIsX64 ? "HostX64" : "HostX86"; > + llvm::sys::path::append(Path, "bin", HostName, SubdirName); > + } else { // OlderVS or DevDivInternal > + llvm::sys::path::append(Path, "bin", SubdirName); > } > break; > case SubDirectoryType::Include: > - llvm::sys::path::append(Path, "include"); > + llvm::sys::path::append(Path, IncludeName); > break; > case SubDirectoryType::Lib: > - llvm::sys::path::append( > - Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch) > - : llvmArchToLegacyVCArch(TargetArch)); > + llvm::sys::path::append(Path, "lib", SubdirName); > break; > } > return Path.str(); > > Modified: cfe/trunk/lib/Driver/ToolChains/MSVC.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/MSVC.h?rev=311391&r1=311390&r2=311391&view=diff > ============================================================================== > --- cfe/trunk/lib/Driver/ToolChains/MSVC.h (original) > +++ cfe/trunk/lib/Driver/ToolChains/MSVC.h Mon Aug 21 15:19:33 2017 > @@ -92,7 +92,12 @@ public: > return getSubDirectoryPath(Type, getArch()); > } > > - bool getIsVS2017OrNewer() const { return IsVS2017OrNewer; } > + enum class ToolsetLayout { > + OlderVS, > + VS2017OrNewer, > + DevDivInternal, > + }; > + bool getIsVS2017OrNewer() const { return VSLayout == > ToolsetLayout::VS2017OrNewer; } > > void > AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, > @@ -130,7 +135,7 @@ protected: > Tool *buildAssembler() const override; > private: > std::string VCToolChainPath; > - bool IsVS2017OrNewer = false; > + ToolsetLayout VSLayout = ToolsetLayout::OlderVS; > CudaInstallationDetector CudaInstallation; > }; > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits