Revert "[dsymutil] Emit real dSYM companion binaries."
[oota-llvm.git] / tools / dsymutil / MachOUtils.cpp
1 //===-- MachOUtils.h - Mach-o specific helpers for dsymutil  --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MachOUtils.h"
11 #include "dsymutil.h"
12 #include "llvm/Support/FileUtilities.h"
13 #include "llvm/Support/Program.h"
14 #include "llvm/Support/raw_ostream.h"
15
16 namespace llvm {
17 namespace dsymutil {
18 namespace MachOUtils {
19
20 std::string getArchName(StringRef Arch) {
21   if (Arch.startswith("thumb"))
22     return (llvm::Twine("arm") + Arch.drop_front(5)).str();
23   return Arch;
24 }
25
26 static bool runLipo(SmallVectorImpl<const char *> &Args) {
27   auto Path = sys::findProgramByName("lipo");
28
29   if (!Path) {
30     errs() << "error: lipo: " << Path.getError().message() << "\n";
31     return false;
32   }
33
34   std::string ErrMsg;
35   int result =
36       sys::ExecuteAndWait(*Path, Args.data(), nullptr, nullptr, 0, 0, &ErrMsg);
37   if (result) {
38     errs() << "error: lipo: " << ErrMsg << "\n";
39     return false;
40   }
41
42   return true;
43 }
44
45 bool generateUniversalBinary(SmallVectorImpl<ArchAndFilename> &ArchFiles,
46                              StringRef OutputFileName,
47                              const LinkOptions &Options) {
48   // No need to merge one file into a universal fat binary. First, try
49   // to move it (rename) to the final location. If that fails because
50   // of cross-device link issues then copy and delete.
51   if (ArchFiles.size() == 1) {
52     StringRef From(ArchFiles.front().Path);
53     if (sys::fs::rename(From, OutputFileName)) {
54       if (std::error_code EC = sys::fs::copy_file(From, OutputFileName)) {
55         errs() << "error: while copying " << From << " to " << OutputFileName
56                << ": " << EC.message() << "\n";
57         return false;
58       }
59       sys::fs::remove(From);
60     }
61     return true;
62   }
63
64   SmallVector<const char *, 8> Args;
65   Args.push_back("lipo");
66   Args.push_back("-create");
67
68   for (auto &Thin : ArchFiles)
69     Args.push_back(Thin.Path.c_str());
70
71   // Align segments to match dsymutil-classic alignment
72   for (auto &Thin : ArchFiles) {
73     Thin.Arch = getArchName(Thin.Arch);
74     Args.push_back("-segalign");
75     Args.push_back(Thin.Arch.c_str());
76     Args.push_back("20");
77   }
78
79   Args.push_back("-output");
80   Args.push_back(OutputFileName.data());
81   Args.push_back(nullptr);
82
83   if (Options.Verbose) {
84     outs() << "Running lipo\n";
85     for (auto Arg : Args)
86       outs() << ' ' << ((Arg == nullptr) ? "\n" : Arg);
87   }
88
89   return Options.NoOutput ? true : runLipo(Args);
90 }
91 }
92 }
93 }