|
23 | 23 | #include "llvm/Option/ArgList.h"
|
24 | 24 | #include "llvm/Option/Option.h"
|
25 | 25 | #include "llvm/Support/CommandLine.h"
|
| 26 | +#include "llvm/Support/FileSystem.h" |
26 | 27 | #include "llvm/Support/Path.h"
|
27 | 28 | #include "llvm/TextAPI/MachO/InterfaceFile.h"
|
28 | 29 | #include "llvm/TextAPI/MachO/TextAPIReader.h"
|
@@ -164,12 +165,15 @@ Optional<std::string> macho::resolveDylibPath(StringRef path) {
|
164 | 165 | // they are consistent.
|
165 | 166 | if (fs::exists(path))
|
166 | 167 | return std::string(path);
|
| 168 | + else |
| 169 | + depTracker->logFileNotFound(path); |
167 | 170 |
|
168 | 171 | SmallString<261> location = path;
|
169 | 172 | path::replace_extension(location, ".tbd");
|
170 | 173 | if (fs::exists(location))
|
171 | 174 | return std::string(location);
|
172 |
| - |
| 175 | + else |
| 176 | + depTracker->logFileNotFound(location); |
173 | 177 | return {};
|
174 | 178 | }
|
175 | 179 |
|
@@ -240,3 +244,49 @@ void macho::printArchiveMemberLoad(StringRef reason, const InputFile *f) {
|
240 | 244 | if (config->printWhyLoad)
|
241 | 245 | message(reason + " forced load of " + toString(f));
|
242 | 246 | }
|
| 247 | + |
| 248 | +macho::DependencyTracker::DependencyTracker(StringRef path) |
| 249 | + : path(path), active(!path.empty()) { |
| 250 | + if (active && fs::exists(path) && !fs::can_write(path)) { |
| 251 | + warn("Ignoring dependency_info option since specified path is not " |
| 252 | + "writeable."); |
| 253 | + active = false; |
| 254 | + } |
| 255 | +} |
| 256 | + |
| 257 | +void macho::DependencyTracker::write(llvm::StringRef version, |
| 258 | + const llvm::SetVector<InputFile *> &inputs, |
| 259 | + llvm::StringRef output) { |
| 260 | + if (!active) |
| 261 | + return; |
| 262 | + |
| 263 | + std::error_code ec; |
| 264 | + llvm::raw_fd_ostream os(path, ec, llvm::sys::fs::OF_None); |
| 265 | + if (ec) { |
| 266 | + warn("Error writing dependency info to file"); |
| 267 | + return; |
| 268 | + } |
| 269 | + |
| 270 | + auto addDep = [&os](DepOpCode opcode, const StringRef &path) { |
| 271 | + os << opcode; |
| 272 | + os << path; |
| 273 | + os << '\0'; |
| 274 | + }; |
| 275 | + |
| 276 | + addDep(DepOpCode::Version, version); |
| 277 | + |
| 278 | + // Sort the input by its names. |
| 279 | + std::vector<StringRef> inputNames; |
| 280 | + inputNames.reserve(inputs.size()); |
| 281 | + for (InputFile *f : inputs) |
| 282 | + inputNames.push_back(f->getName()); |
| 283 | + llvm::sort(inputNames, |
| 284 | + [](const StringRef &a, const StringRef &b) { return a < b; }); |
| 285 | + for (const StringRef &in : inputNames) |
| 286 | + addDep(DepOpCode::Input, in); |
| 287 | + |
| 288 | + for (const std::string &f : notFounds) |
| 289 | + addDep(DepOpCode::NotFound, f); |
| 290 | + |
| 291 | + addDep(DepOpCode::Output, output); |
| 292 | +} |
0 commit comments