1193323Sed//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This utility may be invoked in the following manner:
11193323Sed//  llvm-link a.bc b.bc c.bc -o x.bc
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#include "llvm/Linker.h"
16193323Sed#include "llvm/Analysis/Verifier.h"
17193323Sed#include "llvm/Bitcode/ReaderWriter.h"
18249423Sdim#include "llvm/IR/LLVMContext.h"
19249423Sdim#include "llvm/IR/Module.h"
20249423Sdim#include "llvm/IRReader/IRReader.h"
21193323Sed#include "llvm/Support/CommandLine.h"
22193323Sed#include "llvm/Support/ManagedStatic.h"
23249423Sdim#include "llvm/Support/Path.h"
24193323Sed#include "llvm/Support/PrettyStackTrace.h"
25249423Sdim#include "llvm/Support/Signals.h"
26249423Sdim#include "llvm/Support/SourceMgr.h"
27249423Sdim#include "llvm/Support/SystemUtils.h"
28218885Sdim#include "llvm/Support/ToolOutputFile.h"
29193323Sed#include <memory>
30193323Sedusing namespace llvm;
31193323Sed
32193323Sedstatic cl::list<std::string>
33193323SedInputFilenames(cl::Positional, cl::OneOrMore,
34193323Sed               cl::desc("<input bitcode files>"));
35193323Sed
36193323Sedstatic cl::opt<std::string>
37193323SedOutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
38193323Sed               cl::value_desc("filename"));
39193323Sed
40198090Srdivackystatic cl::opt<bool>
41198090SrdivackyForce("f", cl::desc("Enable binary output on terminals"));
42193323Sed
43193323Sedstatic cl::opt<bool>
44198090SrdivackyOutputAssembly("S",
45198090Srdivacky         cl::desc("Write output as LLVM assembly"), cl::Hidden);
46198090Srdivacky
47198090Srdivackystatic cl::opt<bool>
48193323SedVerbose("v", cl::desc("Print information about actions taken"));
49193323Sed
50193323Sedstatic cl::opt<bool>
51193323SedDumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);
52193323Sed
53193323Sed// LoadFile - Read the specified bitcode file in and return it.  This routine
54193323Sed// searches the link path for the specified file to try to find it...
55193323Sed//
56251662Sdimstatic inline Module *LoadFile(const char *argv0, const std::string &FN,
57251662Sdim                               LLVMContext& Context) {
58198090Srdivacky  SMDiagnostic Err;
59263508Sdim  if (Verbose) errs() << "Loading '" << FN << "'\n";
60210006Srdivacky  Module* Result = 0;
61263508Sdim
62263508Sdim  Result = ParseIRFile(FN, Err, Context);
63251662Sdim  if (Result) return Result;   // Load successful!
64193323Sed
65234353Sdim  Err.print(argv0, errs());
66251662Sdim  return NULL;
67193323Sed}
68193323Sed
69193323Sedint main(int argc, char **argv) {
70193323Sed  // Print a stack trace if we signal out.
71193323Sed  sys::PrintStackTraceOnErrorSignal();
72193323Sed  PrettyStackTraceProgram X(argc, argv);
73263508Sdim
74198090Srdivacky  LLVMContext &Context = getGlobalContext();
75193323Sed  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
76193323Sed  cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
77193323Sed
78193323Sed  unsigned BaseArg = 0;
79193323Sed  std::string ErrorMessage;
80193323Sed
81251662Sdim  OwningPtr<Module> Composite(LoadFile(argv[0],
82251662Sdim                                       InputFilenames[BaseArg], Context));
83193323Sed  if (Composite.get() == 0) {
84198090Srdivacky    errs() << argv[0] << ": error loading file '"
85198090Srdivacky           << InputFilenames[BaseArg] << "'\n";
86193323Sed    return 1;
87193323Sed  }
88193323Sed
89251662Sdim  Linker L(Composite.get());
90193323Sed  for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
91251662Sdim    OwningPtr<Module> M(LoadFile(argv[0], InputFilenames[i], Context));
92193323Sed    if (M.get() == 0) {
93198090Srdivacky      errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
94193323Sed      return 1;
95193323Sed    }
96193323Sed
97198090Srdivacky    if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";
98193323Sed
99251662Sdim    if (L.linkInModule(M.get(), &ErrorMessage)) {
100198090Srdivacky      errs() << argv[0] << ": link error in '" << InputFilenames[i]
101198090Srdivacky             << "': " << ErrorMessage << "\n";
102193323Sed      return 1;
103193323Sed    }
104193323Sed  }
105193323Sed
106198090Srdivacky  if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
107193323Sed
108198090Srdivacky  std::string ErrorInfo;
109263508Sdim  tool_output_file Out(OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary);
110198090Srdivacky  if (!ErrorInfo.empty()) {
111198090Srdivacky    errs() << ErrorInfo << '\n';
112198090Srdivacky    return 1;
113198090Srdivacky  }
114193323Sed
115198090Srdivacky  if (verifyModule(*Composite)) {
116198090Srdivacky    errs() << argv[0] << ": linked module is broken!\n";
117193323Sed    return 1;
118193323Sed  }
119193323Sed
120198090Srdivacky  if (Verbose) errs() << "Writing bitcode...\n";
121198090Srdivacky  if (OutputAssembly) {
122212793Sdim    Out.os() << *Composite;
123212793Sdim  } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
124212793Sdim    WriteBitcodeToFile(Composite.get(), Out.os());
125193323Sed
126212793Sdim  // Declare success.
127212793Sdim  Out.keep();
128212793Sdim
129193323Sed  return 0;
130193323Sed}
131