[lld-macho] Add .tbd support for frameworks

Required for e.g. linking iOS apps since they don't have a platform-native
SDK

Reviewed By: #lld-macho, compnerd, smeenai

Differential Revision: https://reviews.llvm.org/D85153
This commit is contained in:
Jez Ng 2020-08-07 11:04:54 -07:00
parent ca85e37338
commit 25367dfefb
3 changed files with 52 additions and 22 deletions

View File

@ -83,45 +83,51 @@ void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
lld::outs() << "\n";
}
static Optional<std::string> findLibrary(StringRef name) {
std::string stub = (llvm::Twine("lib") + name + ".tbd").str();
std::string shared = (llvm::Twine("lib") + name + ".dylib").str();
std::string archive = (llvm::Twine("lib") + name + ".a").str();
llvm::SmallString<260> location;
static Optional<std::string> findWithExtension(StringRef base,
ArrayRef<StringRef> extensions) {
for (StringRef ext : extensions) {
Twine location = base + ext;
if (fs::exists(location))
return location.str();
}
return {};
}
static Optional<std::string> findLibrary(StringRef name) {
llvm::SmallString<261> location;
for (StringRef dir : config->librarySearchPaths) {
for (StringRef library : {stub, shared, archive}) {
location = dir;
llvm::sys::path::append(location, library);
if (fs::exists(location))
return location.str().str();
}
path::append(location, Twine("lib") + name);
if (Optional<std::string> path =
findWithExtension(location, {".tbd", ".dylib", ".a"}))
return path;
}
return {};
}
static Optional<std::string> findFramework(StringRef name) {
// TODO: support .tbd files
llvm::SmallString<260> symlink;
llvm::SmallString<260> location;
StringRef suffix;
std::tie(name, suffix) = name.split(",");
for (StringRef dir : config->frameworkSearchPaths) {
symlink = dir;
path::append(symlink, name + ".framework", name);
// If the symlink fails to resolve, skip to the next search path.
// NOTE: we must resolve the symlink before trying the suffixes, because
// there are no symlinks for the suffixed paths.
if (fs::real_path(symlink, location))
continue;
if (!suffix.empty()) {
llvm::Twine suffixed = location + suffix;
if (fs::exists(suffixed))
return suffixed.str();
// NOTE: we must resolve the symlink before trying the suffixes, because
// there are no symlinks for the suffixed paths.
llvm::SmallString<260> location;
if (!fs::real_path(symlink, location)) {
// only append suffix if realpath() succeeds
Twine suffixed = location + suffix;
if (fs::exists(suffixed))
return suffixed.str();
}
// Suffix lookup failed, fall through to the no-suffix case.
}
if (fs::exists(location))
return location.str().str();
if (Optional<std::string> path = findWithExtension(symlink, {".tbd", ""}))
return path;
}
return {};
}

View File

@ -0,0 +1,10 @@
--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000000' ]
platform: macosx
install-name: '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation'
current-version: 0001.001.1
compatibility-version: 150
exports:
- archs: [ 'x86_64' ]
symbols: [ '__CFBigNumGetInt128' ]

View File

@ -0,0 +1,14 @@
# REQUIRES: x86
# RUN: mkdir -p %t
# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
# RUN: lld -flavor darwinnew -o %t/test -Z -F%S/Inputs/MacOSX.sdk/System/Library/Frameworks -framework CoreFoundation %t/test.o
#
# RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck %s
# CHECK: /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
.section __TEXT,__text
.global _main
_main:
movq __CFBigNumGetInt128@GOTPCREL(%rip), %rax
ret