llvm-link.cpp revision 164cb69e045f91900410781605cff7e5594460f2
1075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner//===----------------------------------------------------------------------===//
2075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner// LLVM 'LINK' UTILITY
3075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner//
4075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner// This utility may be invoked in the following manner:
5075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner//  link a.bc b.bc c.bc -o x.bc
6075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner//
7075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner//===----------------------------------------------------------------------===//
8075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
9075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Transforms/Linker.h"
10075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Bytecode/Reader.h"
11075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Bytecode/Writer.h"
12164cb69e045f91900410781605cff7e5594460f2Chris Lattner#include "llvm/Assembly/Writer.h"
13075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Support/CommandLine.h"
14075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Module.h"
15075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include "llvm/Method.h"
16075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include <fstream.h>
17075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner#include <memory>
18075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
19075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
20075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattnercl::StringList InputFilenames("", "Load <arg> files, linking them together",
21075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner			      cl::OneOrMore);
22075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattnercl::String OutputFilename("o", "Override output filename", cl::NoFlags, "-");
23075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattnercl::Flag   Force         ("f", "Overwrite output files", cl::NoFlags, false);
24164cb69e045f91900410781605cff7e5594460f2Chris Lattnercl::Flag   DumpAsm       ("d", "Print assembly as linked", cl::Hidden, false);
25075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
26075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
27075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattnerint main(int argc, char **argv) {
28075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
29075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  assert(InputFilenames.size() > 0 && "OneOrMore is not working");
30075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
31075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  std::auto_ptr<Module> Composite(ParseBytecodeFile(InputFilenames[0]));
32075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  if (Composite.get() == 0) {
33075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    cerr << "Error opening bytecode file: '" << InputFilenames[0] << "'\n";
34075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    return 1;
35075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  }
36075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
37075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  for (unsigned i = 1; i < InputFilenames.size(); ++i) {
38075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    auto_ptr<Module> M(ParseBytecodeFile(InputFilenames[i]));
39075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    if (M.get() == 0) {
40075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      cerr << "Error opening bytecode file: '" << InputFilenames[i] << "'\n";
41075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      return 1;
42075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    }
43075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
44075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    string ErrorMessage;
45075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    if (LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
46075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      cerr << "Error linking in '" << InputFilenames[i] << "': "
47075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner	   << ErrorMessage << endl;
48075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      return 1;
49075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    }
50075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  }
51075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
52164cb69e045f91900410781605cff7e5594460f2Chris Lattner  if (DumpAsm)
53164cb69e045f91900410781605cff7e5594460f2Chris Lattner    cerr << "Here's the assembly:\n" << Composite.get();
54164cb69e045f91900410781605cff7e5594460f2Chris Lattner
55075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  ostream *Out = &cout;  // Default to printing to stdout...
56075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  if (OutputFilename != "-") {
57075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    Out = new ofstream(OutputFilename.c_str(),
58075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner		       (Force ? 0 : ios::noreplace)|ios::out);
59075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    if (!Out->good()) {
60075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      cerr << "Error opening '" << OutputFilename << "'!\n";
61075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner      return 1;
62075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner    }
63075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  }
64075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
65075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  WriteBytecodeToFile(Composite.get(), *Out);
66075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner
67075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  if (Out != &cout) delete Out;
68075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner  return 0;
69075a0b771e1d76ce64f4628b7a680ef6a0486a4bChris Lattner}
70