aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lld/MachO/DriverUtils.cpp')
-rw-r--r--lld/MachO/DriverUtils.cpp61
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);
+}