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