diff options
| -rw-r--r-- | clang/lib/Driver/MSVCToolChain.cpp | 65 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.h | 1 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 33 | 
3 files changed, 99 insertions, 0 deletions
diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp index 64708419270..a2f5e839848 100644 --- a/clang/lib/Driver/MSVCToolChain.cpp +++ b/clang/lib/Driver/MSVCToolChain.cpp @@ -212,6 +212,71 @@ bool MSVCToolChain::getWindowsSDKDir(std::string &path, int &major,    return hasSDKDir && !path.empty();  } +// Gets the library path required to link against the Windows SDK. +bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const { +  std::string sdkPath; +  int sdkMajor = 0; +  int sdkMinor = 0; + +  path.clear(); +  if (!getWindowsSDKDir(sdkPath, sdkMajor, sdkMinor)) +    return false; + +  llvm::SmallString<128> libPath(sdkPath); +  llvm::sys::path::append(libPath, "Lib"); +  if (sdkMajor <= 7) { +    switch (getArch()) { +    // In Windows SDK 7.x, x86 libraries are directly in the Lib folder. +    case llvm::Triple::x86: +      break; +    case llvm::Triple::x86_64: +      llvm::sys::path::append(libPath, "x64"); +      break; +    case llvm::Triple::arm: +      // It is not necessary to link against Windows SDK 7.x when targeting ARM. +      return false; +    default: +      return false; +    } +  } else { +    // Windows SDK 8.x installs libraries in a folder whose names depend on the +    // version of the OS you're targeting.  By default choose the newest, which +    // usually corresponds to the version of the OS you've installed the SDK on. +    char *tests[] = {"winv6.3", "win8", "win7"}; +    bool found = false; +    for (char *test : tests) { +      llvm::SmallString<128> testPath(libPath); +      llvm::sys::path::append(testPath, test); +      if (llvm::sys::fs::exists(testPath.c_str())) { +        libPath = testPath; +        found = true; +        break; +      } +    } + +    if (!found) +      return false; + +    llvm::sys::path::append(libPath, "um"); +    switch (getArch()) { +    case llvm::Triple::x86: +      llvm::sys::path::append(libPath, "x86"); +      break; +    case llvm::Triple::x86_64: +      llvm::sys::path::append(libPath, "x64"); +      break; +    case llvm::Triple::arm: +      llvm::sys::path::append(libPath, "arm"); +      break; +    default: +      return false; +    } +  } + +  path = libPath.str(); +  return true; +} +  // Get the location to use for Visual Studio binaries.  The location priority  // is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on  // system (as reported by the registry). diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index dbacccab0f3..525a7d29a4f 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -746,6 +746,7 @@ public:                                 llvm::opt::ArgStringList &CC1Args) const override;    bool getWindowsSDKDir(std::string &path, int &major, int &minor) const; +  bool getWindowsSDKLibraryPath(std::string &path) const;    bool getVisualStudioInstallDir(std::string &path) const;    bool getVisualStudioBinariesFolder(const char *clangProgramPath,                                       std::string &path) const; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 1c0a6ff4a45..6e7060fedd0 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -7854,6 +7854,39 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,      CmdArgs.push_back("-defaultlib:libcmt");    } +  if (!llvm::sys::Process::GetEnv("LIB")) { +    // If the VC environment hasn't been configured (perhaps because the user +    // did not run vcvarsall), try to build a consistent link environment.  If +    // the environment variable is set however, assume the user knows what he's +    // doing. +    std::string VisualStudioDir; +    const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(getToolChain()); +    if (MSVC.getVisualStudioInstallDir(VisualStudioDir)) { +      SmallString<128> LibDir(VisualStudioDir); +      llvm::sys::path::append(LibDir, "VC", "lib"); +      switch (MSVC.getArch()) { +      case llvm::Triple::x86: +        // x86 just puts the libraries directly in lib +        break; +      case llvm::Triple::x86_64: +        llvm::sys::path::append(LibDir, "amd64"); +        break; +      case llvm::Triple::arm: +        llvm::sys::path::append(LibDir, "arm"); +        break; +      default: +        break; +      } +      CmdArgs.push_back( +          Args.MakeArgString(std::string("-libpath:") + LibDir.c_str())); +    } + +    std::string WindowsSdkLibPath; +    if (MSVC.getWindowsSDKLibraryPath(WindowsSdkLibPath)) +      CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + +                                           WindowsSdkLibPath.c_str())); +  } +    CmdArgs.push_back("-nologo");    if (Args.hasArg(options::OPT_g_Group)) {  | 

