3400df8dc1dfe1a12f23971b467cf69b28ce103d
[oota-llvm.git] / tools / llvm-link / llvm-link.cpp
1 //===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
2 //
3 // This utility may be invoked in the following manner:
4 //  llvm-link a.bc b.bc c.bc -o x.bc
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Module.h"
9 #include "llvm/Analysis/Verifier.h"
10 #include "llvm/Bytecode/Reader.h"
11 #include "llvm/Bytecode/Writer.h"
12 #include "llvm/Transforms/Utils/Linker.h"
13 #include "Support/CommandLine.h"
14 #include "Support/Signals.h"
15 #include <fstream>
16 #include <memory>
17 #include <sys/types.h>     // For FileExists
18 #include <sys/stat.h>
19
20 static cl::list<std::string>
21 InputFilenames(cl::Positional, cl::OneOrMore,
22                cl::desc("<input bytecode files>"));
23
24 static cl::opt<std::string>
25 OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
26                cl::value_desc("filename"));
27
28 static cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
29
30 static cl::opt<bool>
31 Verbose("v", cl::desc("Print information about actions taken"));
32
33 static cl::opt<bool>
34 DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);
35
36 static cl::list<std::string>
37 LibPaths("L", cl::desc("Specify a library search path"), cl::ZeroOrMore,
38          cl::value_desc("directory"), cl::Prefix);
39
40 // FileExists - Return true if the specified string is an openable file...
41 static inline bool FileExists(const std::string &FN) {
42   struct stat StatBuf;
43   return stat(FN.c_str(), &StatBuf) != -1;
44 }
45
46 // LoadFile - Read the specified bytecode file in and return it.  This routine
47 // searches the link path for the specified file to try to find it...
48 //
49 static inline std::auto_ptr<Module> LoadFile(const std::string &FN) {
50   std::string Filename = FN;
51   std::string ErrorMessage;
52
53   unsigned NextLibPathIdx = 0;
54   bool FoundAFile = false;
55
56   while (1) {
57     if (Verbose) std::cerr << "Loading '" << Filename << "'\n";
58     if (FileExists(Filename)) FoundAFile = true;
59     Module *Result = ParseBytecodeFile(Filename, &ErrorMessage);
60     if (Result) return std::auto_ptr<Module>(Result);   // Load successful!
61
62     if (Verbose) {
63       std::cerr << "Error opening bytecode file: '" << Filename << "'";
64       if (ErrorMessage.size()) std::cerr << ": " << ErrorMessage;
65       std::cerr << "\n";
66     }
67     
68     if (NextLibPathIdx == LibPaths.size()) break;
69     Filename = LibPaths[NextLibPathIdx++] + "/" + FN;
70   }
71
72   if (FoundAFile)
73     std::cerr << "Bytecode file '" << FN << "' corrupt!  "
74               << "Use 'llvm-link -v ...' for more info.\n";
75   else
76     std::cerr << "Could not locate bytecode file: '" << FN << "'\n";
77   return std::auto_ptr<Module>();
78 }
79
80
81
82
83 int main(int argc, char **argv) {
84   cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
85   assert(InputFilenames.size() > 0 && "OneOrMore is not working");
86
87   unsigned BaseArg = 0;
88   std::string ErrorMessage;
89
90   std::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg]));
91   if (Composite.get() == 0) return 1;
92
93   for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
94     std::auto_ptr<Module> M(LoadFile(InputFilenames[i]));
95     if (M.get() == 0) return 1;
96
97     if (Verbose) std::cerr << "Linking in '" << InputFilenames[i] << "'\n";
98
99     if (LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
100       std::cerr << argv[0] << ": error linking in '" << InputFilenames[i]
101                 << "': " << ErrorMessage << "\n";
102       return 1;
103     }
104   }
105
106   if (DumpAsm) std::cerr << "Here's the assembly:\n" << Composite.get();
107
108   std::ostream *Out = &std::cout;  // Default to printing to stdout...
109   if (OutputFilename != "-") {
110     if (!Force && std::ifstream(OutputFilename.c_str())) {
111       // If force is not specified, make sure not to overwrite a file!
112       std::cerr << argv[0] << ": error opening '" << OutputFilename
113                 << "': file exists!\n"
114                 << "Use -f command line argument to force output\n";
115       return 1;
116     }
117     Out = new std::ofstream(OutputFilename.c_str());
118     if (!Out->good()) {
119       std::cerr << argv[0] << ": error opening '" << OutputFilename << "'!\n";
120       return 1;
121     }
122
123     // Make sure that the Out file gets unlinked from the disk if we get a
124     // SIGINT
125     RemoveFileOnSignal(OutputFilename);
126   }
127
128   if (verifyModule(*Composite.get())) {
129     std::cerr << argv[0] << ": linked module is broken!\n";
130     return 1;
131   }
132
133   if (Verbose) std::cerr << "Writing bytecode...\n";
134   WriteBytecodeToFile(Composite.get(), *Out);
135
136   if (Out != &std::cout) delete Out;
137   return 0;
138 }