1 //===-- llvm-tapi-diff.cpp - tbd comparator command-line driver ---*- 2 // C++ 3 //-*-===// 4 // 5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 6 // See https://llvm.org/LICENSE.txt for license information. 7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 8 // 9 //===----------------------------------------------------------------------===// 10 // 11 // This file defines the command-line driver for the llvm-tapi difference 12 // engine. 13 // 14 //===----------------------------------------------------------------------===// 15 #include "DiffEngine.h" 16 #include "llvm/Object/TapiUniversal.h" 17 #include "llvm/Support/CommandLine.h" 18 #include "llvm/Support/Error.h" 19 #include "llvm/Support/InitLLVM.h" 20 #include "llvm/Support/WithColor.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <cstdlib> 23 24 using namespace llvm; 25 using namespace MachO; 26 using namespace object; 27 28 namespace { 29 cl::OptionCategory NMCat("llvm-tapi-diff Options"); 30 cl::opt<std::string> InputFileNameLHS(cl::Positional, cl::desc("<first file>"), 31 cl::cat(NMCat)); 32 cl::opt<std::string> InputFileNameRHS(cl::Positional, cl::desc("<second file>"), 33 cl::cat(NMCat)); 34 35 std::string ToolName; 36 } // anonymous namespace 37 38 ExitOnError ExitOnErr; 39 40 void setErrorBanner(ExitOnError &ExitOnErr, std::string InputFile) { 41 ExitOnErr.setBanner(ToolName + ": error: " + InputFile + ": "); 42 } 43 44 Expected<std::unique_ptr<Binary>> convertFileToBinary(std::string &Filename) { 45 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 46 MemoryBuffer::getFileOrSTDIN(Filename); 47 if (BufferOrErr.getError()) 48 return errorCodeToError(BufferOrErr.getError()); 49 return createBinary(BufferOrErr.get()->getMemBufferRef()); 50 } 51 52 int main(int Argc, char **Argv) { 53 InitLLVM X(Argc, Argv); 54 cl::HideUnrelatedOptions(NMCat); 55 cl::ParseCommandLineOptions( 56 Argc, Argv, 57 "This tool will compare two tbd files and return the " 58 "differences in those files."); 59 if (InputFileNameLHS.empty() || InputFileNameRHS.empty()) { 60 cl::PrintHelpMessage(); 61 return EXIT_FAILURE; 62 } 63 64 ToolName = Argv[0]; 65 66 setErrorBanner(ExitOnErr, InputFileNameLHS); 67 auto BinLHS = ExitOnErr(convertFileToBinary(InputFileNameLHS)); 68 69 TapiUniversal *FileLHS = dyn_cast<TapiUniversal>(BinLHS.get()); 70 if (!FileLHS) { 71 ExitOnErr( 72 createStringError(std::errc::executable_format_error, 73 "Error when parsing file, unsupported file format")); 74 } 75 76 setErrorBanner(ExitOnErr, InputFileNameRHS); 77 auto BinRHS = ExitOnErr(convertFileToBinary(InputFileNameRHS)); 78 79 TapiUniversal *FileRHS = dyn_cast<TapiUniversal>(BinRHS.get()); 80 if (!FileRHS) { 81 ExitOnErr( 82 createStringError(std::errc::executable_format_error, 83 "Error when parsing file, unsupported file format")); 84 } 85 86 raw_ostream &OS = outs(); 87 88 return DiffEngine(FileLHS, FileRHS).compareFiles(OS); 89 } 90