Keith Smiley 10f22335f3
[llvm-libtool-darwin] Add support for -dependency_info
When using llvm-libtool-darwin as a drop in replacement for cctools
libtool, Xcode expects you to create a dependency info file. This file
is a very simple format describing the input files, the output files,
and the version of the tool. This logic is mirrored from that of
ld64.lld, which supports creating this file as well. Ideally we could
extract it, but I don't think we want to throw this into one of the
grab-bag libraries given how small the logic is.

Differential Revision: https://reviews.llvm.org/D134322
2022-10-03 09:53:02 -07:00

86 lines
2.6 KiB
C++

//===-- DependencyInfo.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <set>
class DependencyInfo {
public:
explicit DependencyInfo(std::string DependencyInfoPath)
: DependencyInfoPath(DependencyInfoPath) {}
virtual ~DependencyInfo(){};
virtual void addMissingInput(llvm::StringRef Path) {
NotFounds.insert(Path.str());
}
// Writes the dependencies to specified path. The content is first sorted by
// OpCode and then by the filename (in alphabetical order).
virtual void write(llvm::Twine Version,
const std::vector<std::string> &Inputs,
std::string Output) {
std::error_code EC;
llvm::raw_fd_ostream OS(DependencyInfoPath, EC, llvm::sys::fs::OF_None);
if (EC) {
llvm::WithColor::defaultErrorHandler(llvm::createStringError(
EC,
"failed to write to " + DependencyInfoPath + ": " + EC.message()));
return;
}
auto AddDep = [&OS](DependencyInfoOpcode Opcode,
const llvm::StringRef &Path) {
OS << static_cast<uint8_t>(Opcode);
OS << Path;
OS << '\0';
};
AddDep(DependencyInfoOpcode::Tool, Version.str());
// Sort the input by its names.
std::vector<llvm::StringRef> InputNames;
InputNames.reserve(Inputs.size());
for (const auto &F : Inputs)
InputNames.push_back(F);
llvm::sort(InputNames);
for (const auto &In : InputNames)
AddDep(DependencyInfoOpcode::InputFound, In);
for (const std::string &F : NotFounds)
AddDep(DependencyInfoOpcode::InputMissing, F);
AddDep(DependencyInfoOpcode::Output, Output);
}
private:
enum DependencyInfoOpcode : uint8_t {
Tool = 0x00,
InputFound = 0x10,
InputMissing = 0x11,
Output = 0x40,
};
const std::string DependencyInfoPath;
std::set<std::string> NotFounds;
};
// Subclass to avoid any overhead when not using this feature
class DummyDependencyInfo : public DependencyInfo {
public:
DummyDependencyInfo() : DependencyInfo("") {}
void addMissingInput(llvm::StringRef Path) override {}
void write(llvm::Twine Version, const std::vector<std::string> &Inputs,
std::string Output) override {}
};