Index: lib/Driver/MSVCToolChain.cpp =================================================================== --- lib/Driver/MSVCToolChain.cpp +++ lib/Driver/MSVCToolChain.cpp @@ -212,6 +212,73 @@ 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. + libPath.clear(); + return false; + default: + return false; + } + } else { + // Windows SDK 8.x installs libraries in an folder whose names depend on + // the version of the OS you're targeting. By default choose the newest, + // which usually will correspond 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). Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -746,6 +746,7 @@ 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; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -7854,6 +7854,39 @@ 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(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)) {