blob: a28527a1c278843563669f05a854edbc8f1527de [file] [log] [blame]
Chris Lattner7915a1e2003-10-14 21:34:11 +00001//===-- ToolRunner.cpp ----------------------------------------------------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner7915a1e2003-10-14 21:34:11 +00009//
10// This file implements the interfaces described in the ToolRunner.h file.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattner0b1fe842003-10-19 02:27:40 +000014#define DEBUG_TYPE "toolrunner"
Misha Brukman68734502003-10-06 18:37:24 +000015#include "llvm/Support/ToolRunner.h"
Brian Gaekec8db76c2003-11-18 06:31:17 +000016#include "Config/config.h" // for HAVE_LINK_R
Misha Brukman9558c6a2003-09-29 22:39:25 +000017#include "Support/Debug.h"
18#include "Support/FileUtilities.h"
Chris Lattner7915a1e2003-10-14 21:34:11 +000019#include <iostream>
20#include <fstream>
Chris Lattner89bf9ea2004-02-18 20:38:00 +000021#include <sstream>
Chris Lattner2cdd21c2003-12-14 21:35:53 +000022using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000023
Alkis Evlogimenos1d29a6d2004-02-19 07:39:26 +000024ToolExecutionError::~ToolExecutionError() throw() { }
25
Chris Lattner89bf9ea2004-02-18 20:38:00 +000026static void ProcessFailure(std::string ProgPath, const char** Args) {
27 std::ostringstream OS;
Chris Lattnera3de1172004-02-18 20:58:00 +000028 OS << "\nError running tool:\n ";
Chris Lattner89bf9ea2004-02-18 20:38:00 +000029 for (const char **Arg = Args; *Arg; ++Arg)
30 OS << " " << *Arg;
31 OS << "\n";
32
33 // Rerun the compiler, capturing any error messages to print them.
34 std::string ErrorFilename = getUniqueFilename("error_messages");
35 RunProgramWithTimeout(ProgPath, Args, "/dev/null", ErrorFilename.c_str(),
36 ErrorFilename.c_str());
37
38 // Print out the error messages generated by GCC if possible...
39 std::ifstream ErrorFile(ErrorFilename.c_str());
40 if (ErrorFile) {
41 std::copy(std::istreambuf_iterator<char>(ErrorFile),
42 std::istreambuf_iterator<char>(),
43 std::ostreambuf_iterator<char>(OS));
44 ErrorFile.close();
45 }
46
47 removeFile(ErrorFilename);
48 throw ToolExecutionError(OS.str());
49}
50
Misha Brukman9558c6a2003-09-29 22:39:25 +000051//===---------------------------------------------------------------------===//
52// LLI Implementation of AbstractIntepreter interface
53//
Chris Lattner2cdd21c2003-12-14 21:35:53 +000054namespace {
55 class LLI : public AbstractInterpreter {
56 std::string LLIPath; // The path to the LLI executable
Brian Gaeked11577b2004-05-04 21:09:01 +000057 std::vector<std::string> ToolArgs; // Args to pass to LLI
Chris Lattner2cdd21c2003-12-14 21:35:53 +000058 public:
Brian Gaeked11577b2004-05-04 21:09:01 +000059 LLI(const std::string &Path, const std::vector<std::string> *Args)
60 : LLIPath(Path) {
61 ToolArgs.clear ();
Brian Gaeke48b008d2004-05-04 22:02:41 +000062 if (Args) { ToolArgs = *Args; }
Brian Gaeked11577b2004-05-04 21:09:01 +000063 }
Chris Lattner2cdd21c2003-12-14 21:35:53 +000064
65 virtual int ExecuteProgram(const std::string &Bytecode,
66 const std::vector<std::string> &Args,
67 const std::string &InputFile,
68 const std::string &OutputFile,
69 const std::vector<std::string> &SharedLibs =
Chris Lattnereeed9832003-10-14 21:52:52 +000070 std::vector<std::string>());
Chris Lattner2cdd21c2003-12-14 21:35:53 +000071 };
72}
Misha Brukman9558c6a2003-09-29 22:39:25 +000073
74int LLI::ExecuteProgram(const std::string &Bytecode,
Chris Lattner7915a1e2003-10-14 21:34:11 +000075 const std::vector<std::string> &Args,
Misha Brukman9558c6a2003-09-29 22:39:25 +000076 const std::string &InputFile,
77 const std::string &OutputFile,
Chris Lattnereeed9832003-10-14 21:52:52 +000078 const std::vector<std::string> &SharedLibs) {
Chris Lattner8c56be52004-02-18 20:21:57 +000079 if (!SharedLibs.empty())
80 throw ToolExecutionError("LLI currently does not support "
81 "loading shared libraries.");
Misha Brukman9558c6a2003-09-29 22:39:25 +000082
83 std::vector<const char*> LLIArgs;
84 LLIArgs.push_back(LLIPath.c_str());
Misha Brukman9558c6a2003-09-29 22:39:25 +000085 LLIArgs.push_back("-force-interpreter=true");
Brian Gaeked11577b2004-05-04 21:09:01 +000086
87 // Add any extra LLI args.
88 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
89 LLIArgs.push_back(ToolArgs[i].c_str());
90
Misha Brukman9558c6a2003-09-29 22:39:25 +000091 LLIArgs.push_back(Bytecode.c_str());
92 // Add optional parameters to the running program from Argv
93 for (unsigned i=0, e = Args.size(); i != e; ++i)
94 LLIArgs.push_back(Args[i].c_str());
95 LLIArgs.push_back(0);
96
97 std::cout << "<lli>" << std::flush;
Chris Lattner0b1fe842003-10-19 02:27:40 +000098 DEBUG(std::cerr << "\nAbout to run:\t";
Chris Lattner7b2ccff2003-10-19 02:14:58 +000099 for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
Misha Brukman9558c6a2003-09-29 22:39:25 +0000100 std::cerr << " " << LLIArgs[i];
101 std::cerr << "\n";
102 );
103 return RunProgramWithTimeout(LLIPath, &LLIArgs[0],
104 InputFile, OutputFile, OutputFile);
105}
106
107// LLI create method - Try to find the LLI executable
Chris Lattner7915a1e2003-10-14 21:34:11 +0000108AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
Brian Gaeked11577b2004-05-04 21:09:01 +0000109 std::string &Message,
110 const std::vector<std::string> *ToolArgs) {
Chris Lattner7915a1e2003-10-14 21:34:11 +0000111 std::string LLIPath = FindExecutable("lli", ProgPath);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000112 if (!LLIPath.empty()) {
113 Message = "Found lli: " + LLIPath + "\n";
Brian Gaeked11577b2004-05-04 21:09:01 +0000114 return new LLI(LLIPath, ToolArgs);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000115 }
116
117 Message = "Cannot find `lli' in executable directory or PATH!\n";
118 return 0;
119}
120
121//===----------------------------------------------------------------------===//
122// LLC Implementation of AbstractIntepreter interface
123//
Chris Lattner8c56be52004-02-18 20:21:57 +0000124void LLC::OutputAsm(const std::string &Bytecode, std::string &OutputAsmFile) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000125 OutputAsmFile = getUniqueFilename(Bytecode+".llc.s");
Brian Gaeked11577b2004-05-04 21:09:01 +0000126 std::vector<const char *> LLCArgs;
127 LLCArgs.push_back (LLCPath.c_str());
128
129 // Add any extra LLC args.
130 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
131 LLCArgs.push_back(ToolArgs[i].c_str());
132
133 LLCArgs.push_back ("-o");
134 LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file
135 LLCArgs.push_back ("-f"); // Overwrite as necessary...
136 LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode
137 LLCArgs.push_back (0);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000138
139 std::cout << "<llc>" << std::flush;
Brian Gaeked11577b2004-05-04 21:09:01 +0000140 DEBUG(std::cerr << "\nAbout to run:\t";
141 for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
142 std::cerr << " " << LLCArgs[i];
143 std::cerr << "\n";
144 );
145 if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "/dev/null", "/dev/null",
Chris Lattner8c56be52004-02-18 20:21:57 +0000146 "/dev/null"))
Brian Gaeked11577b2004-05-04 21:09:01 +0000147 ProcessFailure(LLCPath, &LLCArgs[0]);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000148}
149
Chris Lattner9cbbee32004-02-18 23:24:41 +0000150void LLC::compileProgram(const std::string &Bytecode) {
151 std::string OutputAsmFile;
152 OutputAsm(Bytecode, OutputAsmFile);
153 removeFile(OutputAsmFile);
154}
155
Misha Brukman9558c6a2003-09-29 22:39:25 +0000156int LLC::ExecuteProgram(const std::string &Bytecode,
Chris Lattner7915a1e2003-10-14 21:34:11 +0000157 const std::vector<std::string> &Args,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000158 const std::string &InputFile,
159 const std::string &OutputFile,
Chris Lattnereeed9832003-10-14 21:52:52 +0000160 const std::vector<std::string> &SharedLibs) {
161
Misha Brukman9558c6a2003-09-29 22:39:25 +0000162 std::string OutputAsmFile;
Chris Lattner8c56be52004-02-18 20:21:57 +0000163 OutputAsm(Bytecode, OutputAsmFile);
164 FileRemover OutFileRemover(OutputAsmFile);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000165
166 // Assuming LLC worked, compile the result with GCC and run it.
Chris Lattner8c56be52004-02-18 20:21:57 +0000167 return gcc->ExecuteProgram(OutputAsmFile, Args, GCC::AsmFile,
168 InputFile, OutputFile, SharedLibs);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000169}
170
Chris Lattner7915a1e2003-10-14 21:34:11 +0000171/// createLLC - Try to find the LLC executable
Misha Brukman9558c6a2003-09-29 22:39:25 +0000172///
Chris Lattner7915a1e2003-10-14 21:34:11 +0000173LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath,
Brian Gaeked11577b2004-05-04 21:09:01 +0000174 std::string &Message,
175 const std::vector<std::string> *Args) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000176 std::string LLCPath = FindExecutable("llc", ProgramPath);
177 if (LLCPath.empty()) {
178 Message = "Cannot find `llc' in executable directory or PATH!\n";
179 return 0;
180 }
181
182 Message = "Found llc: " + LLCPath + "\n";
Chris Lattner7915a1e2003-10-14 21:34:11 +0000183 GCC *gcc = GCC::create(ProgramPath, Message);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000184 if (!gcc) {
185 std::cerr << Message << "\n";
186 exit(1);
187 }
Brian Gaeked11577b2004-05-04 21:09:01 +0000188 return new LLC(LLCPath, gcc, Args);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000189}
190
191//===---------------------------------------------------------------------===//
192// JIT Implementation of AbstractIntepreter interface
193//
Chris Lattner2cdd21c2003-12-14 21:35:53 +0000194namespace {
195 class JIT : public AbstractInterpreter {
196 std::string LLIPath; // The path to the LLI executable
Brian Gaeked11577b2004-05-04 21:09:01 +0000197 std::vector<std::string> ToolArgs; // Args to pass to LLI
Chris Lattner2cdd21c2003-12-14 21:35:53 +0000198 public:
Brian Gaeked11577b2004-05-04 21:09:01 +0000199 JIT(const std::string &Path, const std::vector<std::string> *Args)
200 : LLIPath(Path) {
201 ToolArgs.clear ();
Brian Gaeke48b008d2004-05-04 22:02:41 +0000202 if (Args) { ToolArgs = *Args; }
Brian Gaeked11577b2004-05-04 21:09:01 +0000203 }
Chris Lattner2cdd21c2003-12-14 21:35:53 +0000204
205 virtual int ExecuteProgram(const std::string &Bytecode,
206 const std::vector<std::string> &Args,
207 const std::string &InputFile,
208 const std::string &OutputFile,
209 const std::vector<std::string> &SharedLibs =
Chris Lattnereeed9832003-10-14 21:52:52 +0000210 std::vector<std::string>());
Chris Lattner2cdd21c2003-12-14 21:35:53 +0000211 };
212}
Misha Brukman9558c6a2003-09-29 22:39:25 +0000213
214int JIT::ExecuteProgram(const std::string &Bytecode,
Chris Lattner7915a1e2003-10-14 21:34:11 +0000215 const std::vector<std::string> &Args,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000216 const std::string &InputFile,
217 const std::string &OutputFile,
Chris Lattnereeed9832003-10-14 21:52:52 +0000218 const std::vector<std::string> &SharedLibs) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000219 // Construct a vector of parameters, incorporating those from the command-line
220 std::vector<const char*> JITArgs;
221 JITArgs.push_back(LLIPath.c_str());
Misha Brukman9558c6a2003-09-29 22:39:25 +0000222 JITArgs.push_back("-force-interpreter=false");
Chris Lattnereeed9832003-10-14 21:52:52 +0000223
Brian Gaeked11577b2004-05-04 21:09:01 +0000224 // Add any extra LLI args.
225 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
226 JITArgs.push_back(ToolArgs[i].c_str());
227
Chris Lattnereeed9832003-10-14 21:52:52 +0000228 for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000229 JITArgs.push_back("-load");
Chris Lattnereeed9832003-10-14 21:52:52 +0000230 JITArgs.push_back(SharedLibs[i].c_str());
Misha Brukman9558c6a2003-09-29 22:39:25 +0000231 }
232 JITArgs.push_back(Bytecode.c_str());
233 // Add optional parameters to the running program from Argv
234 for (unsigned i=0, e = Args.size(); i != e; ++i)
235 JITArgs.push_back(Args[i].c_str());
236 JITArgs.push_back(0);
237
238 std::cout << "<jit>" << std::flush;
Chris Lattner0b1fe842003-10-19 02:27:40 +0000239 DEBUG(std::cerr << "\nAbout to run:\t";
Chris Lattner7b2ccff2003-10-19 02:14:58 +0000240 for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
Misha Brukman9558c6a2003-09-29 22:39:25 +0000241 std::cerr << " " << JITArgs[i];
242 std::cerr << "\n";
243 );
244 DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
245 return RunProgramWithTimeout(LLIPath, &JITArgs[0],
246 InputFile, OutputFile, OutputFile);
247}
248
Chris Lattner7915a1e2003-10-14 21:34:11 +0000249/// createJIT - Try to find the LLI executable
Misha Brukman9558c6a2003-09-29 22:39:25 +0000250///
Chris Lattner7915a1e2003-10-14 21:34:11 +0000251AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
Brian Gaeked11577b2004-05-04 21:09:01 +0000252 std::string &Message, const std::vector<std::string> *Args) {
Chris Lattner7915a1e2003-10-14 21:34:11 +0000253 std::string LLIPath = FindExecutable("lli", ProgPath);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000254 if (!LLIPath.empty()) {
255 Message = "Found lli: " + LLIPath + "\n";
Brian Gaeked11577b2004-05-04 21:09:01 +0000256 return new JIT(LLIPath, Args);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000257 }
258
259 Message = "Cannot find `lli' in executable directory or PATH!\n";
260 return 0;
261}
262
Chris Lattner8c56be52004-02-18 20:21:57 +0000263void CBE::OutputC(const std::string &Bytecode,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000264 std::string &OutputCFile) {
265 OutputCFile = getUniqueFilename(Bytecode+".cbe.c");
Brian Gaeked11577b2004-05-04 21:09:01 +0000266 std::vector<const char *> LLCArgs;
267 LLCArgs.push_back (LLCPath.c_str());
268
269 // Add any extra LLC args.
270 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
271 LLCArgs.push_back(ToolArgs[i].c_str());
272
273 LLCArgs.push_back ("-o");
274 LLCArgs.push_back (OutputCFile.c_str()); // Output to the C file
275 LLCArgs.push_back ("-march=c"); // Output C language
276 LLCArgs.push_back ("-f"); // Overwrite as necessary...
277 LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode
278 LLCArgs.push_back (0);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000279
280 std::cout << "<cbe>" << std::flush;
Brian Gaeked11577b2004-05-04 21:09:01 +0000281 DEBUG(std::cerr << "\nAbout to run:\t";
282 for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
283 std::cerr << " " << LLCArgs[i];
284 std::cerr << "\n";
285 );
286 if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "/dev/null", "/dev/null",
Chris Lattner8c56be52004-02-18 20:21:57 +0000287 "/dev/null"))
Brian Gaeked11577b2004-05-04 21:09:01 +0000288 ProcessFailure(LLCPath, &LLCArgs[0]);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000289}
290
Chris Lattner9cbbee32004-02-18 23:24:41 +0000291void CBE::compileProgram(const std::string &Bytecode) {
292 std::string OutputCFile;
293 OutputC(Bytecode, OutputCFile);
294 removeFile(OutputCFile);
295}
296
Misha Brukman9558c6a2003-09-29 22:39:25 +0000297int CBE::ExecuteProgram(const std::string &Bytecode,
Chris Lattner7915a1e2003-10-14 21:34:11 +0000298 const std::vector<std::string> &Args,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000299 const std::string &InputFile,
300 const std::string &OutputFile,
Chris Lattnereeed9832003-10-14 21:52:52 +0000301 const std::vector<std::string> &SharedLibs) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000302 std::string OutputCFile;
Chris Lattner8c56be52004-02-18 20:21:57 +0000303 OutputC(Bytecode, OutputCFile);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000304
Chris Lattner8c56be52004-02-18 20:21:57 +0000305 FileRemover CFileRemove(OutputCFile);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000306
Chris Lattner8c56be52004-02-18 20:21:57 +0000307 return gcc->ExecuteProgram(OutputCFile, Args, GCC::CFile,
308 InputFile, OutputFile, SharedLibs);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000309}
310
Chris Lattner9915cd92004-02-17 06:40:06 +0000311/// createCBE - Try to find the 'llc' executable
Misha Brukman9558c6a2003-09-29 22:39:25 +0000312///
Chris Lattner7915a1e2003-10-14 21:34:11 +0000313CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
Brian Gaeked11577b2004-05-04 21:09:01 +0000314 std::string &Message,
315 const std::vector<std::string> *Args) {
Chris Lattner9915cd92004-02-17 06:40:06 +0000316 std::string LLCPath = FindExecutable("llc", ProgramPath);
317 if (LLCPath.empty()) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000318 Message =
Chris Lattner9915cd92004-02-17 06:40:06 +0000319 "Cannot find `llc' in executable directory or PATH!\n";
Misha Brukman9558c6a2003-09-29 22:39:25 +0000320 return 0;
321 }
322
Chris Lattner9915cd92004-02-17 06:40:06 +0000323 Message = "Found llc: " + LLCPath + "\n";
Chris Lattner7915a1e2003-10-14 21:34:11 +0000324 GCC *gcc = GCC::create(ProgramPath, Message);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000325 if (!gcc) {
326 std::cerr << Message << "\n";
327 exit(1);
328 }
Brian Gaeked11577b2004-05-04 21:09:01 +0000329 return new CBE(LLCPath, gcc, Args);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000330}
331
332//===---------------------------------------------------------------------===//
333// GCC abstraction
334//
Misha Brukman9558c6a2003-09-29 22:39:25 +0000335int GCC::ExecuteProgram(const std::string &ProgramFile,
Chris Lattner7915a1e2003-10-14 21:34:11 +0000336 const std::vector<std::string> &Args,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000337 FileType fileType,
338 const std::string &InputFile,
339 const std::string &OutputFile,
Chris Lattnereeed9832003-10-14 21:52:52 +0000340 const std::vector<std::string> &SharedLibs) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000341 std::vector<const char*> GCCArgs;
342
343 GCCArgs.push_back(GCCPath.c_str());
Chris Lattnereeed9832003-10-14 21:52:52 +0000344
345 // Specify the shared libraries to link in...
346 for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i)
347 GCCArgs.push_back(SharedLibs[i].c_str());
348
349 // Specify -x explicitly in case the extension is wonky
Misha Brukman9558c6a2003-09-29 22:39:25 +0000350 GCCArgs.push_back("-x");
351 if (fileType == CFile) {
352 GCCArgs.push_back("c");
353 GCCArgs.push_back("-fno-strict-aliasing");
354 } else {
355 GCCArgs.push_back("assembler");
356 }
357 GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename...
358 GCCArgs.push_back("-o");
Chris Lattnereeed9832003-10-14 21:52:52 +0000359 std::string OutputBinary = getUniqueFilename(ProgramFile+".gcc.exe");
Misha Brukman9558c6a2003-09-29 22:39:25 +0000360 GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
361 GCCArgs.push_back("-lm"); // Hard-code the math library...
362 GCCArgs.push_back("-O2"); // Optimize the program a bit...
Brian Gaekec8db76c2003-11-18 06:31:17 +0000363#if defined (HAVE_LINK_R)
Chris Lattner1f0f1622003-10-18 21:54:47 +0000364 GCCArgs.push_back("-Wl,-R."); // Search this dir for .so files
Brian Gaekec8db76c2003-11-18 06:31:17 +0000365#endif
Misha Brukman9558c6a2003-09-29 22:39:25 +0000366 GCCArgs.push_back(0); // NULL terminator
367
368 std::cout << "<gcc>" << std::flush;
369 if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "/dev/null", "/dev/null",
370 "/dev/null")) {
Chris Lattner89bf9ea2004-02-18 20:38:00 +0000371 ProcessFailure(GCCPath, &GCCArgs[0]);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000372 exit(1);
373 }
374
375 std::vector<const char*> ProgramArgs;
376 ProgramArgs.push_back(OutputBinary.c_str());
377 // Add optional parameters to the running program from Argv
378 for (unsigned i=0, e = Args.size(); i != e; ++i)
379 ProgramArgs.push_back(Args[i].c_str());
380 ProgramArgs.push_back(0); // NULL terminator
381
382 // Now that we have a binary, run it!
383 std::cout << "<program>" << std::flush;
Chris Lattner0b1fe842003-10-19 02:27:40 +0000384 DEBUG(std::cerr << "\nAbout to run:\t";
Chris Lattner7b2ccff2003-10-19 02:14:58 +0000385 for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
Misha Brukman9558c6a2003-09-29 22:39:25 +0000386 std::cerr << " " << ProgramArgs[i];
387 std::cerr << "\n";
388 );
Chris Lattner8c56be52004-02-18 20:21:57 +0000389
390 FileRemover OutputBinaryRemover(OutputBinary);
391 return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
392 InputFile, OutputFile, OutputFile);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000393}
394
Chris Lattner1798e4a2003-10-14 21:07:25 +0000395int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
Misha Brukman9558c6a2003-09-29 22:39:25 +0000396 std::string &OutputFile) {
John Criswell7f7d16b2004-01-26 20:59:41 +0000397 OutputFile = getUniqueFilename(InputFile+SHLIBEXT);
Misha Brukman9558c6a2003-09-29 22:39:25 +0000398 // Compile the C/asm file into a shared object
399 const char* GCCArgs[] = {
400 GCCPath.c_str(),
401 "-x", (fileType == AsmFile) ? "assembler" : "c",
402 "-fno-strict-aliasing",
403 InputFile.c_str(), // Specify the input filename...
404#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
405 "-G", // Compile a shared library, `-G' for Sparc
406#else
407 "-shared", // `-shared' for Linux/X86, maybe others
408#endif
409 "-o", OutputFile.c_str(), // Output to the right filename...
410 "-O2", // Optimize the program a bit...
411 0
412 };
413
414 std::cout << "<gcc>" << std::flush;
Chris Lattner1798e4a2003-10-14 21:07:25 +0000415 if (RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", "/dev/null",
416 "/dev/null")) {
Chris Lattner89bf9ea2004-02-18 20:38:00 +0000417 ProcessFailure(GCCPath, GCCArgs);
Chris Lattner1798e4a2003-10-14 21:07:25 +0000418 return 1;
Misha Brukman9558c6a2003-09-29 22:39:25 +0000419 }
420 return 0;
421}
422
Chris Lattner7915a1e2003-10-14 21:34:11 +0000423/// create - Try to find the `gcc' executable
Misha Brukman9558c6a2003-09-29 22:39:25 +0000424///
Chris Lattner7915a1e2003-10-14 21:34:11 +0000425GCC *GCC::create(const std::string &ProgramPath, std::string &Message) {
Misha Brukman9558c6a2003-09-29 22:39:25 +0000426 std::string GCCPath = FindExecutable("gcc", ProgramPath);
427 if (GCCPath.empty()) {
428 Message = "Cannot find `gcc' in executable directory or PATH!\n";
429 return 0;
430 }
431
432 Message = "Found gcc: " + GCCPath + "\n";
433 return new GCC(GCCPath);
434}