diff options
Diffstat (limited to 'lld/MachO/DriverUtils.cpp')
-rw-r--r-- | lld/MachO/DriverUtils.cpp | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp index faa9b760d904..064a509f47c8 100644 --- a/lld/MachO/DriverUtils.cpp +++ b/lld/MachO/DriverUtils.cpp @@ -10,6 +10,7 @@ #include "Driver.h" #include "InputFiles.h" #include "ObjC.h" +#include "Target.h" #include "lld/Common/Args.h" #include "lld/Common/ErrorHandler.h" @@ -23,9 +24,10 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" -#include "llvm/TextAPI/MachO/InterfaceFile.h" -#include "llvm/TextAPI/MachO/TextAPIReader.h" +#include "llvm/TextAPI/InterfaceFile.h" +#include "llvm/TextAPI/TextAPIReader.h" using namespace llvm; using namespace llvm::MachO; @@ -164,12 +166,15 @@ Optional<std::string> macho::resolveDylibPath(StringRef path) { // they are consistent. if (fs::exists(path)) return std::string(path); + else + depTracker->logFileNotFound(path); SmallString<261> location = path; path::replace_extension(location, ".tbd"); if (fs::exists(location)) return std::string(location); - + else + depTracker->logFileNotFound(location); return {}; } @@ -240,3 +245,53 @@ void macho::printArchiveMemberLoad(StringRef reason, const InputFile *f) { if (config->printWhyLoad) message(reason + " forced load of " + toString(f)); } + +macho::DependencyTracker::DependencyTracker(StringRef path) + : path(path), active(!path.empty()) { + if (active && fs::exists(path) && !fs::can_write(path)) { + warn("Ignoring dependency_info option since specified path is not " + "writeable."); + active = false; + } +} + +void macho::DependencyTracker::write(llvm::StringRef version, + const llvm::SetVector<InputFile *> &inputs, + llvm::StringRef output) { + if (!active) + return; + + std::error_code ec; + llvm::raw_fd_ostream os(path, ec, llvm::sys::fs::OF_None); + if (ec) { + warn("Error writing dependency info to file"); + return; + } + + auto addDep = [&os](DepOpCode opcode, const StringRef &path) { + // XXX: Even though DepOpCode's underlying type is uint8_t, + // this cast is still needed because Clang older than 10.x has a bug, + // where it doesn't know to cast the enum to its underlying type. + // Hence `<< DepOpCode` is ambiguous to it. + os << static_cast<uint8_t>(opcode); + os << path; + os << '\0'; + }; + + addDep(DepOpCode::Version, version); + + // Sort the input by its names. + std::vector<StringRef> inputNames; + inputNames.reserve(inputs.size()); + for (InputFile *f : inputs) + inputNames.push_back(f->getName()); + llvm::sort(inputNames); + + for (const StringRef &in : inputNames) + addDep(DepOpCode::Input, in); + + for (const std::string &f : notFounds) + addDep(DepOpCode::NotFound, f); + + addDep(DepOpCode::Output, output); +} |