diff options
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 83 |
1 files changed, 32 insertions, 51 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index ea5c3ab..151400c 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -7809,50 +7809,6 @@ 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) { - // Since a particular Visual Studio executable is tied to a set of system - // includes and libraries, first try to use the same location that we use for - // the include paths to ensure that a consistent build environment is located. - const toolchains::Windows &WTC = static_cast<const toolchains::Windows &>(TC); - std::string visualStudioDir; - if (WTC.getVisualStudioDir(visualStudioDir)) { - SmallString<128> VSDir(visualStudioDir); - llvm::sys::path::append(VSDir, "VC\\bin"); - llvm::sys::path::append(VSDir, Exe); - if (llvm::sys::fs::can_execute(VSDir.c_str())) - return VSDir.str(); - } - - // If it could not be found, we're already probably broken, but try to - // fallback to PATH anyway. - llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH"); - if (!OptPath.hasValue()) - return Exe; - - const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; - SmallVector<StringRef, 8> PathSegments; - llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr); - - for (StringRef PathSegment : PathSegments) { - if (PathSegment.empty()) - continue; - - SmallString<128> FilePath(PathSegment); - llvm::sys::path::append(FilePath, Exe); - if (llvm::sys::fs::can_execute(FilePath.c_str()) && - !llvm::sys::fs::equivalent(FilePath.c_str(), ClangProgramPath)) - return FilePath.str(); - } - - return Exe; -} - void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -7938,11 +7894,8 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, A.renderAsInput(Args, CmdArgs); } - // 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); + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs)); } @@ -7954,6 +7907,35 @@ 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, @@ -8035,8 +8017,7 @@ std::unique_ptr<Command> visualstudio::Compile::GetCommand( CmdArgs.push_back(Fo); const Driver &D = getToolChain().getDriver(); - std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe", - D.getClangProgramPath()); + std::string Exec = FindFallback("cl.exe", D.getClangProgramPath()); return llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Exec), CmdArgs); } |