summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/macdeployqt/shared/shared.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/tools/macdeployqt/shared/shared.cpp b/src/tools/macdeployqt/shared/shared.cpp
index 0731fb616ed..7f8590ae894 100644
--- a/src/tools/macdeployqt/shared/shared.cpp
+++ b/src/tools/macdeployqt/shared/shared.cpp
@@ -1008,6 +1008,31 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
rpathsUsed.append(framework.rpathUsed);
}
+ // To properly find all dependencies of the current framework / library further down in
+ // getQtFrameworks, we need to get its rpaths, resolve them in the context of its original
+ // location before it is copied, and add them as candidate rpaths.
+ //
+ // This is necessary to handle cases like
+ // (1) QtNetwork.framework -> (2) libbrotlidec.dylib -> (3) libbrotlicommon.1.dylib
+ // to correctly resolve the path to (3) when it is referenced as
+ // '@rpath/libbrotlicommon.1.dylib' and (2) has an LC_RPATH of '@loader_path/../lib', and
+ // no other absolute rpaths. So the '@loader_path/../lib' will be resolved relative
+ // to (2)'s original location and its LC_RPATH.
+ //
+ // Otherwise we'd only have the Qt prefix and the current bundle app dir as rpath
+ // candidates, and once (2) is copied into the app bundle, there's no way
+ // '@rpath/libbrotlicommon.1.dylib' could resolve to the real path on disk from the two
+ // candidates above.
+ if (!framework.sourceFilePath.isEmpty()) {
+ const QList<QString> sourceRPaths = getBinaryRPaths(framework.sourceFilePath, true);
+ for (const QString &sourceRPath : sourceRPaths) {
+ const QDir sourceRPathDir(sourceRPath);
+ if (sourceRPathDir.exists() && !rpathsUsed.contains(sourceRPath)) {
+ rpathsUsed.append(sourceRPath);
+ }
+ }
+ }
+
// Copy the framework/dylib to the app bundle.
const QString deployedBinaryPath = framework.isDylib ? copyDylib(framework, bundlePath)
: copyFramework(framework, bundlePath);
@@ -1032,7 +1057,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
for (const FrameworkInfo &dependency : dependencies) {
if (dependency.rpathUsed.isEmpty()) {
changeInstallName(bundlePath, dependency, QStringList() << deployedBinaryPath, useLoaderPath);
- } else {
+ } else if (!rpathsUsed.contains(dependency.rpathUsed)) {
rpathsUsed.append(dependency.rpathUsed);
}