r311391 - [Driver] Recognize DevDiv internal builds of MSVC, with a different directory structure.

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 22 15:02:12 PDT 2017


Merged to 5.0 in r311500.

On Mon, Aug 21, 2017 at 3:19 PM, Stephan T. Lavavej via cfe-commits
<cfe-commits at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list