Fix FindExecutable to use sys::Path::GetMainExecutable instead of

just argv[0]. And remove the code for searching the current
working directory and for searching PATH; the point of FindExecutable
is not to find whatever version of the executable can be found by
searching around, but to find an executable that accompanies the
current executable.

Update the tools to use sys::Program::FindProgramByName when they
want PATH searching.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78240 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman
2009-08-05 20:21:17 +00:00
parent 7b3544ba97
commit 197f728d49
8 changed files with 65 additions and 66 deletions

View File

@@ -40,12 +40,12 @@ bool CheckBitcodeOutputToConsole(
); );
/// FindExecutable - Find a named executable, giving the argv[0] of program /// FindExecutable - Find a named executable, giving the argv[0] of program
/// being executed. This allows us to find another LLVM tool if it is built into /// being executed. This allows us to find another LLVM tool if it is built in
/// the same directory, but that directory is neither the current directory, nor /// the same directory. If the executable cannot be found, return an
/// in the PATH. If the executable cannot be found, return an empty string. /// empty string.
/// @brief Find a named executable. /// @brief Find a named executable.
sys::Path FindExecutable(const std::string &ExeName, sys::Path FindExecutable(const std::string &ExeName,
const std::string &ProgramPath); const char *Argv0, void *MainAddr);
} // End llvm namespace } // End llvm namespace

View File

@@ -50,24 +50,17 @@ bool llvm::CheckBitcodeOutputToConsole(std::ostream* stream_to_check,
} }
/// FindExecutable - Find a named executable, giving the argv[0] of program /// FindExecutable - Find a named executable, giving the argv[0] of program
/// being executed. This allows us to find another LLVM tool if it is built /// being executed. This allows us to find another LLVM tool if it is built in
/// into the same directory, but that directory is neither the current /// the same directory. If the executable cannot be found, return an
/// directory, nor in the PATH. If the executable cannot be found, return an /// empty string.
/// empty string. Return the input string if given a full path to an executable. /// @brief Find a named executable.
///
#undef FindExecutable // needed on windows :( #undef FindExecutable // needed on windows :(
sys::Path llvm::FindExecutable(const std::string &ExeName, sys::Path llvm::FindExecutable(const std::string &ExeName,
const std::string &ProgramPath) { const char *Argv0, void *MainAddr) {
// First check if the given name is already a valid path to an executable. // Check the directory that the calling program is in. We can do
sys::Path Result(ExeName);
Result.makeAbsolute();
if (Result.canExecute())
return Result;
// Otherwise check the directory that the calling program is in. We can do
// this if ProgramPath contains at least one / character, indicating that it // this if ProgramPath contains at least one / character, indicating that it
// is a relative path to the executable itself. // is a relative path to the executable itself.
Result = ProgramPath; sys::Path Result = sys::Path::GetMainExecutable(Argv0, MainAddr);
Result.eraseComponent(); Result.eraseComponent();
if (!Result.isEmpty()) { if (!Result.isEmpty()) {
Result.appendComponent(ExeName); Result.appendComponent(ExeName);
@@ -75,5 +68,5 @@ sys::Path llvm::FindExecutable(const std::string &ExeName,
return Result; return Result;
} }
return sys::Program::FindProgramByName(ExeName); return sys::Path();
} }

View File

@@ -44,7 +44,7 @@ extern bool BugpointIsInterrupted;
class BugDriver { class BugDriver {
LLVMContext& Context; LLVMContext& Context;
const std::string ToolName; // Name of bugpoint const char *ToolName; // argv[0] of bugpoint
std::string ReferenceOutputFile; // Name of `good' output file std::string ReferenceOutputFile; // Name of `good' output file
Module *Program; // The raw program, linked together Module *Program; // The raw program, linked together
std::vector<const PassInfo*> PassesToRun; std::vector<const PassInfo*> PassesToRun;
@@ -64,7 +64,7 @@ public:
BugDriver(const char *toolname, bool as_child, bool find_bugs, BugDriver(const char *toolname, bool as_child, bool find_bugs,
unsigned timeout, unsigned memlimit, LLVMContext& ctxt); unsigned timeout, unsigned memlimit, LLVMContext& ctxt);
const std::string &getToolName() const { return ToolName; } const char *getToolName() const { return ToolName; }
LLVMContext& getContext() { return Context; } LLVMContext& getContext() { return Context; }

View File

@@ -177,8 +177,7 @@ bool BugDriver::initializeExecutionEnvironment() {
&ToolArgv, &GCCToolArgv); &ToolArgv, &GCCToolArgv);
break; break;
case Custom: case Custom:
Interpreter = AbstractInterpreter::createCustom(getToolName(), Message, Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand);
CustomExecCommand);
break; break;
default: default:
Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
@@ -200,7 +199,7 @@ bool BugDriver::initializeExecutionEnvironment() {
InterpreterSel == CBE_bug) { InterpreterSel == CBE_bug) {
SafeInterpreterSel = RunLLC; SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic"); SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
} }
@@ -210,7 +209,7 @@ bool BugDriver::initializeExecutionEnvironment() {
InterpreterSel == LLC_Safe) { InterpreterSel == LLC_Safe) {
SafeInterpreterSel = RunLLC; SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic"); SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
} }
@@ -221,7 +220,7 @@ bool BugDriver::initializeExecutionEnvironment() {
if (!SafeInterpreter && if (!SafeInterpreter &&
InterpreterSel != RunCBE) { InterpreterSel != RunCBE) {
SafeInterpreterSel = RunCBE; SafeInterpreterSel = RunCBE;
SafeInterpreter = AbstractInterpreter::createCBE(Path, Message, SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
} }
@@ -230,7 +229,7 @@ bool BugDriver::initializeExecutionEnvironment() {
InterpreterSel != RunJIT) { InterpreterSel != RunJIT) {
SafeInterpreterSel = RunLLC; SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic"); SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
} }
@@ -241,17 +240,17 @@ bool BugDriver::initializeExecutionEnvironment() {
break; break;
case RunLLC: case RunLLC:
SafeToolArgs.push_back("--relocation-model=pic"); SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path, Message, SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
break; break;
case RunCBE: case RunCBE:
SafeInterpreter = AbstractInterpreter::createCBE(Path, Message, SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
&SafeToolArgs, &SafeToolArgs,
&GCCToolArgv); &GCCToolArgv);
break; break;
case Custom: case Custom:
SafeInterpreter = AbstractInterpreter::createCustom(Path, Message, SafeInterpreter = AbstractInterpreter::createCustom(Message,
CustomExecCommand); CustomExecCommand);
break; break;
default: default:
@@ -261,7 +260,7 @@ bool BugDriver::initializeExecutionEnvironment() {
} }
if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
gcc = GCC::create(getToolName(), Message, &GCCToolArgv); gcc = GCC::create(Message, &GCCToolArgv);
if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); } if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
// If there was an error creating the selected interpreter, quit with error. // If there was an error creating the selected interpreter, quit with error.

View File

@@ -167,7 +167,7 @@ bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
args[n++] = "-q"; args[n++] = "-q";
args[n++] = tool.c_str(); args[n++] = tool.c_str();
} else } else
args[n++] = ToolName.c_str(); args[n++] = ToolName;
args[n++] = "-as-child"; args[n++] = "-as-child";
args[n++] = "-child-output"; args[n++] = "-child-output";

View File

@@ -228,10 +228,12 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
} }
// LLI create method - Try to find the LLI executable // LLI create method - Try to find the LLI executable
AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath, AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
std::string &Message, std::string &Message,
const std::vector<std::string> *ToolArgs) { const std::vector<std::string> *ToolArgs) {
std::string LLIPath = FindExecutable("lli", ProgPath).toString(); std::string LLIPath =
FindExecutable("lli", Argv0,
reinterpret_cast<void *>(&createLLI)).toString();
if (!LLIPath.empty()) { if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n"; Message = "Found lli: " + LLIPath + "\n";
return new LLI(LLIPath, ToolArgs); return new LLI(LLIPath, ToolArgs);
@@ -298,7 +300,6 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
// Custom execution environment create method, takes the execution command // Custom execution environment create method, takes the execution command
// as arguments // as arguments
AbstractInterpreter *AbstractInterpreter::createCustom( AbstractInterpreter *AbstractInterpreter::createCustom(
const std::string &ProgramPath,
std::string &Message, std::string &Message,
const std::string &ExecCommandLine) { const std::string &ExecCommandLine) {
@@ -332,7 +333,7 @@ AbstractInterpreter *AbstractInterpreter::createCustom(
pos = ExecCommandLine.find_first_of(delimiters, lastPos); pos = ExecCommandLine.find_first_of(delimiters, lastPos);
} }
std::string CmdPath = FindExecutable(Command, ProgramPath).toString(); std::string CmdPath = sys::Program::FindProgramByName(Command).toString();
if (CmdPath.empty()) { if (CmdPath.empty()) {
Message = Message =
std::string("Cannot find '") + Command + std::string("Cannot find '") + Command +
@@ -414,18 +415,20 @@ int LLC::ExecuteProgram(const std::string &Bitcode,
/// createLLC - Try to find the LLC executable /// createLLC - Try to find the LLC executable
/// ///
LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath, LLC *AbstractInterpreter::createLLC(const char *Argv0,
std::string &Message, std::string &Message,
const std::vector<std::string> *Args, const std::vector<std::string> *Args,
const std::vector<std::string> *GCCArgs) { const std::vector<std::string> *GCCArgs) {
std::string LLCPath = FindExecutable("llc", ProgramPath).toString(); std::string LLCPath =
FindExecutable("llc", Argv0,
reinterpret_cast<void *>(&createLLC)).toString();
if (LLCPath.empty()) { if (LLCPath.empty()) {
Message = "Cannot find `llc' in executable directory or PATH!\n"; Message = "Cannot find `llc' in executable directory or PATH!\n";
return 0; return 0;
} }
Message = "Found llc: " + LLCPath + "\n"; Message = "Found llc: " + LLCPath + "\n";
GCC *gcc = GCC::create(ProgramPath, Message, GCCArgs); GCC *gcc = GCC::create(Message, GCCArgs);
if (!gcc) { if (!gcc) {
errs() << Message << "\n"; errs() << Message << "\n";
exit(1); exit(1);
@@ -501,9 +504,11 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
/// createJIT - Try to find the LLI executable /// createJIT - Try to find the LLI executable
/// ///
AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath, AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
std::string &Message, const std::vector<std::string> *Args) { std::string &Message, const std::vector<std::string> *Args) {
std::string LLIPath = FindExecutable("lli", ProgPath).toString(); std::string LLIPath =
FindExecutable("lli", Argv0,
reinterpret_cast<void *>(&createJIT)).toString();
if (!LLIPath.empty()) { if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n"; Message = "Found lli: " + LLIPath + "\n";
return new JIT(LLIPath, Args); return new JIT(LLIPath, Args);
@@ -577,11 +582,13 @@ int CBE::ExecuteProgram(const std::string &Bitcode,
/// createCBE - Try to find the 'llc' executable /// createCBE - Try to find the 'llc' executable
/// ///
CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath, CBE *AbstractInterpreter::createCBE(const char *Argv0,
std::string &Message, std::string &Message,
const std::vector<std::string> *Args, const std::vector<std::string> *Args,
const std::vector<std::string> *GCCArgs) { const std::vector<std::string> *GCCArgs) {
sys::Path LLCPath = FindExecutable("llc", ProgramPath); sys::Path LLCPath =
FindExecutable("llc", Argv0,
reinterpret_cast<void *>(&createCBE));
if (LLCPath.isEmpty()) { if (LLCPath.isEmpty()) {
Message = Message =
"Cannot find `llc' in executable directory or PATH!\n"; "Cannot find `llc' in executable directory or PATH!\n";
@@ -589,7 +596,7 @@ CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
} }
Message = "Found llc: " + LLCPath.toString() + "\n"; Message = "Found llc: " + LLCPath.toString() + "\n";
GCC *gcc = GCC::create(ProgramPath, Message, GCCArgs); GCC *gcc = GCC::create(Message, GCCArgs);
if (!gcc) { if (!gcc) {
errs() << Message << "\n"; errs() << Message << "\n";
exit(1); exit(1);
@@ -827,9 +834,9 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
/// create - Try to find the `gcc' executable /// create - Try to find the `gcc' executable
/// ///
GCC *GCC::create(const std::string &ProgramPath, std::string &Message, GCC *GCC::create(std::string &Message,
const std::vector<std::string> *Args) { const std::vector<std::string> *Args) {
sys::Path GCCPath = FindExecutable("gcc", ProgramPath); sys::Path GCCPath = sys::Program::FindProgramByName("gcc");
if (GCCPath.isEmpty()) { if (GCCPath.isEmpty()) {
Message = "Cannot find `gcc' in executable directory or PATH!\n"; Message = "Cannot find `gcc' in executable directory or PATH!\n";
return 0; return 0;
@@ -837,7 +844,7 @@ GCC *GCC::create(const std::string &ProgramPath, std::string &Message,
sys::Path RemoteClientPath; sys::Path RemoteClientPath;
if (!RemoteClient.empty()) if (!RemoteClient.empty())
RemoteClientPath = FindExecutable(RemoteClient.c_str(), ProgramPath); RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
Message = "Found gcc: " + GCCPath.toString() + "\n"; Message = "Found gcc: " + GCCPath.toString() + "\n";
return new GCC(GCCPath, RemoteClientPath, Args); return new GCC(GCCPath, RemoteClientPath, Args);

View File

@@ -57,7 +57,7 @@ class GCC {
public: public:
enum FileType { AsmFile, CFile }; enum FileType { AsmFile, CFile };
static GCC *create(const std::string &ProgramPath, std::string &Message, static GCC *create(std::string &Message,
const std::vector<std::string> *Args); const std::vector<std::string> *Args);
/// ExecuteProgram - Execute the program specified by "ProgramFile" (which is /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
@@ -93,23 +93,20 @@ public:
/// ///
class AbstractInterpreter { class AbstractInterpreter {
public: public:
static CBE *createCBE(const std::string &ProgramPath, std::string &Message, static CBE *createCBE(const char *Argv0, std::string &Message,
const std::vector<std::string> *Args = 0, const std::vector<std::string> *Args = 0,
const std::vector<std::string> *GCCArgs = 0); const std::vector<std::string> *GCCArgs = 0);
static LLC *createLLC(const std::string &ProgramPath, std::string &Message, static LLC *createLLC(const char *Argv0, std::string &Message,
const std::vector<std::string> *Args = 0, const std::vector<std::string> *Args = 0,
const std::vector<std::string> *GCCArgs = 0); const std::vector<std::string> *GCCArgs = 0);
static AbstractInterpreter* createLLI(const std::string &ProgramPath, static AbstractInterpreter* createLLI(const char *Argv0, std::string &Message,
std::string &Message,
const std::vector<std::string> *Args=0); const std::vector<std::string> *Args=0);
static AbstractInterpreter* createJIT(const std::string &ProgramPath, static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
std::string &Message,
const std::vector<std::string> *Args=0); const std::vector<std::string> *Args=0);
static AbstractInterpreter* createCustom(const std::string &ProgramPath, static AbstractInterpreter* createCustom(std::string &Message,
std::string &Message,
const std::string &ExecCommandLine); const std::string &ExecCommandLine);

View File

@@ -41,6 +41,11 @@
#include <cstring> #include <cstring>
using namespace llvm; using namespace llvm;
// Rightly this should go in a header file but it just seems such a waste.
namespace llvm {
extern void Optimize(Module*);
}
// Input/Output Options // Input/Output Options
static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
cl::desc("<input bitcode files>")); cl::desc("<input bitcode files>"));
@@ -409,7 +414,8 @@ static void EmitShellScript(char **argv) {
// support windows systems, we copy the llvm-stub.exe executable from the // support windows systems, we copy the llvm-stub.exe executable from the
// build tree to the destination file. // build tree to the destination file.
std::string ErrMsg; std::string ErrMsg;
sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0]); sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0],
reinterpret_cast<void *>(&Optimize));
if (llvmstub.isEmpty()) if (llvmstub.isEmpty())
PrintAndExit("Could not find llvm-stub.exe executable!"); PrintAndExit("Could not find llvm-stub.exe executable!");
@@ -500,11 +506,6 @@ static void BuildLinkItems(
} }
} }
// Rightly this should go in a header file but it just seems such a waste.
namespace llvm {
extern void Optimize(Module*);
}
int main(int argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) {
// Print a stack trace if we signal out. // Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal(); sys::PrintStackTraceOnErrorSignal();
@@ -640,11 +641,12 @@ int main(int argc, char **argv, char **envp) {
sys::RemoveFileOnSignal(sys::Path(OutputFilename)); sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs. // Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]); sys::Path llc = FindExecutable("llc", argv[0],
reinterpret_cast<void *>(&Optimize));
if (llc.isEmpty()) if (llc.isEmpty())
PrintAndExit("Failed to find llc"); PrintAndExit("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]); sys::Path gcc = sys::Program::FindProgramByName("gcc");
if (gcc.isEmpty()) if (gcc.isEmpty())
PrintAndExit("Failed to find gcc"); PrintAndExit("Failed to find gcc");
@@ -669,11 +671,12 @@ int main(int argc, char **argv, char **envp) {
sys::RemoveFileOnSignal(sys::Path(OutputFilename)); sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs. // Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]); sys::Path llc = FindExecutable("llc", argv[0],
reinterpret_cast<void *>(&Optimize));
if (llc.isEmpty()) if (llc.isEmpty())
PrintAndExit("Failed to find llc"); PrintAndExit("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]); sys::Path gcc = sys::Program::FindProgramByName("gcc");
if (gcc.isEmpty()) if (gcc.isEmpty())
PrintAndExit("Failed to find gcc"); PrintAndExit("Failed to find gcc");