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