From 5cc8920d02e90e1a5ec2e1a740f0c7f1bd87002f Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Mon, 10 Dec 2018 00:56:13 +0000 Subject: [bugpoint] Find 'opt', etc., in bugpoint directory Summary: When bugpoint attempts to find the other executables it needs to run, such as `opt` or `clang`, it tries searching the user's PATH. However, in many cases, the 'bugpoint' executable is part of an LLVM build, and the 'opt' executable it's looking for is in that same directory. Many LLVM tools handle this case by using the `Paths` parameter of `llvm::sys::findProgramByName`, passing the parent path of the currently running executable. Do this same thing for bugpoint. However, to preserve the current behavior exactly, first search the user's PATH, and then search for 'opt' in the directory containing 'bugpoint'. Test Plan: `check-llvm`. Many of the existing bugpoint tests no longer need to use the `--opt-command` option as a result of these changes. Reviewers: MatzeB, silvas, davide Reviewed By: MatzeB, davide Subscribers: davide, llvm-commits Differential Revision: https://reviews.llvm.org/D54884 llvm-svn: 348734 --- llvm/tools/bugpoint/ToolRunner.cpp | 92 ++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 53 deletions(-) (limited to 'llvm/tools/bugpoint/ToolRunner.cpp') diff --git a/llvm/tools/bugpoint/ToolRunner.cpp b/llvm/tools/bugpoint/ToolRunner.cpp index 812e8e3bbae..7ba8ea1f16c 100644 --- a/llvm/tools/bugpoint/ToolRunner.cpp +++ b/llvm/tools/bugpoint/ToolRunner.cpp @@ -202,19 +202,7 @@ Expected LLI::ExecuteProgram(const std::string &Bitcode, void AbstractInterpreter::anchor() {} -#if defined(LLVM_ON_UNIX) -const char EXESuffix[] = ""; -#elif defined(_WIN32) -const char EXESuffix[] = "exe"; -#endif - -/// Prepend the path to the program being executed -/// to \p ExeName, given the value of argv[0] and the address of main() -/// itself. This allows us to find another LLVM tool if it is built in the same -/// directory. An empty string is returned on error; note that this function -/// just mainpulates the path and doesn't check for executability. -/// Find a named executable. -static std::string PrependMainExecutablePath(const std::string &ExeName, +ErrorOr llvm::FindProgramByName(const std::string &ExeName, const char *Argv0, void *MainAddr) { // Check the directory that the calling program is in. We can do @@ -222,30 +210,25 @@ static std::string PrependMainExecutablePath(const std::string &ExeName, // is a relative path to the executable itself. std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr); StringRef Result = sys::path::parent_path(Main); + if (ErrorOr Path = sys::findProgramByName(ExeName, Result)) + return *Path; - if (!Result.empty()) { - SmallString<128> Storage = Result; - sys::path::append(Storage, ExeName); - sys::path::replace_extension(Storage, EXESuffix); - return Storage.str(); - } - - return Result.str(); + // Check the user PATH. + return sys::findProgramByName(ExeName); } // LLI create method - Try to find the LLI executable AbstractInterpreter * AbstractInterpreter::createLLI(const char *Argv0, std::string &Message, const std::vector *ToolArgs) { - std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI); - if (!LLIPath.empty()) { - Message = "Found lli: " + LLIPath + "\n"; - return new LLI(LLIPath, ToolArgs); + if (ErrorOr LLIPath = + FindProgramByName("lli", Argv0, (void *)(intptr_t)&createLLI)) { + Message = "Found lli: " + *LLIPath + "\n"; + return new LLI(*LLIPath, ToolArgs); + } else { + Message = LLIPath.getError().message() + "\n"; + return nullptr; } - - Message = "Cannot find `lli' in executable directory!\n"; - return nullptr; } //===---------------------------------------------------------------------===// @@ -368,8 +351,9 @@ Expected CustomExecutor::ExecuteProgram( // '\ ' -> ' ' // 'exa\mple' -> 'example' // -static void lexCommand(std::string &Message, const std::string &CommandLine, - std::string &CmdPath, std::vector &Args) { +static void lexCommand(const char *Argv0, std::string &Message, + const std::string &CommandLine, std::string &CmdPath, + std::vector &Args) { std::string Token; std::string Command; @@ -402,7 +386,7 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, Token.push_back(CommandLine[Pos]); } - auto Path = sys::findProgramByName(Command); + auto Path = FindProgramByName(Command, Argv0, (void *)(intptr_t)&lexCommand); if (!Path) { Message = std::string("Cannot find '") + Command + "' in PATH: " + Path.getError().message() + "\n"; @@ -416,11 +400,12 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, // Custom execution environment create method, takes the execution command // as arguments AbstractInterpreter *AbstractInterpreter::createCustomCompiler( - std::string &Message, const std::string &CompileCommandLine) { + const char *Argv0, std::string &Message, + const std::string &CompileCommandLine) { std::string CmdPath; std::vector Args; - lexCommand(Message, CompileCommandLine, CmdPath, Args); + lexCommand(Argv0, Message, CompileCommandLine, CmdPath, Args); if (CmdPath.empty()) return nullptr; @@ -430,12 +415,13 @@ AbstractInterpreter *AbstractInterpreter::createCustomCompiler( // Custom execution environment create method, takes the execution command // as arguments AbstractInterpreter * -AbstractInterpreter::createCustomExecutor(std::string &Message, +AbstractInterpreter::createCustomExecutor(const char *Argv0, + std::string &Message, const std::string &ExecCommandLine) { std::string CmdPath; std::vector Args; - lexCommand(Message, ExecCommandLine, CmdPath, Args); + lexCommand(Argv0, Message, ExecCommandLine, CmdPath, Args); if (CmdPath.empty()) return nullptr; @@ -524,20 +510,20 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message, const std::vector *Args, const std::vector *CCArgs, bool UseIntegratedAssembler) { - std::string LLCPath = - PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC); - if (LLCPath.empty()) { - Message = "Cannot find `llc' in executable directory!\n"; + ErrorOr LLCPath = + FindProgramByName("llc", Argv0, (void *)(intptr_t)&createLLC); + if (!LLCPath) { + Message = LLCPath.getError().message() + "\n"; return nullptr; } - CC *cc = CC::create(Message, CCBinary, CCArgs); + CC *cc = CC::create(Argv0, Message, CCBinary, CCArgs); if (!cc) { errs() << Message << "\n"; exit(1); } - Message = "Found llc: " + LLCPath + "\n"; - return new LLC(LLCPath, cc, Args, UseIntegratedAssembler); + Message = "Found llc: " + *LLCPath + "\n"; + return new LLC(*LLCPath, cc, Args, UseIntegratedAssembler); } //===---------------------------------------------------------------------===// @@ -606,15 +592,14 @@ Expected JIT::ExecuteProgram(const std::string &Bitcode, AbstractInterpreter * AbstractInterpreter::createJIT(const char *Argv0, std::string &Message, const std::vector *Args) { - std::string LLIPath = - PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT); - if (!LLIPath.empty()) { - Message = "Found lli: " + LLIPath + "\n"; - return new JIT(LLIPath, Args); + if (ErrorOr LLIPath = + FindProgramByName("lli", Argv0, (void *)(intptr_t)&createJIT)) { + Message = "Found lli: " + *LLIPath + "\n"; + return new JIT(*LLIPath, Args); + } else { + Message = LLIPath.getError().message() + "\n"; + return nullptr; } - - Message = "Cannot find `lli' in executable directory!\n"; - return nullptr; } //===---------------------------------------------------------------------===// @@ -855,9 +840,10 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType, /// create - Try to find the CC executable /// -CC *CC::create(std::string &Message, const std::string &CCBinary, +CC *CC::create(const char *Argv0, std::string &Message, + const std::string &CCBinary, const std::vector *Args) { - auto CCPath = sys::findProgramByName(CCBinary); + auto CCPath = FindProgramByName(CCBinary, Argv0, (void *)(intptr_t)&create); if (!CCPath) { Message = "Cannot find `" + CCBinary + "' in PATH: " + CCPath.getError().message() + "\n"; -- cgit v1.2.3