1 //===-- ToolRunner.cpp ----------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the interfaces described in the ToolRunner.h file.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "toolrunner"
15 #include "ToolRunner.h"
16 #include "llvm/System/Program.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/FileUtilities.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Config/config.h" // for HAVE_LINK_R
29 SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
34 RemoteClient("remote-client",
35 cl::desc("Remote execution client (rsh/ssh)"));
38 RemoteHost("remote-host",
39 cl::desc("Remote execution (rsh/ssh) host"));
42 RemotePort("remote-port",
43 cl::desc("Remote execution (rsh/ssh) port"));
46 RemoteUser("remote-user",
47 cl::desc("Remote execution (rsh/ssh) user id"));
50 RemoteExtra("remote-extra-options",
51 cl::desc("Remote execution (rsh/ssh) extra options"));
54 ToolExecutionError::~ToolExecutionError() throw() { }
56 /// RunProgramWithTimeout - This function provides an alternate interface
57 /// to the sys::Program::ExecuteAndWait interface.
58 /// @see sys:Program::ExecuteAndWait
59 static int RunProgramWithTimeout(const sys::Path
&ProgramPath
,
61 const sys::Path
&StdInFile
,
62 const sys::Path
&StdOutFile
,
63 const sys::Path
&StdErrFile
,
64 unsigned NumSeconds
= 0,
65 unsigned MemoryLimit
= 0) {
66 const sys::Path
* redirects
[3];
67 redirects
[0] = &StdInFile
;
68 redirects
[1] = &StdOutFile
;
69 redirects
[2] = &StdErrFile
;
71 #if 0 // For debug purposes
74 for (unsigned i
= 0; Args
[i
]; ++i
)
75 errs() << " " << Args
[i
];
81 sys::Program::ExecuteAndWait(ProgramPath
, Args
, 0, redirects
,
82 NumSeconds
, MemoryLimit
);
85 /// RunProgramRemotelyWithTimeout - This function runs the given program
86 /// remotely using the given remote client and the sys::Program::ExecuteAndWait.
87 /// Returns the remote program exit code or reports a remote client error if it
88 /// fails. Remote client is required to return 255 if it failed or program exit
90 /// @see sys:Program::ExecuteAndWait
91 static int RunProgramRemotelyWithTimeout(const sys::Path
&RemoteClientPath
,
93 const sys::Path
&StdInFile
,
94 const sys::Path
&StdOutFile
,
95 const sys::Path
&StdErrFile
,
96 unsigned NumSeconds
= 0,
97 unsigned MemoryLimit
= 0) {
98 const sys::Path
* redirects
[3];
99 redirects
[0] = &StdInFile
;
100 redirects
[1] = &StdOutFile
;
101 redirects
[2] = &StdErrFile
;
103 #if 0 // For debug purposes
106 for (unsigned i
= 0; Args
[i
]; ++i
)
107 errs() << " " << Args
[i
];
112 // Run the program remotely with the remote client
113 int ReturnCode
= sys::Program::ExecuteAndWait(RemoteClientPath
, Args
,
114 0, redirects
, NumSeconds
, MemoryLimit
);
116 // Has the remote client fail?
117 if (255 == ReturnCode
) {
118 std::ostringstream OS
;
119 OS
<< "\nError running remote client:\n ";
120 for (const char **Arg
= Args
; *Arg
; ++Arg
)
124 // The error message is in the output file, let's print it out from there.
125 std::ifstream
ErrorFile(StdOutFile
.c_str());
127 std::copy(std::istreambuf_iterator
<char>(ErrorFile
),
128 std::istreambuf_iterator
<char>(),
129 std::ostreambuf_iterator
<char>(OS
));
133 throw ToolExecutionError(OS
.str());
139 static void ProcessFailure(sys::Path ProgPath
, const char** Args
) {
140 std::ostringstream OS
;
141 OS
<< "\nError running tool:\n ";
142 for (const char **Arg
= Args
; *Arg
; ++Arg
)
146 // Rerun the compiler, capturing any error messages to print them.
147 sys::Path
ErrorFilename("bugpoint.program_error_messages");
149 if (ErrorFilename
.makeUnique(true, &ErrMsg
)) {
150 errs() << "Error making unique filename: " << ErrMsg
<< "\n";
153 RunProgramWithTimeout(ProgPath
, Args
, sys::Path(""), ErrorFilename
,
154 ErrorFilename
); // FIXME: check return code ?
156 // Print out the error messages generated by GCC if possible...
157 std::ifstream
ErrorFile(ErrorFilename
.c_str());
159 std::copy(std::istreambuf_iterator
<char>(ErrorFile
),
160 std::istreambuf_iterator
<char>(),
161 std::ostreambuf_iterator
<char>(OS
));
165 ErrorFilename
.eraseFromDisk();
166 throw ToolExecutionError(OS
.str());
169 //===---------------------------------------------------------------------===//
170 // LLI Implementation of AbstractIntepreter interface
173 class LLI
: public AbstractInterpreter
{
174 std::string LLIPath
; // The path to the LLI executable
175 std::vector
<std::string
> ToolArgs
; // Args to pass to LLI
177 LLI(const std::string
&Path
, const std::vector
<std::string
> *Args
)
180 if (Args
) { ToolArgs
= *Args
; }
183 virtual int ExecuteProgram(const std::string
&Bitcode
,
184 const std::vector
<std::string
> &Args
,
185 const std::string
&InputFile
,
186 const std::string
&OutputFile
,
187 const std::vector
<std::string
> &GCCArgs
,
188 const std::vector
<std::string
> &SharedLibs
=
189 std::vector
<std::string
>(),
190 unsigned Timeout
= 0,
191 unsigned MemoryLimit
= 0);
195 int LLI::ExecuteProgram(const std::string
&Bitcode
,
196 const std::vector
<std::string
> &Args
,
197 const std::string
&InputFile
,
198 const std::string
&OutputFile
,
199 const std::vector
<std::string
> &GCCArgs
,
200 const std::vector
<std::string
> &SharedLibs
,
202 unsigned MemoryLimit
) {
203 if (!SharedLibs
.empty())
204 throw ToolExecutionError("LLI currently does not support "
205 "loading shared libraries.");
207 std::vector
<const char*> LLIArgs
;
208 LLIArgs
.push_back(LLIPath
.c_str());
209 LLIArgs
.push_back("-force-interpreter=true");
211 // Add any extra LLI args.
212 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
213 LLIArgs
.push_back(ToolArgs
[i
].c_str());
215 LLIArgs
.push_back(Bitcode
.c_str());
216 // Add optional parameters to the running program from Argv
217 for (unsigned i
=0, e
= Args
.size(); i
!= e
; ++i
)
218 LLIArgs
.push_back(Args
[i
].c_str());
219 LLIArgs
.push_back(0);
221 outs() << "<lli>"; outs().flush();
222 DEBUG(errs() << "\nAbout to run:\t";
223 for (unsigned i
=0, e
= LLIArgs
.size()-1; i
!= e
; ++i
)
224 errs() << " " << LLIArgs
[i
];
227 return RunProgramWithTimeout(sys::Path(LLIPath
), &LLIArgs
[0],
228 sys::Path(InputFile
), sys::Path(OutputFile
), sys::Path(OutputFile
),
229 Timeout
, MemoryLimit
);
232 // LLI create method - Try to find the LLI executable
233 AbstractInterpreter
*AbstractInterpreter::createLLI(const char *Argv0
,
234 std::string
&Message
,
235 const std::vector
<std::string
> *ToolArgs
) {
236 std::string LLIPath
=
237 FindExecutable("lli", Argv0
, (void *)(intptr_t)&createLLI
).str();
238 if (!LLIPath
.empty()) {
239 Message
= "Found lli: " + LLIPath
+ "\n";
240 return new LLI(LLIPath
, ToolArgs
);
243 Message
= "Cannot find `lli' in executable directory or PATH!\n";
247 //===---------------------------------------------------------------------===//
248 // Custom execution command implementation of AbstractIntepreter interface
250 // Allows using a custom command for executing the bitcode, thus allows,
251 // for example, to invoke a cross compiler for code generation followed by
252 // a simulator that executes the generated binary.
254 class CustomExecutor
: public AbstractInterpreter
{
255 std::string ExecutionCommand
;
256 std::vector
<std::string
> ExecutorArgs
;
259 const std::string
&ExecutionCmd
, std::vector
<std::string
> ExecArgs
) :
260 ExecutionCommand(ExecutionCmd
), ExecutorArgs(ExecArgs
) {}
262 virtual int ExecuteProgram(const std::string
&Bitcode
,
263 const std::vector
<std::string
> &Args
,
264 const std::string
&InputFile
,
265 const std::string
&OutputFile
,
266 const std::vector
<std::string
> &GCCArgs
,
267 const std::vector
<std::string
> &SharedLibs
=
268 std::vector
<std::string
>(),
269 unsigned Timeout
= 0,
270 unsigned MemoryLimit
= 0);
274 int CustomExecutor::ExecuteProgram(const std::string
&Bitcode
,
275 const std::vector
<std::string
> &Args
,
276 const std::string
&InputFile
,
277 const std::string
&OutputFile
,
278 const std::vector
<std::string
> &GCCArgs
,
279 const std::vector
<std::string
> &SharedLibs
,
281 unsigned MemoryLimit
) {
283 std::vector
<const char*> ProgramArgs
;
284 ProgramArgs
.push_back(ExecutionCommand
.c_str());
286 for (std::size_t i
= 0; i
< ExecutorArgs
.size(); ++i
)
287 ProgramArgs
.push_back(ExecutorArgs
.at(i
).c_str());
288 ProgramArgs
.push_back(Bitcode
.c_str());
289 ProgramArgs
.push_back(0);
291 // Add optional parameters to the running program from Argv
292 for (unsigned i
=0, e
= Args
.size(); i
!= e
; ++i
)
293 ProgramArgs
.push_back(Args
[i
].c_str());
295 return RunProgramWithTimeout(
296 sys::Path(ExecutionCommand
),
297 &ProgramArgs
[0], sys::Path(InputFile
), sys::Path(OutputFile
),
298 sys::Path(OutputFile
), Timeout
, MemoryLimit
);
301 // Custom execution environment create method, takes the execution command
303 AbstractInterpreter
*AbstractInterpreter::createCustom(
304 std::string
&Message
,
305 const std::string
&ExecCommandLine
) {
307 std::string Command
= "";
308 std::vector
<std::string
> Args
;
309 std::string delimiters
= " ";
311 // Tokenize the ExecCommandLine to the command and the args to allow
312 // defining a full command line as the command instead of just the
313 // executed program. We cannot just pass the whole string after the command
314 // as a single argument because then program sees only a single
315 // command line argument (with spaces in it: "foo bar" instead
316 // of "foo" and "bar").
318 // code borrowed from:
319 // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
320 std::string::size_type lastPos
=
321 ExecCommandLine
.find_first_not_of(delimiters
, 0);
322 std::string::size_type pos
=
323 ExecCommandLine
.find_first_of(delimiters
, lastPos
);
325 while (std::string::npos
!= pos
|| std::string::npos
!= lastPos
) {
326 std::string token
= ExecCommandLine
.substr(lastPos
, pos
- lastPos
);
330 Args
.push_back(token
);
331 // Skip delimiters. Note the "not_of"
332 lastPos
= ExecCommandLine
.find_first_not_of(delimiters
, pos
);
333 // Find next "non-delimiter"
334 pos
= ExecCommandLine
.find_first_of(delimiters
, lastPos
);
337 std::string CmdPath
= sys::Program::FindProgramByName(Command
).str();
338 if (CmdPath
.empty()) {
340 std::string("Cannot find '") + Command
+
341 "' in executable directory or PATH!\n";
345 Message
= "Found command in: " + CmdPath
+ "\n";
347 return new CustomExecutor(CmdPath
, Args
);
350 //===----------------------------------------------------------------------===//
351 // LLC Implementation of AbstractIntepreter interface
353 GCC::FileType
LLC::OutputCode(const std::string
&Bitcode
,
354 sys::Path
&OutputAsmFile
) {
355 sys::Path
uniqueFile(Bitcode
+".llc.s");
357 if (uniqueFile
.makeUnique(true, &ErrMsg
)) {
358 errs() << "Error making unique filename: " << ErrMsg
<< "\n";
361 OutputAsmFile
= uniqueFile
;
362 std::vector
<const char *> LLCArgs
;
363 LLCArgs
.push_back (LLCPath
.c_str());
365 // Add any extra LLC args.
366 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
367 LLCArgs
.push_back(ToolArgs
[i
].c_str());
369 LLCArgs
.push_back ("-o");
370 LLCArgs
.push_back (OutputAsmFile
.c_str()); // Output to the Asm file
371 LLCArgs
.push_back (Bitcode
.c_str()); // This is the input bitcode
372 LLCArgs
.push_back (0);
374 outs() << "<llc>"; outs().flush();
375 DEBUG(errs() << "\nAbout to run:\t";
376 for (unsigned i
=0, e
= LLCArgs
.size()-1; i
!= e
; ++i
)
377 errs() << " " << LLCArgs
[i
];
380 if (RunProgramWithTimeout(sys::Path(LLCPath
), &LLCArgs
[0],
381 sys::Path(), sys::Path(), sys::Path()))
382 ProcessFailure(sys::Path(LLCPath
), &LLCArgs
[0]);
387 void LLC::compileProgram(const std::string
&Bitcode
) {
388 sys::Path OutputAsmFile
;
389 OutputCode(Bitcode
, OutputAsmFile
);
390 OutputAsmFile
.eraseFromDisk();
393 int LLC::ExecuteProgram(const std::string
&Bitcode
,
394 const std::vector
<std::string
> &Args
,
395 const std::string
&InputFile
,
396 const std::string
&OutputFile
,
397 const std::vector
<std::string
> &ArgsForGCC
,
398 const std::vector
<std::string
> &SharedLibs
,
400 unsigned MemoryLimit
) {
402 sys::Path OutputAsmFile
;
403 OutputCode(Bitcode
, OutputAsmFile
);
404 FileRemover
OutFileRemover(OutputAsmFile
, !SaveTemps
);
406 std::vector
<std::string
> GCCArgs(ArgsForGCC
);
407 GCCArgs
.insert(GCCArgs
.end(), SharedLibs
.begin(), SharedLibs
.end());
408 GCCArgs
.insert(GCCArgs
.end(), gccArgs
.begin(), gccArgs
.end());
410 // Assuming LLC worked, compile the result with GCC and run it.
411 return gcc
->ExecuteProgram(OutputAsmFile
.str(), Args
, GCC::AsmFile
,
412 InputFile
, OutputFile
, GCCArgs
,
413 Timeout
, MemoryLimit
);
416 /// createLLC - Try to find the LLC executable
418 LLC
*AbstractInterpreter::createLLC(const char *Argv0
,
419 std::string
&Message
,
420 const std::vector
<std::string
> *Args
,
421 const std::vector
<std::string
> *GCCArgs
) {
422 std::string LLCPath
=
423 FindExecutable("llc", Argv0
, (void *)(intptr_t)&createLLC
).str();
424 if (LLCPath
.empty()) {
425 Message
= "Cannot find `llc' in executable directory or PATH!\n";
429 Message
= "Found llc: " + LLCPath
+ "\n";
430 GCC
*gcc
= GCC::create(Message
, GCCArgs
);
432 errs() << Message
<< "\n";
435 return new LLC(LLCPath
, gcc
, Args
, GCCArgs
);
438 //===---------------------------------------------------------------------===//
439 // JIT Implementation of AbstractIntepreter interface
442 class JIT
: public AbstractInterpreter
{
443 std::string LLIPath
; // The path to the LLI executable
444 std::vector
<std::string
> ToolArgs
; // Args to pass to LLI
446 JIT(const std::string
&Path
, const std::vector
<std::string
> *Args
)
449 if (Args
) { ToolArgs
= *Args
; }
452 virtual int ExecuteProgram(const std::string
&Bitcode
,
453 const std::vector
<std::string
> &Args
,
454 const std::string
&InputFile
,
455 const std::string
&OutputFile
,
456 const std::vector
<std::string
> &GCCArgs
=
457 std::vector
<std::string
>(),
458 const std::vector
<std::string
> &SharedLibs
=
459 std::vector
<std::string
>(),
461 unsigned MemoryLimit
=0);
465 int JIT::ExecuteProgram(const std::string
&Bitcode
,
466 const std::vector
<std::string
> &Args
,
467 const std::string
&InputFile
,
468 const std::string
&OutputFile
,
469 const std::vector
<std::string
> &GCCArgs
,
470 const std::vector
<std::string
> &SharedLibs
,
472 unsigned MemoryLimit
) {
473 // Construct a vector of parameters, incorporating those from the command-line
474 std::vector
<const char*> JITArgs
;
475 JITArgs
.push_back(LLIPath
.c_str());
476 JITArgs
.push_back("-force-interpreter=false");
478 // Add any extra LLI args.
479 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
480 JITArgs
.push_back(ToolArgs
[i
].c_str());
482 for (unsigned i
= 0, e
= SharedLibs
.size(); i
!= e
; ++i
) {
483 JITArgs
.push_back("-load");
484 JITArgs
.push_back(SharedLibs
[i
].c_str());
486 JITArgs
.push_back(Bitcode
.c_str());
487 // Add optional parameters to the running program from Argv
488 for (unsigned i
=0, e
= Args
.size(); i
!= e
; ++i
)
489 JITArgs
.push_back(Args
[i
].c_str());
490 JITArgs
.push_back(0);
492 outs() << "<jit>"; outs().flush();
493 DEBUG(errs() << "\nAbout to run:\t";
494 for (unsigned i
=0, e
= JITArgs
.size()-1; i
!= e
; ++i
)
495 errs() << " " << JITArgs
[i
];
498 DEBUG(errs() << "\nSending output to " << OutputFile
<< "\n");
499 return RunProgramWithTimeout(sys::Path(LLIPath
), &JITArgs
[0],
500 sys::Path(InputFile
), sys::Path(OutputFile
), sys::Path(OutputFile
),
501 Timeout
, MemoryLimit
);
504 /// createJIT - Try to find the LLI executable
506 AbstractInterpreter
*AbstractInterpreter::createJIT(const char *Argv0
,
507 std::string
&Message
, const std::vector
<std::string
> *Args
) {
508 std::string LLIPath
=
509 FindExecutable("lli", Argv0
, (void *)(intptr_t)&createJIT
).str();
510 if (!LLIPath
.empty()) {
511 Message
= "Found lli: " + LLIPath
+ "\n";
512 return new JIT(LLIPath
, Args
);
515 Message
= "Cannot find `lli' in executable directory or PATH!\n";
519 GCC::FileType
CBE::OutputCode(const std::string
&Bitcode
,
520 sys::Path
&OutputCFile
) {
521 sys::Path
uniqueFile(Bitcode
+".cbe.c");
523 if (uniqueFile
.makeUnique(true, &ErrMsg
)) {
524 errs() << "Error making unique filename: " << ErrMsg
<< "\n";
527 OutputCFile
= uniqueFile
;
528 std::vector
<const char *> LLCArgs
;
529 LLCArgs
.push_back (LLCPath
.c_str());
531 // Add any extra LLC args.
532 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
533 LLCArgs
.push_back(ToolArgs
[i
].c_str());
535 LLCArgs
.push_back ("-o");
536 LLCArgs
.push_back (OutputCFile
.c_str()); // Output to the C file
537 LLCArgs
.push_back ("-march=c"); // Output C language
538 LLCArgs
.push_back ("-f"); // Overwrite as necessary...
539 LLCArgs
.push_back (Bitcode
.c_str()); // This is the input bitcode
540 LLCArgs
.push_back (0);
542 outs() << "<cbe>"; outs().flush();
543 DEBUG(errs() << "\nAbout to run:\t";
544 for (unsigned i
=0, e
= LLCArgs
.size()-1; i
!= e
; ++i
)
545 errs() << " " << LLCArgs
[i
];
548 if (RunProgramWithTimeout(LLCPath
, &LLCArgs
[0], sys::Path(), sys::Path(),
550 ProcessFailure(LLCPath
, &LLCArgs
[0]);
554 void CBE::compileProgram(const std::string
&Bitcode
) {
555 sys::Path OutputCFile
;
556 OutputCode(Bitcode
, OutputCFile
);
557 OutputCFile
.eraseFromDisk();
560 int CBE::ExecuteProgram(const std::string
&Bitcode
,
561 const std::vector
<std::string
> &Args
,
562 const std::string
&InputFile
,
563 const std::string
&OutputFile
,
564 const std::vector
<std::string
> &ArgsForGCC
,
565 const std::vector
<std::string
> &SharedLibs
,
567 unsigned MemoryLimit
) {
568 sys::Path OutputCFile
;
569 OutputCode(Bitcode
, OutputCFile
);
571 FileRemover
CFileRemove(OutputCFile
, !SaveTemps
);
573 std::vector
<std::string
> GCCArgs(ArgsForGCC
);
574 GCCArgs
.insert(GCCArgs
.end(), SharedLibs
.begin(), SharedLibs
.end());
576 return gcc
->ExecuteProgram(OutputCFile
.str(), Args
, GCC::CFile
,
577 InputFile
, OutputFile
, GCCArgs
,
578 Timeout
, MemoryLimit
);
581 /// createCBE - Try to find the 'llc' executable
583 CBE
*AbstractInterpreter::createCBE(const char *Argv0
,
584 std::string
&Message
,
585 const std::vector
<std::string
> *Args
,
586 const std::vector
<std::string
> *GCCArgs
) {
588 FindExecutable("llc", Argv0
, (void *)(intptr_t)&createCBE
);
589 if (LLCPath
.isEmpty()) {
591 "Cannot find `llc' in executable directory or PATH!\n";
595 Message
= "Found llc: " + LLCPath
.str() + "\n";
596 GCC
*gcc
= GCC::create(Message
, GCCArgs
);
598 errs() << Message
<< "\n";
601 return new CBE(LLCPath
, gcc
, Args
);
604 //===---------------------------------------------------------------------===//
609 IsARMArchitecture(std::vector
<std::string
> Args
)
611 for (std::vector
<std::string
>::const_iterator
612 I
= Args
.begin(), E
= Args
.end(); I
!= E
; ++I
) {
613 if (!StringsEqualNoCase(*I
, "-arch")) {
615 if ((I
!= E
) && !StringsEqualNoCase(I
->c_str(), "arm", strlen("arm"))) {
624 int GCC::ExecuteProgram(const std::string
&ProgramFile
,
625 const std::vector
<std::string
> &Args
,
627 const std::string
&InputFile
,
628 const std::string
&OutputFile
,
629 const std::vector
<std::string
> &ArgsForGCC
,
631 unsigned MemoryLimit
) {
632 std::vector
<const char*> GCCArgs
;
634 GCCArgs
.push_back(GCCPath
.c_str());
636 for (std::vector
<std::string
>::const_iterator
637 I
= gccArgs
.begin(), E
= gccArgs
.end(); I
!= E
; ++I
)
638 GCCArgs
.push_back(I
->c_str());
640 // Specify -x explicitly in case the extension is wonky
641 GCCArgs
.push_back("-x");
642 if (fileType
== CFile
) {
643 GCCArgs
.push_back("c");
644 GCCArgs
.push_back("-fno-strict-aliasing");
646 GCCArgs
.push_back("assembler");
648 // For ARM architectures we don't want this flag. bugpoint isn't
649 // explicitly told what architecture it is working on, so we get
651 if ((TargetTriple
.getOS() == Triple::Darwin
) &&
652 !IsARMArchitecture(ArgsForGCC
))
653 GCCArgs
.push_back("-force_cpusubtype_ALL");
655 GCCArgs
.push_back(ProgramFile
.c_str()); // Specify the input filename...
656 GCCArgs
.push_back("-x");
657 GCCArgs
.push_back("none");
658 GCCArgs
.push_back("-o");
659 sys::Path
OutputBinary (ProgramFile
+".gcc.exe");
661 if (OutputBinary
.makeUnique(true, &ErrMsg
)) {
662 errs() << "Error making unique filename: " << ErrMsg
<< "\n";
665 GCCArgs
.push_back(OutputBinary
.c_str()); // Output to the right file...
667 // Add any arguments intended for GCC. We locate them here because this is
668 // most likely -L and -l options that need to come before other libraries but
669 // after the source. Other options won't be sensitive to placement on the
670 // command line, so this should be safe.
671 for (unsigned i
= 0, e
= ArgsForGCC
.size(); i
!= e
; ++i
)
672 GCCArgs
.push_back(ArgsForGCC
[i
].c_str());
674 GCCArgs
.push_back("-lm"); // Hard-code the math library...
675 GCCArgs
.push_back("-O2"); // Optimize the program a bit...
676 #if defined (HAVE_LINK_R)
677 GCCArgs
.push_back("-Wl,-R."); // Search this dir for .so files
679 if (TargetTriple
.getArch() == Triple::sparc
)
680 GCCArgs
.push_back("-mcpu=v9");
681 GCCArgs
.push_back(0); // NULL terminator
683 outs() << "<gcc>"; outs().flush();
684 DEBUG(errs() << "\nAbout to run:\t";
685 for (unsigned i
=0, e
= GCCArgs
.size()-1; i
!= e
; ++i
)
686 errs() << " " << GCCArgs
[i
];
689 if (RunProgramWithTimeout(GCCPath
, &GCCArgs
[0], sys::Path(), sys::Path(),
691 ProcessFailure(GCCPath
, &GCCArgs
[0]);
695 std::vector
<const char*> ProgramArgs
;
697 if (RemoteClientPath
.isEmpty())
698 ProgramArgs
.push_back(OutputBinary
.c_str());
700 ProgramArgs
.push_back(RemoteClientPath
.c_str());
701 ProgramArgs
.push_back(RemoteHost
.c_str());
702 if (!RemoteUser
.empty()) {
703 ProgramArgs
.push_back("-l");
704 ProgramArgs
.push_back(RemoteUser
.c_str());
706 if (!RemotePort
.empty()) {
707 ProgramArgs
.push_back("-p");
708 ProgramArgs
.push_back(RemotePort
.c_str());
710 if (!RemoteExtra
.empty()) {
711 ProgramArgs
.push_back(RemoteExtra
.c_str());
714 // Full path to the binary. We need to cd to the exec directory because
715 // there is a dylib there that the exec expects to find in the CWD
716 char* env_pwd
= getenv("PWD");
717 std::string Exec
= "cd ";
720 Exec
+= OutputBinary
.c_str();
721 ProgramArgs
.push_back(Exec
.c_str());
724 // Add optional parameters to the running program from Argv
725 for (unsigned i
=0, e
= Args
.size(); i
!= e
; ++i
)
726 ProgramArgs
.push_back(Args
[i
].c_str());
727 ProgramArgs
.push_back(0); // NULL terminator
729 // Now that we have a binary, run it!
730 outs() << "<program>"; outs().flush();
731 DEBUG(errs() << "\nAbout to run:\t";
732 for (unsigned i
=0, e
= ProgramArgs
.size()-1; i
!= e
; ++i
)
733 errs() << " " << ProgramArgs
[i
];
737 FileRemover
OutputBinaryRemover(OutputBinary
, !SaveTemps
);
739 if (RemoteClientPath
.isEmpty()) {
740 DEBUG(errs() << "<run locally>";);
741 return RunProgramWithTimeout(OutputBinary
, &ProgramArgs
[0],
742 sys::Path(InputFile
), sys::Path(OutputFile
), sys::Path(OutputFile
),
743 Timeout
, MemoryLimit
);
745 outs() << "<run remotely>"; outs().flush();
746 return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath
),
747 &ProgramArgs
[0], sys::Path(InputFile
), sys::Path(OutputFile
),
748 sys::Path(OutputFile
), Timeout
, MemoryLimit
);
752 int GCC::MakeSharedObject(const std::string
&InputFile
, FileType fileType
,
753 std::string
&OutputFile
,
754 const std::vector
<std::string
> &ArgsForGCC
) {
755 sys::Path
uniqueFilename(InputFile
+LTDL_SHLIB_EXT
);
757 if (uniqueFilename
.makeUnique(true, &ErrMsg
)) {
758 errs() << "Error making unique filename: " << ErrMsg
<< "\n";
761 OutputFile
= uniqueFilename
.str();
763 std::vector
<const char*> GCCArgs
;
765 GCCArgs
.push_back(GCCPath
.c_str());
767 for (std::vector
<std::string
>::const_iterator
768 I
= gccArgs
.begin(), E
= gccArgs
.end(); I
!= E
; ++I
)
769 GCCArgs
.push_back(I
->c_str());
771 // Compile the C/asm file into a shared object
772 GCCArgs
.push_back("-x");
773 GCCArgs
.push_back(fileType
== AsmFile
? "assembler" : "c");
774 GCCArgs
.push_back("-fno-strict-aliasing");
775 GCCArgs
.push_back(InputFile
.c_str()); // Specify the input filename.
776 GCCArgs
.push_back("-x");
777 GCCArgs
.push_back("none");
778 if (TargetTriple
.getArch() == Triple::sparc
)
779 GCCArgs
.push_back("-G"); // Compile a shared library, `-G' for Sparc
780 else if (TargetTriple
.getOS() == Triple::Darwin
) {
781 // link all source files into a single module in data segment, rather than
782 // generating blocks. dynamic_lookup requires that you set
783 // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
784 // bugpoint to just pass that in the environment of GCC.
785 GCCArgs
.push_back("-single_module");
786 GCCArgs
.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC
787 GCCArgs
.push_back("-undefined");
788 GCCArgs
.push_back("dynamic_lookup");
790 GCCArgs
.push_back("-shared"); // `-shared' for Linux/X86, maybe others
792 if ((TargetTriple
.getArch() == Triple::alpha
) ||
793 (TargetTriple
.getArch() == Triple::x86_64
))
794 GCCArgs
.push_back("-fPIC"); // Requires shared objs to contain PIC
796 if (TargetTriple
.getArch() == Triple::sparc
)
797 GCCArgs
.push_back("-mcpu=v9");
799 GCCArgs
.push_back("-o");
800 GCCArgs
.push_back(OutputFile
.c_str()); // Output to the right filename.
801 GCCArgs
.push_back("-O2"); // Optimize the program a bit.
805 // Add any arguments intended for GCC. We locate them here because this is
806 // most likely -L and -l options that need to come before other libraries but
807 // after the source. Other options won't be sensitive to placement on the
808 // command line, so this should be safe.
809 for (unsigned i
= 0, e
= ArgsForGCC
.size(); i
!= e
; ++i
)
810 GCCArgs
.push_back(ArgsForGCC
[i
].c_str());
811 GCCArgs
.push_back(0); // NULL terminator
815 outs() << "<gcc>"; outs().flush();
816 DEBUG(errs() << "\nAbout to run:\t";
817 for (unsigned i
=0, e
= GCCArgs
.size()-1; i
!= e
; ++i
)
818 errs() << " " << GCCArgs
[i
];
821 if (RunProgramWithTimeout(GCCPath
, &GCCArgs
[0], sys::Path(), sys::Path(),
823 ProcessFailure(GCCPath
, &GCCArgs
[0]);
829 /// create - Try to find the `gcc' executable
831 GCC
*GCC::create(std::string
&Message
,
832 const std::vector
<std::string
> *Args
) {
833 sys::Path GCCPath
= sys::Program::FindProgramByName("gcc");
834 if (GCCPath
.isEmpty()) {
835 Message
= "Cannot find `gcc' in executable directory or PATH!\n";
839 sys::Path RemoteClientPath
;
840 if (!RemoteClient
.empty())
841 RemoteClientPath
= sys::Program::FindProgramByName(RemoteClient
);
843 Message
= "Found gcc: " + GCCPath
.str() + "\n";
844 return new GCC(GCCPath
, RemoteClientPath
, Args
);