summaryrefslogtreecommitdiffstats
path: root/src/tools/macdeployqt/shared/shared.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/macdeployqt/shared/shared.cpp')
-rw-r--r--src/tools/macdeployqt/shared/shared.cpp73
1 files changed, 49 insertions, 24 deletions
diff --git a/src/tools/macdeployqt/shared/shared.cpp b/src/tools/macdeployqt/shared/shared.cpp
index 5abc0281c6..6ff269b36d 100644
--- a/src/tools/macdeployqt/shared/shared.cpp
+++ b/src/tools/macdeployqt/shared/shared.cpp
@@ -152,7 +152,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
LogDebug() << " inspecting" << binaryPath;
QProcess otool;
otool.start("otool", QStringList() << "-L" << binaryPath);
- otool.waitForFinished();
+ otool.waitForFinished(-1);
if (otool.exitStatus() != QProcess::NormalExit || otool.exitCode() != 0) {
LogError() << otool.readAllStandardError();
@@ -161,7 +161,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
static const QRegularExpression regexp(QStringLiteral(
"^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), "
- "current version (\\d+\\.\\d+\\.\\d+)(, weak)?\\)$"));
+ "current version (\\d+\\.\\d+\\.\\d+)(, weak|, reexport)?\\)$"));
QString output = otool.readAllStandardOutput();
QStringList outputLines = output.split("\n", Qt::SkipEmptyParts);
@@ -172,7 +172,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
outputLines.removeFirst(); // remove line containing the binary path
if (binaryPath.contains(".framework/") || binaryPath.endsWith(".dylib")) {
- const auto match = regexp.match(outputLines.first());
+ const auto match = regexp.match(outputLines.constFirst());
if (match.hasMatch()) {
QString installname = match.captured(1);
if (QFileInfo(binaryPath).fileName() == QFileInfo(installname).fileName()) {
@@ -184,7 +184,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
info.installName = binaryPath;
}
} else {
- LogDebug() << "Could not parse otool output line:" << outputLines.first();
+ LogDebug() << "Could not parse otool output line:" << outputLines.constFirst();
outputLines.removeFirst();
}
}
@@ -435,7 +435,7 @@ QStringList findAppLibraries(const QString &appBundlePath)
{
QStringList result;
// dylibs
- QDirIterator iter(appBundlePath, QStringList() << QString::fromLatin1("*.dylib"),
+ QDirIterator iter(appBundlePath, QStringList() << QString::fromLatin1("*.dylib") << QString::fromLatin1("*.so"),
QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories);
while (iter.hasNext()) {
iter.next();
@@ -598,10 +598,14 @@ QStringList getBinaryDependencies(const QString executablePath,
QString binary = QDir::cleanPath(executablePath + trimmedLine.mid(QStringLiteral("@executable_path/").length()));
if (binary != path)
binaries.append(binary);
+ } else if (trimmedLine.startsWith("@loader_path/")) {
+ QString binary = QDir::cleanPath(QFileInfo(path).path() + "/" + trimmedLine.mid(QStringLiteral("@loader_path/").length()));
+ if (binary != path)
+ binaries.append(binary);
} else if (trimmedLine.startsWith("@rpath/")) {
if (!rpathsLoaded) {
rpaths = getBinaryRPaths(path, true, executablePath);
- foreach (const QString &binaryPath, additionalBinariesContainingRpaths)
+ for (const QString &binaryPath : additionalBinariesContainingRpaths)
rpaths += getBinaryRPaths(binaryPath, true);
rpaths.removeDuplicates();
rpathsLoaded = true;
@@ -627,22 +631,27 @@ QStringList getBinaryDependencies(const QString executablePath,
}
// copies everything _inside_ sourcePath to destinationPath
-bool recursiveCopy(const QString &sourcePath, const QString &destinationPath)
+bool recursiveCopy(const QString &sourcePath, const QString &destinationPath,
+ const QRegularExpression &ignoreRegExp = QRegularExpression())
{
- if (!QDir(sourcePath).exists())
+ const QDir sourceDir(sourcePath);
+ if (!sourceDir.exists())
return false;
QDir().mkpath(destinationPath);
LogNormal() << "copy:" << sourcePath << destinationPath;
- QStringList files = QDir(sourcePath).entryList(QStringList() << "*", QDir::Files | QDir::NoDotAndDotDot);
+ const QStringList files = sourceDir.entryList(QStringList() << "*", QDir::Files | QDir::NoDotAndDotDot);
+ const bool hasValidRegExp = ignoreRegExp.isValid() && ignoreRegExp.pattern().length() > 0;
for (const QString &file : files) {
+ if (hasValidRegExp && ignoreRegExp.match(file).hasMatch())
+ continue;
const QString fileSourcePath = sourcePath + "/" + file;
const QString fileDestinationPath = destinationPath + "/" + file;
copyFilePrintStatus(fileSourcePath, fileDestinationPath);
}
- QStringList subdirs = QDir(sourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
+ const QStringList subdirs = sourceDir.entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &dir : subdirs) {
recursiveCopy(sourcePath + "/" + dir, destinationPath + "/" + dir);
}
@@ -656,7 +665,9 @@ void recursiveCopyAndDeploy(const QString &appBundlePath, const QList<QString> &
LogNormal() << "copy:" << sourcePath << destinationPath;
const bool isDwarfPath = sourcePath.endsWith("DWARF");
- QStringList files = QDir(sourcePath).entryList(QStringList() << QStringLiteral("*"), QDir::Files | QDir::NoDotAndDotDot);
+ const QDir sourceDir(sourcePath);
+
+ const QStringList files = sourceDir.entryList(QStringList() << QStringLiteral("*"), QDir::Files | QDir::NoDotAndDotDot);
for (const QString &file : files) {
const QString fileSourcePath = sourcePath + u'/' + file;
@@ -702,7 +713,7 @@ void recursiveCopyAndDeploy(const QString &appBundlePath, const QList<QString> &
}
}
- QStringList subdirs = QDir(sourcePath).entryList(QStringList() << QStringLiteral("*"), QDir::Dirs | QDir::NoDotAndDotDot);
+ const QStringList subdirs = sourceDir.entryList(QStringList() << QStringLiteral("*"), QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &dir : subdirs) {
recursiveCopyAndDeploy(appBundlePath, rpaths, sourcePath + u'/' + dir, destinationPath + u'/' + dir);
}
@@ -768,14 +779,16 @@ QString copyFramework(const FrameworkInfo &framework, const QString path)
// Copy Resources/, Libraries/ and Helpers/
const QString resourcesSourcePath = framework.frameworkPath + "/Resources";
- const QString resourcesDestianationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Resources";
- recursiveCopy(resourcesSourcePath, resourcesDestianationPath);
+ const QString resourcesDestinationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Resources";
+ // Ignore *.prl files that are in the Resources directory
+ recursiveCopy(resourcesSourcePath, resourcesDestinationPath,
+ QRegularExpression("\\A(?:[^/]*\\.prl)\\z"));
const QString librariesSourcePath = framework.frameworkPath + "/Libraries";
- const QString librariesDestianationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Libraries";
- bool createdLibraries = recursiveCopy(librariesSourcePath, librariesDestianationPath);
+ const QString librariesDestinationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Libraries";
+ bool createdLibraries = recursiveCopy(librariesSourcePath, librariesDestinationPath);
const QString helpersSourcePath = framework.frameworkPath + "/Helpers";
- const QString helpersDestianationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Helpers";
- bool createdHelpers = recursiveCopy(helpersSourcePath, helpersDestianationPath);
+ const QString helpersDestinationPath = frameworkDestinationDirectory + "/Versions/" + framework.version + "/Helpers";
+ bool createdHelpers = recursiveCopy(helpersSourcePath, helpersDestinationPath);
// Create symlink structure. Links at the framework root point to Versions/Current/
// which again points to the actual version:
@@ -834,9 +847,15 @@ void changeInstallName(const QString &bundlePath, const FrameworkInfo &framework
changeInstallName(framework.installName, deployedInstallName, binary);
// Workaround for the case when the library ID name is a symlink, while the dependencies
// specified using the canonical path to the library (QTBUG-56814)
- QString canonicalInstallName = QFileInfo(framework.installName).canonicalFilePath();
+ QFileInfo fileInfo= QFileInfo(framework.installName);
+ QString canonicalInstallName = fileInfo.canonicalFilePath();
if (!canonicalInstallName.isEmpty() && canonicalInstallName != framework.installName) {
changeInstallName(canonicalInstallName, deployedInstallName, binary);
+ // some libraries' inner dependencies (such as ffmpeg, nettle) use symbol link (QTBUG-100093)
+ QString innerDependency = fileInfo.canonicalPath() + "/" + fileInfo.fileName();
+ if (innerDependency != canonicalInstallName && innerDependency != framework.installName) {
+ changeInstallName(innerDependency, deployedInstallName, binary);
+ }
}
}
}
@@ -862,7 +881,8 @@ void deployRPaths(const QString &bundlePath, const QList<QString> &rpaths, const
continue;
}
if (rpaths.contains(resolveDyldPrefix(rpath, binaryPath, binaryPath))) {
- args << "-delete_rpath" << rpath;
+ if (!args.contains(rpath))
+ args << "-delete_rpath" << rpath;
}
}
if (!args.length()) {
@@ -924,12 +944,15 @@ bool DeploymentInfo::containsModule(const QString &module, const QString &libInF
if (deployedFrameworks.contains("Qt"_L1 + module + libInFix + ".framework"_L1))
return true;
// Check for dylib
- const QRegularExpression dylibRegExp("libQt[0-9]+"_L1 + module + libInFix + ".[0-9]+.dylib"_L1);
+ const QRegularExpression dylibRegExp("libQt[0-9]+"_L1
+ + module + libInFix
+ + (isDebug ? "_debug" : "")
+ + ".[0-9]+.dylib"_L1);
return deployedFrameworks.filter(dylibRegExp).size() > 0;
}
/*
- Deploys the the listed frameworks listed into an app bundle.
+ Deploys the listed frameworks into an app bundle.
The frameworks are searched for dependencies, which are also deployed.
(deploying Qt3Support will also deploy QtNetwork and QtSql for example.)
Returns a DeploymentInfo structure containing the Qt path used and a
@@ -1094,8 +1117,10 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
const QString libInfix = getLibInfix(deploymentInfo.deployedFrameworks);
// Network
- if (deploymentInfo.containsModule("Network", libInfix))
+ if (deploymentInfo.containsModule("Network", libInfix)) {
addPlugins(QStringLiteral("tls"));
+ addPlugins(QStringLiteral("networkinformation"));
+ }
// All image formats (svg if QtSvg is used)
const bool usesSvg = deploymentInfo.containsModule("Svg", libInfix);
@@ -1146,7 +1171,7 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
}
static const std::map<QString, std::vector<QString>> map {
- {QStringLiteral("Multimedia"), {QStringLiteral("mediaservice"), QStringLiteral("audio")}},
+ {QStringLiteral("Multimedia"), {QStringLiteral("multimedia")}},
{QStringLiteral("3DRender"), {QStringLiteral("sceneparsers"), QStringLiteral("geometryloaders"), QStringLiteral("renderers")}},
{QStringLiteral("3DQuickRender"), {QStringLiteral("renderplugins")}},
{QStringLiteral("Positioning"), {QStringLiteral("position")}},