Main.cpp revision 331310e1f3f86a795f78e42b3f03558a43829f09
1331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines/*
2331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Copyright 2012, The Android Open Source Project
3331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
4331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * you may not use this file except in compliance with the License.
6331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * You may obtain a copy of the License at
7331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
8331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines *
10331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * Unless required by applicable law or agreed to in writing, software
11331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * See the License for the specific language governing permissions and
14331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines * limitations under the License.
15331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines */
16331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
17331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <string>
18331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <vector>
19331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
20331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <stdlib.h>
21331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
22331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/ADT/STLExtras.h>
23331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/ADT/SmallString.h>
24331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Config/config.h>
25331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/CommandLine.h>
26331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/FileSystem.h>
27331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/Path.h>
28331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/raw_ostream.h>
29331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <llvm/Support/system_error.h>
30331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
31331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/BCCContext.h>
32331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Compiler.h>
33331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Config/BuildInfo.h>
34331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Config/Config.h>
35331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/ExecutionEngine/BCCRuntimeSymbolResolver.h>
36331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/ExecutionEngine/ObjectLoader.h>
37331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/ExecutionEngine/SymbolResolverProxy.h>
38331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/ExecutionEngine/SymbolResolvers.h>
39331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Renderscript/RSCompilerDriver.h>
40331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Script.h>
41331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Source.h>
42331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/CompilerConfig.h>
43331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/Initialization.h>
44331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/InputFile.h>
45331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/OutputFile.h>
46331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <bcc/Support/TargetCompilerConfigs.h>
47331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
48331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesusing namespace bcc;
49331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
50331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
51331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// General Options
52331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
53331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesnamespace {
54331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
55331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::list<std::string>
56331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptInputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore,
57331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                  llvm::cl::desc("<input bitcode files>"));
58331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
59331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
60331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptOutputFilename("o", llvm::cl::desc("Specify the output filename"),
61331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                  llvm::cl::value_desc("filename"));
62331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
63331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
64331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptRuntimePath("rt-path", llvm::cl::desc("Specify the runtime library path"),
65331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines               llvm::cl::value_desc("path"));
66331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
67331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#ifdef TARGET_BUILD
68331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesconst std::string OptTargetTriple(DEFAULT_TARGET_TRIPLE_STRING);
69331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#else
70331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
71331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptTargetTriple("mtriple",
72331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::desc("Specify the target triple (default: "
73331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                               DEFAULT_TARGET_TRIPLE_STRING ")"),
74331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING),
75331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                llvm::cl::value_desc("triple"));
76331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
77331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden,
78331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                 llvm::cl::desc("Alias for -mtriple"),
79331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                 llvm::cl::aliasopt(OptTargetTriple));
80331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#endif
81331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
82331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
83331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Compiler Options
84331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
85331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
86331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptPIC("fPIC", llvm::cl::desc("Generate fully relocatable, position independent"
87331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                              " code"));
88331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
89331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<char>
90331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptOptLevel("O", llvm::cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
91331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                "(default: -O2)"),
92331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines            llvm::cl::Prefix, llvm::cl::ZeroOrMore, llvm::cl::init('2'));
93331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
94331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
95331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptC("c", llvm::cl::desc("Compile and assemble, but do not link."));
96331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
97331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
98331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Linker Options
99331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//===----------------------------------------------------------------------===//
100331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// FIXME: this option will be removed in the future when MCLinker is capable
101331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//        of generating shared library directly from given bitcode. It only
102331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines//        takes effect when -shared is supplied.
103331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<std::string>
104331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptImmObjectOutput("or", llvm::cl::desc("Specify the filename for output the "
105331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "intermediate relocatable when linking "
106331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "the input bitcode to the shared "
107331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                        "library"), llvm::cl::ValueRequired);
108331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
109331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesllvm::cl::opt<bool>
110331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesOptShared("shared", llvm::cl::desc("Create a shared library from input bitcode "
111331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                                   "files"));
112331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
113331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
114331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Override "bcc -version" since the LLVM version information is not correct on
115331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines// Android build.
116331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesvoid BCCVersionPrinter() {
117331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::raw_ostream &os = llvm::outs();
118331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  os << "libbcc (The Android Open Source Project, http://www.android.com/):\n"
119331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Build time: " << BuildInfo::GetBuildTime() << "\n"
120331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Build revision: " << BuildInfo::GetBuildRev() << "\n"
121331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Build source blob: " << BuildInfo::GetBuildSourceBlob() << "\n"
122331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n";
123331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
124331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  os << "\n";
125331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
126331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  os << "LLVM (http://llvm.org/):\n"
127331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines     << "  Version: " << PACKAGE_VERSION << "\n";
128331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return;
129331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
130331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
131331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines} // end anonymous namespace
132331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
133331310e1f3f86a795f78e42b3f03558a43829f09Stephen HinesRSScript *PrepareRSScript(BCCContext &pContext,
134331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                          const llvm::cl::list<std::string> &pBitcodeFiles) {
135331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  RSScript *result = NULL;
136331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
137331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  for (unsigned i = 0; i < pBitcodeFiles.size(); i++) {
138331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    const std::string &input_bitcode = pBitcodeFiles[i];
139331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    Source *source = Source::CreateFromFile(pContext, input_bitcode);
140331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    if (source == NULL) {
141331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      llvm::errs() << "Failed to load llvm module from file `" << input_bitcode
142331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                   << "'!\n";
143331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      return NULL;
144331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
145331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
146331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    if (result != NULL) {
147331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      if (!result->mergeSource(*source, /* pPreserveSource */false)) {
148331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        llvm::errs() << "Failed to merge the llvm module `" << input_bitcode
149331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                     << "' to compile!\n";
150331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        delete source;
151331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        return NULL;
152331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      }
153331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    } else {
154331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      result = new (std::nothrow) RSScript(*source);
155331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      if (result == NULL) {
156331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        llvm::errs() << "Out of memory when create script for file `"
157331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                     << input_bitcode << "'!\n";
158331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        delete source;
159331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines        return NULL;
160331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      }
161331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
162331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
163331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
164331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return result;
165331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
166331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
167331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstatic inline
168331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesbool ConfigCompiler(RSCompilerDriver &pCompilerDriver) {
169331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  RSCompiler *compiler = pCompilerDriver.getCompiler();
170331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  CompilerConfig *config = NULL;
171331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
172331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#ifdef TARGET_BUILD
173331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  config = new (std::nothrow) DefaultCompilerConfig();
174331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#else
175331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  config = new (std::nothrow) CompilerConfig(OptTargetTriple);
176331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#endif
177331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (config == NULL) {
178331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Out of memory when create the compiler configuration!\n";
179331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return false;
180331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
181331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
182331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // Setup the config according to the value of command line option.
183331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptPIC) {
184331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    config->setRelocationModel(llvm::Reloc::PIC_);
185331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
186331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  switch (OptOptLevel) {
187331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
188331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
189331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '3': config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive); break;
190331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '2':
191331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    default: {
192331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      config->setOptimizationLevel(llvm::CodeGenOpt::Default);
193331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      break;
194331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
195331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
196331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
197331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  pCompilerDriver.setConfig(config);
198331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler::ErrorCode result = compiler->config(*config);
199331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
200331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (result != Compiler::kSuccess) {
201331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to configure the compiler! (detail: "
202331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << Compiler::GetErrorString(result) << ")\n";
203331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return false;
204331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
205331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
206331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return true;
207331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
208331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
209331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#define DEFAULT_OUTPUT_PATH   "/sdcard/a.out"
210331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstatic inline
211331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstd::string DetermineOutputFilename(const std::string &pOutputPath) {
212331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!pOutputPath.empty()) {
213331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return pOutputPath;
214331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
215331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
216331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // User doesn't specify the value to -o.
217331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptInputFilenames.size() > 1) {
218331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
219331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return DEFAULT_OUTPUT_PATH;
220331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
221331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
222331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // There's only one input bitcode file.
223331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  const std::string &input_path = OptInputFilenames[0];
224331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::SmallString<200> output_path(input_path);
225331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
226331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::error_code err = llvm::sys::fs::make_absolute(output_path);
227331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (err != llvm::errc::success) {
228331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to determine the absolute path of `" << input_path
229331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << "'! (detail: " << err.message() << ")\n";
230331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return "";
231331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
232331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
233331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptC) {
234331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // -c was specified. Replace the extension to .o.
235331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::replace_extension(output_path, "o");
236331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  } else {
237331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // Use a.out under current working directory when compile executable or
238331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // shared library.
239331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::remove_filename(output_path);
240331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::append(output_path, "a.out");
241331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
242331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
243331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return output_path.c_str();
244331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
245331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
246331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesint main(int argc, char **argv) {
247331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
248331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::ParseCommandLineOptions(argc, argv);
249331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  init::Initialize();
250331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
251331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptRuntimePath.empty()) {
252331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    fprintf(stderr, "You must set \"-rt-path </path/to/libclcore.bc>\" with "
253331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                    "this tool\n");
254331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
255331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
256331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
257331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  BCCContext context;
258331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  RSCompilerDriver rscd;
259331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler compiler;
260331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
261331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!ConfigCompiler(rscd)) {
262331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
263331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
264331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
265331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
266331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OutputFilename.empty()) {
267331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
268331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
269331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
270331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  RSScript *s = NULL;
271331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  s = PrepareRSScript(context, OptInputFilenames);
272331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  rscd.build(*s, OutputFilename.c_str(), OptRuntimePath.c_str());
273331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
274331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return EXIT_SUCCESS;
275331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
276