path: root/src/corelib
diff options
authorTor Arne Vestbø <>2020-01-21 14:13:03 +0100
committerTor Arne Vestbø <>2020-01-22 17:58:33 +0100
commitd0e9e5a36e3e49ec9fb0fb3f1639c21e7414c615 (patch)
treefbad01d0d5074ab78d23311a2a191defd0d63254 /src/corelib
parent92918e567ae194f0676adabaee88100e1c9e5d82 (diff)
macOS: Work around CoreFoundation failing to resolve bundle resources
When a framework is loaded from a Samba share CoreFoundation will fail to resolve its Resources directory, and hence its Info.plist, which means we can't look up the bundle by id. Until this has been fixed in CoreFoundation and/or the macOS Samba implementation we work around it by manually looking for QtCore. This fixes our particular use-case of finding QtCore so we can resolve the relocatable prefix, but there's still a potential issue if any other code tries to use CF for bundle lookups. We don't seem to have any of those in Qt itself, but this should be kept in mind if we see similar issues in the future. Change-Id: I8fd471e44f6afe33a7459ce550f0fcec9acfefb4 Reviewed-by: Alexandru Croitor <>
Diffstat (limited to 'src/corelib')
1 files changed, 19 insertions, 2 deletions
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index f0f77fe68e..7d6beaf9c2 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -535,8 +535,25 @@ static QString getRelocatablePrefix()
#if defined(QT_STATIC)
prefixPath = prefixFromAppDirHelper();
#elif defined(Q_OS_DARWIN) && QT_CONFIG(framework)
- CFBundleRef qtCoreBundle = CFBundleGetBundleWithIdentifier(
- CFSTR("org.qt-project.QtCore"));
+ auto qtCoreBundle = CFBundleGetBundleWithIdentifier(CFSTR("org.qt-project.QtCore"));
+ if (!qtCoreBundle) {
+ // When running Qt apps over Samba shares, CoreFoundation will fail to find
+ // the Resources directory inside the bundle, This directory is a symlink,
+ // and CF relies on readdir() and dtent.dt_type to detect symlinks, which
+ // does not work reliably for Samba shares. We work around it by manually
+ // looking for the QtCore bundle.
+ auto allBundles = CFBundleGetAllBundles();
+ auto bundleCount = CFArrayGetCount(allBundles);
+ for (int i = 0; i < bundleCount; ++i) {
+ auto bundle = CFBundleRef(CFArrayGetValueAtIndex(allBundles, i));
+ auto url = QCFType<CFURLRef>(CFBundleCopyBundleURL(bundle));
+ auto path = QCFType<CFStringRef>(CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle));
+ if (CFStringHasSuffix(path, CFSTR("/QtCore.framework"))) {
+ qtCoreBundle = bundle;
+ break;
+ }
+ }
+ }
QCFType<CFURLRef> qtCorePath = CFBundleCopyBundleURL(qtCoreBundle);