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