macdeployqt: Replace QSet with QList

This commit is contained in:
Jonas Kvinge
2021-10-09 00:19:49 +02:00
parent c9a501ddc8
commit de2b6d1dee
2 changed files with 34 additions and 27 deletions

View File

@@ -39,6 +39,7 @@
#include <QProcess> #include <QProcess>
#include <QDir> #include <QDir>
#include <QSet> #include <QSet>
#include <QList>
#include <QStack> #include <QStack>
#include <QDirIterator> #include <QDirIterator>
#include <QLibraryInfo> #include <QLibraryInfo>
@@ -232,7 +233,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
return info; return info;
} }
FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs)
{ {
FrameworkInfo info; FrameworkInfo info;
QString trimmed = line.trimmed(); QString trimmed = line.trimmed();
@@ -503,7 +504,7 @@ QString findEntitlementsFile(const QString& path)
return QString(); return QString();
} }
QList<FrameworkInfo> getQtFrameworks(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) QList<FrameworkInfo> getQtFrameworks(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs)
{ {
QList<FrameworkInfo> libraries; QList<FrameworkInfo> libraries;
for (const DylibInfo &dylibInfo : dependencies) { for (const DylibInfo &dylibInfo : dependencies) {
@@ -543,9 +544,9 @@ QString resolveDyldPrefix(const QString &path, const QString &loaderPath, const
return path; return path;
} }
QSet<QString> getBinaryRPaths(const QString &path, bool resolve = true, QString executablePath = QString()) QList<QString> getBinaryRPaths(const QString &path, bool resolve = true, QString executablePath = QString())
{ {
QSet<QString> rpaths; QList<QString> rpaths;
QProcess otool; QProcess otool;
otool.start("otool", QStringList() << "-l" << path); otool.start("otool", QStringList() << "-l" << path);
@@ -582,13 +583,15 @@ QSet<QString> getBinaryRPaths(const QString &path, bool resolve = true, QString
return rpaths; return rpaths;
} }
QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs)
{ {
const OtoolInfo info = findDependencyInfo(path); const OtoolInfo info = findDependencyInfo(path);
return getQtFrameworks(info.dependencies, appBundlePath, rpaths + getBinaryRPaths(path), useDebugLibs); QList<QString> allRPaths = rpaths + getBinaryRPaths(path);
allRPaths.removeDuplicates();
return getQtFrameworks(info.dependencies, appBundlePath, allRPaths, useDebugLibs);
} }
QList<FrameworkInfo> getQtFrameworksForPaths(const QStringList &paths, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) QList<FrameworkInfo> getQtFrameworksForPaths(const QStringList &paths, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs)
{ {
QList<FrameworkInfo> result; QList<FrameworkInfo> result;
QSet<QString> existing; QSet<QString> existing;
@@ -612,7 +615,7 @@ QStringList getBinaryDependencies(const QString executablePath,
const auto dependencies = findDependencyInfo(path).dependencies; const auto dependencies = findDependencyInfo(path).dependencies;
bool rpathsLoaded = false; bool rpathsLoaded = false;
QSet<QString> rpaths; QList<QString> rpaths;
// return bundle-local dependencies. (those starting with @executable_path) // return bundle-local dependencies. (those starting with @executable_path)
for (const DylibInfo &info : dependencies) { for (const DylibInfo &info : dependencies) {
@@ -625,9 +628,9 @@ QStringList getBinaryDependencies(const QString executablePath,
if (!rpathsLoaded) { if (!rpathsLoaded) {
rpaths = getBinaryRPaths(path, true, executablePath); rpaths = getBinaryRPaths(path, true, executablePath);
for (const QString &binaryPath : additionalBinariesContainingRpaths) { for (const QString &binaryPath : additionalBinariesContainingRpaths) {
QSet<QString> binaryRpaths = getBinaryRPaths(binaryPath, true); rpaths += getBinaryRPaths(binaryPath, true);
rpaths += binaryRpaths;
} }
rpaths.removeDuplicates();
rpathsLoaded = true; rpathsLoaded = true;
} }
bool resolved = false; bool resolved = false;
@@ -673,7 +676,7 @@ bool recursiveCopy(const QString &sourcePath, const QString &destinationPath)
return true; return true;
} }
void recursiveCopyAndDeploy(const QString &appBundlePath, const QSet<QString> &rpaths, const QString &sourcePath, const QString &destinationPath) void recursiveCopyAndDeploy(const QString &appBundlePath, const QList<QString> &rpaths, const QString &sourcePath, const QString &destinationPath)
{ {
QDir().mkpath(destinationPath); QDir().mkpath(destinationPath);
@@ -870,7 +873,7 @@ void addRPath(const QString &rpath, const QString &binaryPath)
runInstallNameTool(QStringList() << "-add_rpath" << rpath << binaryPath); runInstallNameTool(QStringList() << "-add_rpath" << rpath << binaryPath);
} }
void deployRPaths(const QString &bundlePath, const QSet<QString> &rpaths, const QString &binaryPath, bool useLoaderPath) void deployRPaths(const QString &bundlePath, const QList<QString> &rpaths, const QString &binaryPath, bool useLoaderPath)
{ {
const QString absFrameworksPath = QFileInfo(bundlePath).absoluteFilePath() const QString absFrameworksPath = QFileInfo(bundlePath).absoluteFilePath()
+ QLatin1String("/Contents/Frameworks"); + QLatin1String("/Contents/Frameworks");
@@ -878,7 +881,7 @@ void deployRPaths(const QString &bundlePath, const QSet<QString> &rpaths, const
const QString loaderPathToFrameworks = QLatin1String("@loader_path/") + relativeFrameworkPath; const QString loaderPathToFrameworks = QLatin1String("@loader_path/") + relativeFrameworkPath;
bool rpathToFrameworksFound = false; bool rpathToFrameworksFound = false;
QStringList args; QStringList args;
QSet<QString> binaryRPaths = getBinaryRPaths(binaryPath, false); QList<QString> binaryRPaths = getBinaryRPaths(binaryPath, false);
for (const QString &rpath : std::as_const(binaryRPaths)) { for (const QString &rpath : std::as_const(binaryRPaths)) {
if (rpath == "@executable_path/../Frameworks" || if (rpath == "@executable_path/../Frameworks" ||
rpath == loaderPathToFrameworks) { rpath == loaderPathToFrameworks) {
@@ -905,7 +908,7 @@ void deployRPaths(const QString &bundlePath, const QSet<QString> &rpaths, const
runInstallNameTool(QStringList() << args << binaryPath); runInstallNameTool(QStringList() << args << binaryPath);
} }
void deployRPaths(const QString &bundlePath, const QSet<QString> &rpaths, const QStringList &binaryPaths, bool useLoaderPath) void deployRPaths(const QString &bundlePath, const QList<QString> &rpaths, const QStringList &binaryPaths, bool useLoaderPath)
{ {
for (const QString &binary : binaryPaths) { for (const QString &binary : binaryPaths) {
deployRPaths(bundlePath, rpaths, binary, useLoaderPath); deployRPaths(bundlePath, rpaths, binary, useLoaderPath);
@@ -973,7 +976,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
deploymentInfo.useLoaderPath = useLoaderPath; deploymentInfo.useLoaderPath = useLoaderPath;
deploymentInfo.isFramework = bundlePath.contains(".framework"); deploymentInfo.isFramework = bundlePath.contains(".framework");
deploymentInfo.isDebug = false; deploymentInfo.isDebug = false;
QSet<QString> rpathsUsed; QList<QString> rpathsUsed;
while (frameworks.isEmpty() == false) { while (frameworks.isEmpty() == false) {
const FrameworkInfo framework = frameworks.takeFirst(); const FrameworkInfo framework = frameworks.takeFirst();
@@ -998,8 +1001,9 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
continue; continue;
} }
if (!framework.rpathUsed.isEmpty()) if (!framework.rpathUsed.isEmpty() && !rpathsUsed.contains(framework.rpathUsed)) {
rpathsUsed << framework.rpathUsed; rpathsUsed.append(framework.rpathUsed);
}
// Copy the framework/dylib to the app bundle. // Copy the framework/dylib to the app bundle.
const QString deployedBinaryPath = framework.isDylib ? copyDylib(framework, bundlePath) const QString deployedBinaryPath = framework.isDylib ? copyDylib(framework, bundlePath)
@@ -1026,7 +1030,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
if (dependency.rpathUsed.isEmpty()) { if (dependency.rpathUsed.isEmpty()) {
changeInstallName(bundlePath, dependency, QStringList() << deployedBinaryPath, useLoaderPath); changeInstallName(bundlePath, dependency, QStringList() << deployedBinaryPath, useLoaderPath);
} else { } else {
rpathsUsed << dependency.rpathUsed; rpathsUsed.append(dependency.rpathUsed);
} }
// Deploy framework if necessary. // Deploy framework if necessary.
@@ -1038,6 +1042,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
deploymentInfo.deployedFrameworks = copiedFrameworks; deploymentInfo.deployedFrameworks = copiedFrameworks;
deployRPaths(bundlePath, rpathsUsed, binaryPaths, useLoaderPath); deployRPaths(bundlePath, rpathsUsed, binaryPaths, useLoaderPath);
deploymentInfo.rpathsUsed += rpathsUsed; deploymentInfo.rpathsUsed += rpathsUsed;
deploymentInfo.rpathsUsed.removeDuplicates();
return deploymentInfo; return deploymentInfo;
} }
@@ -1049,12 +1054,14 @@ DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringLis
applicationBundle.libraryPaths = findAppLibraries(appBundlePath); applicationBundle.libraryPaths = findAppLibraries(appBundlePath);
QStringList allBinaryPaths = QStringList() << applicationBundle.binaryPath << applicationBundle.libraryPaths QStringList allBinaryPaths = QStringList() << applicationBundle.binaryPath << applicationBundle.libraryPaths
<< additionalExecutables; << additionalExecutables;
QSet<QString> allLibraryPaths = getBinaryRPaths(applicationBundle.binaryPath, true); QList<QString> allLibraryPaths = getBinaryRPaths(applicationBundle.binaryPath, true);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
allLibraryPaths.insert(QLibraryInfo::path(QLibraryInfo::LibrariesPath)); allLibraryPaths.append(QLibraryInfo::path(QLibraryInfo::LibrariesPath));
#else #else
allLibraryPaths.insert(QLibraryInfo::location(QLibraryInfo::LibrariesPath)); allLibraryPaths.append(QLibraryInfo::location(QLibraryInfo::LibrariesPath));
#endif #endif
allLibraryPaths.removeDuplicates();
QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(allBinaryPaths, appBundlePath, allLibraryPaths, useDebugLibs); QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(allBinaryPaths, appBundlePath, allLibraryPaths, useDebugLibs);
if (frameworks.isEmpty() && !alwaysOwerwriteEnabled) { if (frameworks.isEmpty() && !alwaysOwerwriteEnabled) {
LogWarning(); LogWarning();
@@ -1399,7 +1406,7 @@ void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo,
deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo, useDebugLibs); deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo, useDebugLibs);
} }
void deployQmlImport(const QString &appBundlePath, const QSet<QString> &rpaths, const QString &importSourcePath, const QString &importName) void deployQmlImport(const QString &appBundlePath, const QList<QString> &rpaths, const QString &importSourcePath, const QString &importName)
{ {
QString importDestinationPath = appBundlePath + "/Contents/Resources/qml/" + importName; QString importDestinationPath = appBundlePath + "/Contents/Resources/qml/" + importName;

View File

@@ -62,7 +62,7 @@ public:
bool isDebugLibrary() const bool isDebugLibrary() const
{ {
return binaryName.contains(QLatin1String("_debug")); return binaryName.endsWith(QStringLiteral("_debug"));
} }
}; };
@@ -101,7 +101,7 @@ public:
QString qtPath; QString qtPath;
QString pluginPath; QString pluginPath;
QStringList deployedFrameworks; QStringList deployedFrameworks;
QSet<QString> rpathsUsed; QList<QString> rpathsUsed;
bool useLoaderPath; bool useLoaderPath;
bool isFramework; bool isFramework;
bool isDebug; bool isDebug;
@@ -112,10 +112,10 @@ public:
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info); inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info);
OtoolInfo findDependencyInfo(const QString &binaryPath); OtoolInfo findDependencyInfo(const QString &binaryPath);
FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs); FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs);
QString findAppBinary(const QString &appBundlePath); QString findAppBinary(const QString &appBundlePath);
QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs); QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs);
QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs); QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, const QString &appBundlePath, const QList<QString> &rpaths, bool useDebugLibs);
QString copyFramework(const FrameworkInfo &framework, const QString path); QString copyFramework(const FrameworkInfo &framework, const QString path);
DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs); DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs);
DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs, bool useLoaderPath); DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs, bool useLoaderPath);