diff options
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index d8f3edd..1c0a6ff 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -7814,6 +7814,26 @@ static void addSanitizerRTWindows(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(LibSanitizer)); } +// Try to find Exe from a Visual Studio distribution. This first tries to find +// an installed copy of Visual Studio and, failing that, looks in the PATH, +// making sure that whatever executable that's found is not a same-named exe +// from clang itself to prevent clang from falling back to itself. +static std::string FindVisualStudioExecutable(const ToolChain &TC, + const char *Exe, + const char *ClangProgramPath) { + const auto &MSVC = static_cast<const toolchains::MSVCToolChain &>(TC); + std::string visualStudioBinDir; + if (MSVC.getVisualStudioBinariesFolder(ClangProgramPath, + visualStudioBinDir)) { + SmallString<128> FilePath(visualStudioBinDir); + llvm::sys::path::append(FilePath, Exe); + if (llvm::sys::fs::can_execute(FilePath.c_str())) + return FilePath.str(); + } + + return Exe; +} + void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -7899,8 +7919,11 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, A.renderAsInput(Args, CmdArgs); } - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); + // It's not sufficient to just use link from the program PATH, because other + // environments like GnuWin32 install their own link.exe which may come first. + llvm::SmallString<128> linkPath(FindVisualStudioExecutable( + getToolChain(), "link.exe", C.getDriver().getClangProgramPath())); + const char *Exec = Args.MakeArgString(linkPath); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } @@ -7912,35 +7935,6 @@ void visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput)); } -// Try to find FallbackName on PATH that is not identical to ClangProgramPath. -// If one cannot be found, return FallbackName. -// We do this special search to prevent clang-cl from falling back onto itself -// if it's available as cl.exe on the path. -static std::string FindFallback(const char *FallbackName, - const char *ClangProgramPath) { - llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH"); - if (!OptPath.hasValue()) - return FallbackName; - - const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; - SmallVector<StringRef, 8> PathSegments; - llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr); - - for (size_t i = 0, e = PathSegments.size(); i != e; ++i) { - StringRef PathSegment = PathSegments[i]; - if (PathSegment.empty()) - continue; - - SmallString<128> FilePath(PathSegment); - llvm::sys::path::append(FilePath, FallbackName); - if (llvm::sys::fs::can_execute(Twine(FilePath)) && - !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath)) - return FilePath.str(); - } - - return FallbackName; -} - std::unique_ptr<Command> visualstudio::Compile::GetCommand( Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -8022,7 +8016,8 @@ std::unique_ptr<Command> visualstudio::Compile::GetCommand( CmdArgs.push_back(Fo); const Driver &D = getToolChain().getDriver(); - std::string Exec = FindFallback("cl.exe", D.getClangProgramPath()); + std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe", + D.getClangProgramPath()); return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), CmdArgs); } |