Skip to content

Commit e759007

Browse files
committed
[Immediate] Workaround for loading merged frameworks in immediate mode
Some frameworks that previously had a separate swift overlay have been merged in macOS 14. This is causing symbols to not resolve if using the new SDK but running on an older OS in immediate mode. Ideally we would handle this automatically in JITLink as is done by the system linker, but in the meantime add a workaround to load the correct libraries manually. rdar://110371405
1 parent 7092e50 commit e759007

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

lib/Immediate/Immediate.cpp

+46-17
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,50 @@ bool swift::immediate::tryLoadLibraries(ArrayRef<LinkLibrary> LinkLibraries,
191191
[](bool Value) { return Value; });
192192
}
193193

194+
/// Workaround for rdar://94645534.
195+
///
196+
/// The framework layout of some frameworks have changed over time, causing
197+
/// unresolved symbol errors in immediate mode when running on older OS versions
198+
/// with a newer SDK. This workaround scans through the list of dependencies and
199+
/// manually adds the right libraries as necessary.
200+
///
201+
/// FIXME: JITLink should emulate the Darwin linker's handling of ld$previous
202+
/// mappings so this is handled automatically.
203+
static void addMergedLibraries(SmallVectorImpl<LinkLibrary> &AllLinkLibraries,
204+
const llvm::Triple &Target) {
205+
assert(Target.isMacOSX());
206+
207+
struct MergedLibrary {
208+
StringRef OldLibrary;
209+
llvm::VersionTuple MovedIn;
210+
};
211+
212+
using VersionTuple = llvm::VersionTuple;
213+
214+
static const llvm::StringMap<MergedLibrary> MergedLibs = {
215+
// Merged in macOS 14.0
216+
{"AppKit", {"libswiftAppKit.dylib", VersionTuple{14}}},
217+
{"HealthKit", {"libswiftHealthKit.dylib", VersionTuple{14}}},
218+
{"Network", {"libswiftNetwork.dylib", VersionTuple{14}}},
219+
{"Photos", {"libswiftPhotos.dylib", VersionTuple{14}}},
220+
{"PhotosUI", {"libswiftPhotosUI.dylib", VersionTuple{14}}},
221+
{"SoundAnalysis", {"libswiftSoundAnalysis.dylib", VersionTuple{14}}},
222+
{"Virtualization", {"libswiftVirtualization.dylib", VersionTuple{14}}},
223+
// Merged in macOS 13.0
224+
{"Foundation", {"libswiftFoundation.dylib", VersionTuple{13}}},
225+
};
226+
227+
SmallVector<StringRef> NewLibs;
228+
for (auto &Lib : AllLinkLibraries) {
229+
auto I = MergedLibs.find(Lib.getName());
230+
if (I != MergedLibs.end() && Target.getOSVersion() < I->second.MovedIn)
231+
NewLibs.push_back(I->second.OldLibrary);
232+
}
233+
234+
for (StringRef NewLib : NewLibs)
235+
AllLinkLibraries.push_back(LinkLibrary(NewLib, LibraryKind::Library));
236+
}
237+
194238
bool swift::immediate::autolinkImportedModules(ModuleDecl *M,
195239
const IRGenOptions &IRGenOpts) {
196240
// Perform autolinking.
@@ -201,24 +245,9 @@ bool swift::immediate::autolinkImportedModules(ModuleDecl *M,
201245

202246
M->collectLinkLibraries(addLinkLibrary);
203247

204-
// Workaround for rdar://94645534.
205-
//
206-
// The framework layout of Foundation has changed in 13.0, causing unresolved symbol
207-
// errors to libswiftFoundation in immediate mode when running on older OS versions
208-
// with a 13.0 SDK. This workaround scans through the list of dependencies and
209-
// manually adds libswiftFoundation if necessary.
210248
auto &Target = M->getASTContext().LangOpts.Target;
211-
if (Target.isMacOSX() && Target.getOSMajorVersion() < 13) {
212-
bool linksFoundation = std::any_of(AllLinkLibraries.begin(),
213-
AllLinkLibraries.end(), [](auto &Lib) {
214-
return Lib.getName() == "Foundation";
215-
});
216-
217-
if (linksFoundation) {
218-
AllLinkLibraries.push_back(LinkLibrary("libswiftFoundation.dylib",
219-
LibraryKind::Library));
220-
}
221-
}
249+
if (Target.isMacOSX())
250+
addMergedLibraries(AllLinkLibraries, Target);
222251

223252
tryLoadLibraries(AllLinkLibraries, M->getASTContext().SearchPathOpts,
224253
M->getASTContext().Diags);

0 commit comments

Comments
 (0)