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 #include "ToolRunner.h"
15 #include "llvm/Config/config.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/FileUtilities.h"
20 #include "llvm/Support/Program.h"
21 #include "llvm/Support/raw_ostream.h"
27 #define DEBUG_TYPE "toolrunner"
30 cl::opt
<bool> SaveTemps("save-temps", cl::init(false),
31 cl::desc("Save temporary files"));
36 RemoteClient("remote-client",
37 cl::desc("Remote execution client (rsh/ssh)"));
39 cl::opt
<std::string
> RemoteHost("remote-host",
40 cl::desc("Remote execution (rsh/ssh) host"));
42 cl::opt
<std::string
> RemotePort("remote-port",
43 cl::desc("Remote execution (rsh/ssh) port"));
45 cl::opt
<std::string
> RemoteUser("remote-user",
46 cl::desc("Remote execution (rsh/ssh) user id"));
49 RemoteExtra("remote-extra-options",
50 cl::desc("Remote execution (rsh/ssh) extra options"));
53 /// RunProgramWithTimeout - This function provides an alternate interface
54 /// to the sys::Program::ExecuteAndWait interface.
55 /// @see sys::Program::ExecuteAndWait
56 static int RunProgramWithTimeout(StringRef ProgramPath
,
57 ArrayRef
<StringRef
> Args
, StringRef StdInFile
,
58 StringRef StdOutFile
, StringRef StdErrFile
,
59 unsigned NumSeconds
= 0,
60 unsigned MemoryLimit
= 0,
61 std::string
*ErrMsg
= nullptr) {
62 Optional
<StringRef
> Redirects
[3] = {StdInFile
, StdOutFile
, StdErrFile
};
63 return sys::ExecuteAndWait(ProgramPath
, Args
, None
, Redirects
, NumSeconds
,
67 /// RunProgramRemotelyWithTimeout - This function runs the given program
68 /// remotely using the given remote client and the sys::Program::ExecuteAndWait.
69 /// Returns the remote program exit code or reports a remote client error if it
70 /// fails. Remote client is required to return 255 if it failed or program exit
72 /// @see sys::Program::ExecuteAndWait
73 static int RunProgramRemotelyWithTimeout(
74 StringRef RemoteClientPath
, ArrayRef
<StringRef
> Args
, StringRef StdInFile
,
75 StringRef StdOutFile
, StringRef StdErrFile
, unsigned NumSeconds
= 0,
76 unsigned MemoryLimit
= 0) {
77 Optional
<StringRef
> Redirects
[3] = {StdInFile
, StdOutFile
, StdErrFile
};
79 // Run the program remotely with the remote client
80 int ReturnCode
= sys::ExecuteAndWait(RemoteClientPath
, Args
, None
, Redirects
,
81 NumSeconds
, MemoryLimit
);
83 // Has the remote client fail?
84 if (255 == ReturnCode
) {
85 std::ostringstream OS
;
86 OS
<< "\nError running remote client:\n ";
87 for (StringRef Arg
: Args
)
88 OS
<< " " << Arg
.str();
91 // The error message is in the output file, let's print it out from there.
92 std::string StdOutFileName
= StdOutFile
.str();
93 std::ifstream
ErrorFile(StdOutFileName
.c_str());
95 std::copy(std::istreambuf_iterator
<char>(ErrorFile
),
96 std::istreambuf_iterator
<char>(),
97 std::ostreambuf_iterator
<char>(OS
));
107 static Error
ProcessFailure(StringRef ProgPath
, ArrayRef
<StringRef
> Args
,
108 unsigned Timeout
= 0, unsigned MemoryLimit
= 0) {
109 std::ostringstream OS
;
110 OS
<< "\nError running tool:\n ";
111 for (StringRef Arg
: Args
)
112 OS
<< " " << Arg
.str();
115 // Rerun the compiler, capturing any error messages to print them.
116 SmallString
<128> ErrorFilename
;
117 std::error_code EC
= sys::fs::createTemporaryFile(
118 "bugpoint.program_error_messages", "", ErrorFilename
);
120 errs() << "Error making unique filename: " << EC
.message() << "\n";
124 RunProgramWithTimeout(ProgPath
, Args
, "", ErrorFilename
.str(),
125 ErrorFilename
.str(), Timeout
, MemoryLimit
);
126 // FIXME: check return code ?
128 // Print out the error messages generated by CC if possible...
129 std::ifstream
ErrorFile(ErrorFilename
.c_str());
131 std::copy(std::istreambuf_iterator
<char>(ErrorFile
),
132 std::istreambuf_iterator
<char>(),
133 std::ostreambuf_iterator
<char>(OS
));
137 sys::fs::remove(ErrorFilename
.c_str());
138 return make_error
<StringError
>(OS
.str(), inconvertibleErrorCode());
141 //===---------------------------------------------------------------------===//
142 // LLI Implementation of AbstractIntepreter interface
145 class LLI
: public AbstractInterpreter
{
146 std::string LLIPath
; // The path to the LLI executable
147 std::vector
<std::string
> ToolArgs
; // Args to pass to LLI
149 LLI(const std::string
&Path
, const std::vector
<std::string
> *Args
)
157 Expected
<int> ExecuteProgram(
158 const std::string
&Bitcode
, const std::vector
<std::string
> &Args
,
159 const std::string
&InputFile
, const std::string
&OutputFile
,
160 const std::vector
<std::string
> &CCArgs
,
161 const std::vector
<std::string
> &SharedLibs
= std::vector
<std::string
>(),
162 unsigned Timeout
= 0, unsigned MemoryLimit
= 0) override
;
166 Expected
<int> LLI::ExecuteProgram(const std::string
&Bitcode
,
167 const std::vector
<std::string
> &Args
,
168 const std::string
&InputFile
,
169 const std::string
&OutputFile
,
170 const std::vector
<std::string
> &CCArgs
,
171 const std::vector
<std::string
> &SharedLibs
,
172 unsigned Timeout
, unsigned MemoryLimit
) {
173 std::vector
<StringRef
> LLIArgs
;
174 LLIArgs
.push_back(LLIPath
.c_str());
175 LLIArgs
.push_back("-force-interpreter=true");
177 for (std::vector
<std::string
>::const_iterator i
= SharedLibs
.begin(),
178 e
= SharedLibs
.end();
180 LLIArgs
.push_back("-load");
181 LLIArgs
.push_back(*i
);
184 // Add any extra LLI args.
185 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
186 LLIArgs
.push_back(ToolArgs
[i
]);
188 LLIArgs
.push_back(Bitcode
);
189 // Add optional parameters to the running program from Argv
190 for (unsigned i
= 0, e
= Args
.size(); i
!= e
; ++i
)
191 LLIArgs
.push_back(Args
[i
]);
195 LLVM_DEBUG(errs() << "\nAbout to run:\t";
196 for (unsigned i
= 0, e
= LLIArgs
.size() - 1; i
!= e
; ++i
) errs()
197 << " " << LLIArgs
[i
];
199 return RunProgramWithTimeout(LLIPath
, LLIArgs
, InputFile
, OutputFile
,
200 OutputFile
, Timeout
, MemoryLimit
);
203 void AbstractInterpreter::anchor() {}
205 #if defined(LLVM_ON_UNIX)
206 const char EXESuffix
[] = "";
207 #elif defined(_WIN32)
208 const char EXESuffix
[] = "exe";
211 /// Prepend the path to the program being executed
212 /// to \p ExeName, given the value of argv[0] and the address of main()
213 /// itself. This allows us to find another LLVM tool if it is built in the same
214 /// directory. An empty string is returned on error; note that this function
215 /// just mainpulates the path and doesn't check for executability.
216 /// Find a named executable.
217 static std::string
PrependMainExecutablePath(const std::string
&ExeName
,
220 // Check the directory that the calling program is in. We can do
221 // this if ProgramPath contains at least one / character, indicating that it
222 // is a relative path to the executable itself.
223 std::string Main
= sys::fs::getMainExecutable(Argv0
, MainAddr
);
224 StringRef Result
= sys::path::parent_path(Main
);
226 if (!Result
.empty()) {
227 SmallString
<128> Storage
= Result
;
228 sys::path::append(Storage
, ExeName
);
229 sys::path::replace_extension(Storage
, EXESuffix
);
230 return Storage
.str();
236 // LLI create method - Try to find the LLI executable
237 AbstractInterpreter
*
238 AbstractInterpreter::createLLI(const char *Argv0
, std::string
&Message
,
239 const std::vector
<std::string
> *ToolArgs
) {
240 std::string LLIPath
=
241 PrependMainExecutablePath("lli", Argv0
, (void *)(intptr_t)&createLLI
);
242 if (!LLIPath
.empty()) {
243 Message
= "Found lli: " + LLIPath
+ "\n";
244 return new LLI(LLIPath
, ToolArgs
);
247 Message
= "Cannot find `lli' in executable directory!\n";
251 //===---------------------------------------------------------------------===//
252 // Custom compiler command implementation of AbstractIntepreter interface
254 // Allows using a custom command for compiling the bitcode, thus allows, for
255 // example, to compile a bitcode fragment without linking or executing, then
256 // using a custom wrapper script to check for compiler errors.
258 class CustomCompiler
: public AbstractInterpreter
{
259 std::string CompilerCommand
;
260 std::vector
<std::string
> CompilerArgs
;
263 CustomCompiler(const std::string
&CompilerCmd
,
264 std::vector
<std::string
> CompArgs
)
265 : CompilerCommand(CompilerCmd
), CompilerArgs(std::move(CompArgs
)) {}
267 Error
compileProgram(const std::string
&Bitcode
, unsigned Timeout
= 0,
268 unsigned MemoryLimit
= 0) override
;
270 Expected
<int> ExecuteProgram(
271 const std::string
&Bitcode
, const std::vector
<std::string
> &Args
,
272 const std::string
&InputFile
, const std::string
&OutputFile
,
273 const std::vector
<std::string
> &CCArgs
= std::vector
<std::string
>(),
274 const std::vector
<std::string
> &SharedLibs
= std::vector
<std::string
>(),
275 unsigned Timeout
= 0, unsigned MemoryLimit
= 0) override
{
276 return make_error
<StringError
>(
277 "Execution not supported with -compile-custom",
278 inconvertibleErrorCode());
283 Error
CustomCompiler::compileProgram(const std::string
&Bitcode
,
284 unsigned Timeout
, unsigned MemoryLimit
) {
286 std::vector
<StringRef
> ProgramArgs
;
287 ProgramArgs
.push_back(CompilerCommand
.c_str());
289 for (std::size_t i
= 0; i
< CompilerArgs
.size(); ++i
)
290 ProgramArgs
.push_back(CompilerArgs
.at(i
).c_str());
291 ProgramArgs
.push_back(Bitcode
);
293 // Add optional parameters to the running program from Argv
294 for (unsigned i
= 0, e
= CompilerArgs
.size(); i
!= e
; ++i
)
295 ProgramArgs
.push_back(CompilerArgs
[i
].c_str());
297 if (RunProgramWithTimeout(CompilerCommand
, ProgramArgs
, "", "", "", Timeout
,
299 return ProcessFailure(CompilerCommand
, ProgramArgs
, Timeout
, MemoryLimit
);
300 return Error::success();
303 //===---------------------------------------------------------------------===//
304 // Custom execution command implementation of AbstractIntepreter interface
306 // Allows using a custom command for executing the bitcode, thus allows,
307 // for example, to invoke a cross compiler for code generation followed by
308 // a simulator that executes the generated binary.
310 class CustomExecutor
: public AbstractInterpreter
{
311 std::string ExecutionCommand
;
312 std::vector
<std::string
> ExecutorArgs
;
315 CustomExecutor(const std::string
&ExecutionCmd
,
316 std::vector
<std::string
> ExecArgs
)
317 : ExecutionCommand(ExecutionCmd
), ExecutorArgs(std::move(ExecArgs
)) {}
319 Expected
<int> ExecuteProgram(
320 const std::string
&Bitcode
, const std::vector
<std::string
> &Args
,
321 const std::string
&InputFile
, const std::string
&OutputFile
,
322 const std::vector
<std::string
> &CCArgs
,
323 const std::vector
<std::string
> &SharedLibs
= std::vector
<std::string
>(),
324 unsigned Timeout
= 0, unsigned MemoryLimit
= 0) override
;
328 Expected
<int> CustomExecutor::ExecuteProgram(
329 const std::string
&Bitcode
, const std::vector
<std::string
> &Args
,
330 const std::string
&InputFile
, const std::string
&OutputFile
,
331 const std::vector
<std::string
> &CCArgs
,
332 const std::vector
<std::string
> &SharedLibs
, unsigned Timeout
,
333 unsigned MemoryLimit
) {
335 std::vector
<StringRef
> ProgramArgs
;
336 ProgramArgs
.push_back(ExecutionCommand
);
338 for (std::size_t i
= 0; i
< ExecutorArgs
.size(); ++i
)
339 ProgramArgs
.push_back(ExecutorArgs
[i
]);
340 ProgramArgs
.push_back(Bitcode
);
342 // Add optional parameters to the running program from Argv
343 for (unsigned i
= 0, e
= Args
.size(); i
!= e
; ++i
)
344 ProgramArgs
.push_back(Args
[i
]);
346 return RunProgramWithTimeout(ExecutionCommand
, ProgramArgs
, InputFile
,
347 OutputFile
, OutputFile
, Timeout
, MemoryLimit
);
350 // Tokenize the CommandLine to the command and the args to allow
351 // defining a full command line as the command instead of just the
352 // executed program. We cannot just pass the whole string after the command
353 // as a single argument because then the program sees only a single
354 // command line argument (with spaces in it: "foo bar" instead
355 // of "foo" and "bar").
357 // Spaces are used as a delimiter; however repeated, leading, and trailing
358 // whitespace are ignored. Simple escaping is allowed via the '\'
359 // character, as seen below:
361 // Two consecutive '\' evaluate to a single '\'.
362 // A space after a '\' evaluates to a space that is not interpreted as a
364 // Any other instances of the '\' character are removed.
369 // 'exa\mple' -> 'example'
371 static void lexCommand(std::string
&Message
, const std::string
&CommandLine
,
372 std::string
&CmdPath
, std::vector
<std::string
> &Args
) {
376 bool FoundPath
= false;
378 // first argument is the PATH.
379 // Skip repeated whitespace, leading whitespace and trailing whitespace.
380 for (std::size_t Pos
= 0u; Pos
<= CommandLine
.size(); ++Pos
) {
381 if ('\\' == CommandLine
[Pos
]) {
382 if (Pos
+ 1 < CommandLine
.size())
383 Token
.push_back(CommandLine
[++Pos
]);
387 if (' ' == CommandLine
[Pos
] || CommandLine
.size() == Pos
) {
398 Args
.push_back(Token
);
402 Token
.push_back(CommandLine
[Pos
]);
405 auto Path
= sys::findProgramByName(Command
);
407 Message
= std::string("Cannot find '") + Command
+
408 "' in PATH: " + Path
.getError().message() + "\n";
413 Message
= "Found command in: " + CmdPath
+ "\n";
416 // Custom execution environment create method, takes the execution command
418 AbstractInterpreter
*AbstractInterpreter::createCustomCompiler(
419 std::string
&Message
, const std::string
&CompileCommandLine
) {
422 std::vector
<std::string
> Args
;
423 lexCommand(Message
, CompileCommandLine
, CmdPath
, Args
);
427 return new CustomCompiler(CmdPath
, Args
);
430 // Custom execution environment create method, takes the execution command
432 AbstractInterpreter
*
433 AbstractInterpreter::createCustomExecutor(std::string
&Message
,
434 const std::string
&ExecCommandLine
) {
437 std::vector
<std::string
> Args
;
438 lexCommand(Message
, ExecCommandLine
, CmdPath
, Args
);
442 return new CustomExecutor(CmdPath
, Args
);
445 //===----------------------------------------------------------------------===//
446 // LLC Implementation of AbstractIntepreter interface
448 Expected
<CC::FileType
> LLC::OutputCode(const std::string
&Bitcode
,
449 std::string
&OutputAsmFile
,
450 unsigned Timeout
, unsigned MemoryLimit
) {
451 const char *Suffix
= (UseIntegratedAssembler
? ".llc.o" : ".llc.s");
453 SmallString
<128> UniqueFile
;
455 sys::fs::createUniqueFile(Bitcode
+ "-%%%%%%%" + Suffix
, UniqueFile
);
457 errs() << "Error making unique filename: " << EC
.message() << "\n";
460 OutputAsmFile
= UniqueFile
.str();
461 std::vector
<StringRef
> LLCArgs
;
462 LLCArgs
.push_back(LLCPath
);
464 // Add any extra LLC args.
465 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
466 LLCArgs
.push_back(ToolArgs
[i
]);
468 LLCArgs
.push_back("-o");
469 LLCArgs
.push_back(OutputAsmFile
); // Output to the Asm file
470 LLCArgs
.push_back(Bitcode
); // This is the input bitcode
472 if (UseIntegratedAssembler
)
473 LLCArgs
.push_back("-filetype=obj");
475 outs() << (UseIntegratedAssembler
? "<llc-ia>" : "<llc>");
477 LLVM_DEBUG(errs() << "\nAbout to run:\t";
478 for (unsigned i
= 0, e
= LLCArgs
.size() - 1; i
!= e
; ++i
) errs()
479 << " " << LLCArgs
[i
];
481 if (RunProgramWithTimeout(LLCPath
, LLCArgs
, "", "", "", Timeout
, MemoryLimit
))
482 return ProcessFailure(LLCPath
, LLCArgs
, Timeout
, MemoryLimit
);
483 return UseIntegratedAssembler
? CC::ObjectFile
: CC::AsmFile
;
486 Error
LLC::compileProgram(const std::string
&Bitcode
, unsigned Timeout
,
487 unsigned MemoryLimit
) {
488 std::string OutputAsmFile
;
489 Expected
<CC::FileType
> Result
=
490 OutputCode(Bitcode
, OutputAsmFile
, Timeout
, MemoryLimit
);
491 sys::fs::remove(OutputAsmFile
);
492 if (Error E
= Result
.takeError())
494 return Error::success();
497 Expected
<int> LLC::ExecuteProgram(const std::string
&Bitcode
,
498 const std::vector
<std::string
> &Args
,
499 const std::string
&InputFile
,
500 const std::string
&OutputFile
,
501 const std::vector
<std::string
> &ArgsForCC
,
502 const std::vector
<std::string
> &SharedLibs
,
503 unsigned Timeout
, unsigned MemoryLimit
) {
505 std::string OutputAsmFile
;
506 Expected
<CC::FileType
> FileKind
=
507 OutputCode(Bitcode
, OutputAsmFile
, Timeout
, MemoryLimit
);
508 FileRemover
OutFileRemover(OutputAsmFile
, !SaveTemps
);
509 if (Error E
= FileKind
.takeError())
512 std::vector
<std::string
> CCArgs(ArgsForCC
);
513 CCArgs
.insert(CCArgs
.end(), SharedLibs
.begin(), SharedLibs
.end());
515 // Assuming LLC worked, compile the result with CC and run it.
516 return cc
->ExecuteProgram(OutputAsmFile
, Args
, *FileKind
, InputFile
,
517 OutputFile
, CCArgs
, Timeout
, MemoryLimit
);
520 /// createLLC - Try to find the LLC executable
522 LLC
*AbstractInterpreter::createLLC(const char *Argv0
, std::string
&Message
,
523 const std::string
&CCBinary
,
524 const std::vector
<std::string
> *Args
,
525 const std::vector
<std::string
> *CCArgs
,
526 bool UseIntegratedAssembler
) {
527 std::string LLCPath
=
528 PrependMainExecutablePath("llc", Argv0
, (void *)(intptr_t)&createLLC
);
529 if (LLCPath
.empty()) {
530 Message
= "Cannot find `llc' in executable directory!\n";
534 CC
*cc
= CC::create(Message
, CCBinary
, CCArgs
);
536 errs() << Message
<< "\n";
539 Message
= "Found llc: " + LLCPath
+ "\n";
540 return new LLC(LLCPath
, cc
, Args
, UseIntegratedAssembler
);
543 //===---------------------------------------------------------------------===//
544 // JIT Implementation of AbstractIntepreter interface
547 class JIT
: public AbstractInterpreter
{
548 std::string LLIPath
; // The path to the LLI executable
549 std::vector
<std::string
> ToolArgs
; // Args to pass to LLI
551 JIT(const std::string
&Path
, const std::vector
<std::string
> *Args
)
559 Expected
<int> ExecuteProgram(
560 const std::string
&Bitcode
, const std::vector
<std::string
> &Args
,
561 const std::string
&InputFile
, const std::string
&OutputFile
,
562 const std::vector
<std::string
> &CCArgs
= std::vector
<std::string
>(),
563 const std::vector
<std::string
> &SharedLibs
= std::vector
<std::string
>(),
564 unsigned Timeout
= 0, unsigned MemoryLimit
= 0) override
;
568 Expected
<int> JIT::ExecuteProgram(const std::string
&Bitcode
,
569 const std::vector
<std::string
> &Args
,
570 const std::string
&InputFile
,
571 const std::string
&OutputFile
,
572 const std::vector
<std::string
> &CCArgs
,
573 const std::vector
<std::string
> &SharedLibs
,
574 unsigned Timeout
, unsigned MemoryLimit
) {
575 // Construct a vector of parameters, incorporating those from the command-line
576 std::vector
<StringRef
> JITArgs
;
577 JITArgs
.push_back(LLIPath
.c_str());
578 JITArgs
.push_back("-force-interpreter=false");
580 // Add any extra LLI args.
581 for (unsigned i
= 0, e
= ToolArgs
.size(); i
!= e
; ++i
)
582 JITArgs
.push_back(ToolArgs
[i
]);
584 for (unsigned i
= 0, e
= SharedLibs
.size(); i
!= e
; ++i
) {
585 JITArgs
.push_back("-load");
586 JITArgs
.push_back(SharedLibs
[i
]);
588 JITArgs
.push_back(Bitcode
.c_str());
589 // Add optional parameters to the running program from Argv
590 for (unsigned i
= 0, e
= Args
.size(); i
!= e
; ++i
)
591 JITArgs
.push_back(Args
[i
]);
595 LLVM_DEBUG(errs() << "\nAbout to run:\t";
596 for (unsigned i
= 0, e
= JITArgs
.size() - 1; i
!= e
; ++i
) errs()
597 << " " << JITArgs
[i
];
599 LLVM_DEBUG(errs() << "\nSending output to " << OutputFile
<< "\n");
600 return RunProgramWithTimeout(LLIPath
, JITArgs
, InputFile
, OutputFile
,
601 OutputFile
, Timeout
, MemoryLimit
);
604 /// createJIT - Try to find the LLI executable
606 AbstractInterpreter
*
607 AbstractInterpreter::createJIT(const char *Argv0
, std::string
&Message
,
608 const std::vector
<std::string
> *Args
) {
609 std::string LLIPath
=
610 PrependMainExecutablePath("lli", Argv0
, (void *)(intptr_t)&createJIT
);
611 if (!LLIPath
.empty()) {
612 Message
= "Found lli: " + LLIPath
+ "\n";
613 return new JIT(LLIPath
, Args
);
616 Message
= "Cannot find `lli' in executable directory!\n";
620 //===---------------------------------------------------------------------===//
624 static bool IsARMArchitecture(std::vector
<StringRef
> Args
) {
625 for (size_t I
= 0; I
< Args
.size(); ++I
) {
626 if (!Args
[I
].equals_lower("-arch"))
629 if (I
== Args
.size())
631 if (Args
[I
].startswith_lower("arm"))
638 Expected
<int> CC::ExecuteProgram(const std::string
&ProgramFile
,
639 const std::vector
<std::string
> &Args
,
641 const std::string
&InputFile
,
642 const std::string
&OutputFile
,
643 const std::vector
<std::string
> &ArgsForCC
,
644 unsigned Timeout
, unsigned MemoryLimit
) {
645 std::vector
<StringRef
> CCArgs
;
647 CCArgs
.push_back(CCPath
);
649 if (TargetTriple
.getArch() == Triple::x86
)
650 CCArgs
.push_back("-m32");
652 for (std::vector
<std::string
>::const_iterator I
= ccArgs
.begin(),
655 CCArgs
.push_back(*I
);
657 // Specify -x explicitly in case the extension is wonky
658 if (fileType
!= ObjectFile
) {
659 CCArgs
.push_back("-x");
660 if (fileType
== CFile
) {
661 CCArgs
.push_back("c");
662 CCArgs
.push_back("-fno-strict-aliasing");
664 CCArgs
.push_back("assembler");
666 // For ARM architectures we don't want this flag. bugpoint isn't
667 // explicitly told what architecture it is working on, so we get
669 if (TargetTriple
.isOSDarwin() && !IsARMArchitecture(CCArgs
))
670 CCArgs
.push_back("-force_cpusubtype_ALL");
674 CCArgs
.push_back(ProgramFile
); // Specify the input filename.
676 CCArgs
.push_back("-x");
677 CCArgs
.push_back("none");
678 CCArgs
.push_back("-o");
680 SmallString
<128> OutputBinary
;
682 sys::fs::createUniqueFile(ProgramFile
+ "-%%%%%%%.cc.exe", OutputBinary
);
684 errs() << "Error making unique filename: " << EC
.message() << "\n";
687 CCArgs
.push_back(OutputBinary
); // Output to the right file...
689 // Add any arguments intended for CC. We locate them here because this is
690 // most likely -L and -l options that need to come before other libraries but
691 // after the source. Other options won't be sensitive to placement on the
692 // command line, so this should be safe.
693 for (unsigned i
= 0, e
= ArgsForCC
.size(); i
!= e
; ++i
)
694 CCArgs
.push_back(ArgsForCC
[i
]);
696 CCArgs
.push_back("-lm"); // Hard-code the math library...
697 CCArgs
.push_back("-O2"); // Optimize the program a bit...
698 if (TargetTriple
.getArch() == Triple::sparc
)
699 CCArgs
.push_back("-mcpu=v9");
703 LLVM_DEBUG(errs() << "\nAbout to run:\t";
704 for (unsigned i
= 0, e
= CCArgs
.size() - 1; i
!= e
; ++i
) errs()
707 if (RunProgramWithTimeout(CCPath
, CCArgs
, "", "", ""))
708 return ProcessFailure(CCPath
, CCArgs
);
710 std::vector
<StringRef
> ProgramArgs
;
712 // Declared here so that the destructor only runs after
713 // ProgramArgs is used.
716 if (RemoteClientPath
.empty())
717 ProgramArgs
.push_back(OutputBinary
);
719 ProgramArgs
.push_back(RemoteClientPath
);
720 ProgramArgs
.push_back(RemoteHost
);
721 if (!RemoteUser
.empty()) {
722 ProgramArgs
.push_back("-l");
723 ProgramArgs
.push_back(RemoteUser
);
725 if (!RemotePort
.empty()) {
726 ProgramArgs
.push_back("-p");
727 ProgramArgs
.push_back(RemotePort
);
729 if (!RemoteExtra
.empty()) {
730 ProgramArgs
.push_back(RemoteExtra
);
733 // Full path to the binary. We need to cd to the exec directory because
734 // there is a dylib there that the exec expects to find in the CWD
735 char *env_pwd
= getenv("PWD");
739 Exec
+= OutputBinary
.c_str();
740 ProgramArgs
.push_back(Exec
);
743 // Add optional parameters to the running program from Argv
744 for (unsigned i
= 0, e
= Args
.size(); i
!= e
; ++i
)
745 ProgramArgs
.push_back(Args
[i
]);
747 // Now that we have a binary, run it!
748 outs() << "<program>";
751 errs() << "\nAbout to run:\t";
752 for (unsigned i
= 0, e
= ProgramArgs
.size() - 1; i
!= e
; ++i
) errs()
753 << " " << ProgramArgs
[i
];
756 FileRemover
OutputBinaryRemover(OutputBinary
.str(), !SaveTemps
);
758 if (RemoteClientPath
.empty()) {
759 LLVM_DEBUG(errs() << "<run locally>");
761 int ExitCode
= RunProgramWithTimeout(OutputBinary
.str(), ProgramArgs
,
762 InputFile
, OutputFile
, OutputFile
,
763 Timeout
, MemoryLimit
, &Error
);
764 // Treat a signal (usually SIGSEGV) or timeout as part of the program output
765 // so that crash-causing miscompilation is handled seamlessly.
767 std::ofstream
outFile(OutputFile
.c_str(), std::ios_base::app
);
768 outFile
<< Error
<< '\n';
773 outs() << "<run remotely>";
775 return RunProgramRemotelyWithTimeout(RemoteClientPath
, ProgramArgs
,
776 InputFile
, OutputFile
, OutputFile
,
777 Timeout
, MemoryLimit
);
781 Error
CC::MakeSharedObject(const std::string
&InputFile
, FileType fileType
,
782 std::string
&OutputFile
,
783 const std::vector
<std::string
> &ArgsForCC
) {
784 SmallString
<128> UniqueFilename
;
785 std::error_code EC
= sys::fs::createUniqueFile(
786 InputFile
+ "-%%%%%%%" + LTDL_SHLIB_EXT
, UniqueFilename
);
788 errs() << "Error making unique filename: " << EC
.message() << "\n";
791 OutputFile
= UniqueFilename
.str();
793 std::vector
<StringRef
> CCArgs
;
795 CCArgs
.push_back(CCPath
);
797 if (TargetTriple
.getArch() == Triple::x86
)
798 CCArgs
.push_back("-m32");
800 for (std::vector
<std::string
>::const_iterator I
= ccArgs
.begin(),
803 CCArgs
.push_back(*I
);
805 // Compile the C/asm file into a shared object
806 if (fileType
!= ObjectFile
) {
807 CCArgs
.push_back("-x");
808 CCArgs
.push_back(fileType
== AsmFile
? "assembler" : "c");
810 CCArgs
.push_back("-fno-strict-aliasing");
811 CCArgs
.push_back(InputFile
); // Specify the input filename.
812 CCArgs
.push_back("-x");
813 CCArgs
.push_back("none");
814 if (TargetTriple
.getArch() == Triple::sparc
)
815 CCArgs
.push_back("-G"); // Compile a shared library, `-G' for Sparc
816 else if (TargetTriple
.isOSDarwin()) {
817 // link all source files into a single module in data segment, rather than
818 // generating blocks. dynamic_lookup requires that you set
819 // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
820 // bugpoint to just pass that in the environment of CC.
821 CCArgs
.push_back("-single_module");
822 CCArgs
.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC
823 CCArgs
.push_back("-undefined");
824 CCArgs
.push_back("dynamic_lookup");
826 CCArgs
.push_back("-shared"); // `-shared' for Linux/X86, maybe others
828 if (TargetTriple
.getArch() == Triple::x86_64
)
829 CCArgs
.push_back("-fPIC"); // Requires shared objs to contain PIC
831 if (TargetTriple
.getArch() == Triple::sparc
)
832 CCArgs
.push_back("-mcpu=v9");
834 CCArgs
.push_back("-o");
835 CCArgs
.push_back(OutputFile
); // Output to the right filename.
836 CCArgs
.push_back("-O2"); // Optimize the program a bit.
838 // Add any arguments intended for CC. We locate them here because this is
839 // most likely -L and -l options that need to come before other libraries but
840 // after the source. Other options won't be sensitive to placement on the
841 // command line, so this should be safe.
842 for (unsigned i
= 0, e
= ArgsForCC
.size(); i
!= e
; ++i
)
843 CCArgs
.push_back(ArgsForCC
[i
]);
847 LLVM_DEBUG(errs() << "\nAbout to run:\t";
848 for (unsigned i
= 0, e
= CCArgs
.size() - 1; i
!= e
; ++i
) errs()
851 if (RunProgramWithTimeout(CCPath
, CCArgs
, "", "", ""))
852 return ProcessFailure(CCPath
, CCArgs
);
853 return Error::success();
856 /// create - Try to find the CC executable
858 CC
*CC::create(std::string
&Message
, const std::string
&CCBinary
,
859 const std::vector
<std::string
> *Args
) {
860 auto CCPath
= sys::findProgramByName(CCBinary
);
862 Message
= "Cannot find `" + CCBinary
+ "' in PATH: " +
863 CCPath
.getError().message() + "\n";
867 std::string RemoteClientPath
;
868 if (!RemoteClient
.empty()) {
869 auto Path
= sys::findProgramByName(RemoteClient
);
871 Message
= "Cannot find `" + RemoteClient
+ "' in PATH: " +
872 Path
.getError().message() + "\n";
875 RemoteClientPath
= *Path
;
878 Message
= "Found CC: " + *CCPath
+ "\n";
879 return new CC(*CCPath
, RemoteClientPath
, Args
);