Main.cpp revision 47f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9
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
179e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  // Explicitly set ARM feature vector
180e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  if (config->getTriple().find("arm") != std::string::npos) {
181e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    std::vector<std::string> fv;
182e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("+vfp3");
183e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("+d16");
184e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("-neon");
185e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    fv.push_back("-neonfp");
186e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines    config->setFeatureString(fv);
187e87e66154f37858f244f0bb4146c67984bb33b6bStephen Hines  }
188221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  // Compatibility mode on x86 requires atom code generation.
189221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  if (config->getTriple().find("i686") != std::string::npos) {
190221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines    config->setCPU("atom");
191221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines  }
192221efde4ece61fd4f1106fc80314395ef99457d8Stephen Hines
193331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // Setup the config according to the value of command line option.
194331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptPIC) {
195331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    config->setRelocationModel(llvm::Reloc::PIC_);
196331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
197331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  switch (OptOptLevel) {
198331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '0': config->setOptimizationLevel(llvm::CodeGenOpt::None); break;
199331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '1': config->setOptimizationLevel(llvm::CodeGenOpt::Less); break;
200331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '3': config->setOptimizationLevel(llvm::CodeGenOpt::Aggressive); break;
201331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    case '2':
202331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    default: {
203331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      config->setOptimizationLevel(llvm::CodeGenOpt::Default);
204331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines      break;
205331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    }
206331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
207331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
208331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  pCompilerDriver.setConfig(config);
209331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler::ErrorCode result = compiler->config(*config);
210331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
211331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (result != Compiler::kSuccess) {
212331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to configure the compiler! (detail: "
213331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << Compiler::GetErrorString(result) << ")\n";
214331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return false;
215331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
216331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
217331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return true;
218331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
219331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
220331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#define DEFAULT_OUTPUT_PATH   "/sdcard/a.out"
221331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstatic inline
222331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesstd::string DetermineOutputFilename(const std::string &pOutputPath) {
223331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!pOutputPath.empty()) {
224331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return pOutputPath;
225331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
226331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
227331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // User doesn't specify the value to -o.
228331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptInputFilenames.size() > 1) {
229331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n";
230331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return DEFAULT_OUTPUT_PATH;
231331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
232331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
233331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  // There's only one input bitcode file.
234331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  const std::string &input_path = OptInputFilenames[0];
235331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::SmallString<200> output_path(input_path);
236331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
237331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::error_code err = llvm::sys::fs::make_absolute(output_path);
238331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (err != llvm::errc::success) {
239331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::errs() << "Failed to determine the absolute path of `" << input_path
240331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                 << "'! (detail: " << err.message() << ")\n";
241331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return "";
242331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
243331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
244331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptC) {
245331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // -c was specified. Replace the extension to .o.
246331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::replace_extension(output_path, "o");
247331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  } else {
248331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // Use a.out under current working directory when compile executable or
249331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    // shared library.
250331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::remove_filename(output_path);
251331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    llvm::sys::path::append(output_path, "a.out");
252331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
253331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
254331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return output_path.c_str();
255331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
256331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
257331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hinesint main(int argc, char **argv) {
258331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::SetVersionPrinter(BCCVersionPrinter);
259331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  llvm::cl::ParseCommandLineOptions(argc, argv);
260331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  init::Initialize();
261331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
262331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OptRuntimePath.empty()) {
263331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    fprintf(stderr, "You must set \"-rt-path </path/to/libclcore.bc>\" with "
264331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines                    "this tool\n");
265331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
266331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
267331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
268331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  BCCContext context;
2693ab9da1e1b3d7794994393af086d096397fb84dbStephen Hines  RSCompilerDriver rscd(false);
270331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  Compiler compiler;
271331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
272331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!ConfigCompiler(rscd)) {
273331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
274331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
275331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
276331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  std::string OutputFilename = DetermineOutputFilename(OptOutputFilename);
277331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (OutputFilename.empty()) {
278331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines    return EXIT_FAILURE;
279331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
280331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
281331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  RSScript *s = NULL;
282331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  s = PrepareRSScript(context, OptInputFilenames);
28347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  if (!rscd.build(*s, OutputFilename.c_str(), OptRuntimePath.c_str())) {
28447f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    fprintf(stderr, "Failed to compile script!");
28547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return EXIT_FAILURE;
28647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  }
287331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
288331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  return EXIT_SUCCESS;
289331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
290