0ae39228d9cbbe060b849449e678c3cbf699c7a6
[oota-llvm.git] / tools / llvm-link / llvm-link.cpp
1 //===----------------------------------------------------------------------===//
2 // LLVM 'LINK' UTILITY 
3 //
4 // This utility may be invoked in the following manner:
5 //  link a.bc b.bc c.bc -o x.bc
6 //
7 // Alternatively, this can be used as an 'ar' tool as well.  If invoked as
8 // either 'ar' or 'llvm-ar', it accepts a 'cr' parameter as well.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #include "llvm/Transforms/Linker.h"
13 #include "llvm/Bytecode/Reader.h"
14 #include "llvm/Bytecode/Writer.h"
15 #include "llvm/Assembly/Writer.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Module.h"
18 #include "llvm/Method.h"
19 #include <fstream.h>
20 #include <memory>
21
22
23 cl::StringList InputFilenames("", "Load <arg> files, linking them together", 
24                               cl::OneOrMore);
25 cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "-");
26 cl::Flag   Force         ("f", "Overwrite output files", cl::NoFlags, false);
27 cl::Flag   Verbose       ("v", "Print information about actions taken");
28 cl::Flag   DumpAsm       ("d", "Print assembly as linked", cl::Hidden, false);
29
30
31 int main(int argc, char **argv) {
32   cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
33   assert(InputFilenames.size() > 0 && "OneOrMore is not working");
34
35   // TODO: TEST argv[0]
36   string ErrorMessage;
37     
38   if (Verbose) cerr << "Loading '" << InputFilenames[0] << "'\n";
39   std::auto_ptr<Module> Composite(ParseBytecodeFile(InputFilenames[0],
40                                                     &ErrorMessage));
41   if (Composite.get() == 0) {
42     cerr << "Error opening bytecode file: '" << InputFilenames[0] << "'";
43     if (ErrorMessage.size()) cerr << ": " << ErrorMessage;
44     cerr << endl;
45     return 1;
46   }
47
48   for (unsigned i = 1; i < InputFilenames.size(); ++i) {
49   if (Verbose) cerr << "Loading '" << InputFilenames[i] << "'\n";
50     auto_ptr<Module> M(ParseBytecodeFile(InputFilenames[i], &ErrorMessage));
51     if (M.get() == 0) {
52       cerr << "Error opening bytecode file: '" << InputFilenames[i] << "'";
53       if (ErrorMessage.size()) cerr << ": " << ErrorMessage;
54       cerr << endl;
55       return 1;
56     }
57
58     if (Verbose) cerr << "Linking in '" << InputFilenames[i] << "'\n";
59
60     if (LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
61       cerr << "Error linking in '" << InputFilenames[i] << "': "
62            << ErrorMessage << endl;
63       return 1;
64     }
65   }
66
67   if (DumpAsm)
68     cerr << "Here's the assembly:\n" << Composite.get();
69
70   ostream *Out = &cout;  // Default to printing to stdout...
71   if (OutputFilename != "-") {
72     Out = new ofstream(OutputFilename.c_str(), 
73                        (Force ? 0 : ios::noreplace)|ios::out);
74     if (!Out->good()) {
75       cerr << "Error opening '" << OutputFilename << "'!\n";
76       return 1;
77     }
78   }
79
80   if (Verbose) cerr << "Writing bytecode...\n";
81   WriteBytecodeToFile(Composite.get(), *Out);
82
83   if (Out != &cout) delete Out;
84   return 0;
85 }