|
30 | 30 | #include "llvm/Object/Archive.h"
|
31 | 31 | #include "llvm/Option/ArgList.h"
|
32 | 32 | #include "llvm/Option/Option.h"
|
| 33 | +#include "llvm/Support/FileSystem.h" |
33 | 34 | #include "llvm/Support/Host.h"
|
34 | 35 | #include "llvm/Support/MemoryBuffer.h"
|
35 | 36 | #include "llvm/Support/Path.h"
|
@@ -98,6 +99,32 @@ static Optional<std::string> findLibrary(StringRef name) {
|
98 | 99 | return {};
|
99 | 100 | }
|
100 | 101 |
|
| 102 | +static Optional<std::string> findFramework(StringRef name) { |
| 103 | + // TODO: support .tbd files |
| 104 | + llvm::SmallString<260> symlink; |
| 105 | + llvm::SmallString<260> location; |
| 106 | + StringRef suffix; |
| 107 | + std::tie(name, suffix) = name.split(","); |
| 108 | + for (StringRef dir : config->frameworkSearchPaths) { |
| 109 | + symlink = dir; |
| 110 | + path::append(symlink, name + ".framework", name); |
| 111 | + // If the symlink fails to resolve, skip to the next search path. |
| 112 | + // NOTE: we must resolve the symlink before trying the suffixes, because |
| 113 | + // there are no symlinks for the suffixed paths. |
| 114 | + if (fs::real_path(symlink, location)) |
| 115 | + continue; |
| 116 | + if (!suffix.empty()) { |
| 117 | + llvm::Twine suffixed = location + suffix; |
| 118 | + if (fs::exists(suffixed)) |
| 119 | + return suffixed.str(); |
| 120 | + // Suffix lookup failed, fall through to the no-suffix case. |
| 121 | + } |
| 122 | + if (fs::exists(location)) |
| 123 | + return location.str().str(); |
| 124 | + } |
| 125 | + return {}; |
| 126 | +} |
| 127 | + |
101 | 128 | static TargetInfo *createTargetInfo(opt::InputArgList &args) {
|
102 | 129 | StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
|
103 | 130 | config->arch = llvm::MachO::getArchitectureFromName(
|
@@ -393,13 +420,24 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
393 | 420 | error("library not found for -l" + name);
|
394 | 421 | break;
|
395 | 422 | }
|
| 423 | + case OPT_framework: { |
| 424 | + StringRef name = arg->getValue(); |
| 425 | + if (Optional<std::string> path = findFramework(name)) { |
| 426 | + addFile(*path); |
| 427 | + break; |
| 428 | + } |
| 429 | + error("framework not found for -framework " + name); |
| 430 | + break; |
| 431 | + } |
396 | 432 | case OPT_platform_version:
|
397 | 433 | handlePlatformVersion(arg);
|
398 | 434 | break;
|
399 | 435 | case OPT_o:
|
400 | 436 | case OPT_dylib:
|
401 | 437 | case OPT_e:
|
| 438 | + case OPT_F: |
402 | 439 | case OPT_L:
|
| 440 | + case OPT_install_name: |
403 | 441 | case OPT_Z:
|
404 | 442 | case OPT_arch:
|
405 | 443 | // handled elsewhere
|
|
0 commit comments