Attempt at closing #3, reopen if this causes issues
This commit is contained in:
@@ -22,8 +22,8 @@ Options:
|
|||||||
-no-plugins : Skip plugin deployment
|
-no-plugins : Skip plugin deployment
|
||||||
-appimage : Create an AppImage
|
-appimage : Create an AppImage
|
||||||
-no-strip : Don't run 'strip' on the binaries
|
-no-strip : Don't run 'strip' on the binaries
|
||||||
-use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)
|
-use-debug-libs : Deploy with debug versions of libraries and plugins (implies -no-strip)
|
||||||
-executable=<path> : Let the given executable use the deployed frameworks too
|
-executable=<path> : Let the given executable use the deployed libraries too
|
||||||
-qmldir=<path> : Scan for QML imports in the given path
|
-qmldir=<path> : Scan for QML imports in the given path
|
||||||
-always-overwrite : Copy files even if the target file exists
|
-always-overwrite : Copy files even if the target file exists
|
||||||
-libpath=<path> : Add the given path to the library search path
|
-libpath=<path> : Add the given path to the library search path
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ int main(int argc, char **argv)
|
|||||||
qDebug() << " -no-plugins : Skip plugin deployment";
|
qDebug() << " -no-plugins : Skip plugin deployment";
|
||||||
qDebug() << " -appimage : Create an AppImage";
|
qDebug() << " -appimage : Create an AppImage";
|
||||||
qDebug() << " -no-strip : Don't run 'strip' on the binaries";
|
qDebug() << " -no-strip : Don't run 'strip' on the binaries";
|
||||||
qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)";
|
qDebug() << " -use-debug-libs : Deploy with debug versions of libraries and plugins (implies -no-strip)";
|
||||||
qDebug() << " -executable=<path> : Let the given executable use the deployed frameworks too";
|
qDebug() << " -executable=<path> : Let the given executable use the deployed libraries too";
|
||||||
qDebug() << " -qmldir=<path> : Scan for QML imports in the given path";
|
qDebug() << " -qmldir=<path> : Scan for QML imports in the given path";
|
||||||
qDebug() << " -always-overwrite : Copy files even if the target file exists";
|
qDebug() << " -always-overwrite : Copy files even if the target file exists";
|
||||||
qDebug() << " -libpath=<path> : Add the given path to the library search path";
|
qDebug() << " -libpath=<path> : Add the given path to the library search path";
|
||||||
@@ -160,7 +160,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath, additionalExecutables, useDebugLibs);
|
DeploymentInfo deploymentInfo = deployQtLibraries(appBundlePath, additionalExecutables, useDebugLibs);
|
||||||
|
|
||||||
// Convenience: Look for .qml files in the current directoty if no -qmldir specified.
|
// Convenience: Look for .qml files in the current directoty if no -qmldir specified.
|
||||||
if (qmlDirs.isEmpty()) {
|
if (qmlDirs.isEmpty()) {
|
||||||
@@ -175,11 +175,11 @@ int main(int argc, char **argv)
|
|||||||
if (!ok && qmldirArgumentUsed)
|
if (!ok && qmldirArgumentUsed)
|
||||||
return 1; // exit if the user explicitly asked for qml import deployment
|
return 1; // exit if the user explicitly asked for qml import deployment
|
||||||
|
|
||||||
// Update deploymentInfo.deployedFrameworks - the QML imports
|
// Update deploymentInfo.deployedLibraries - the QML imports
|
||||||
// may have brought in extra frameworks as dependencies.
|
// may have brought in extra libraries as dependencies.
|
||||||
// deploymentInfo.deployedFrameworks += findAppFrameworkNames(appBundlePath);
|
// deploymentInfo.deployedLibraries += findAppLibraryNames(appBundlePath);
|
||||||
deploymentInfo.deployedFrameworks += findAppLibraries(appBundlePath);
|
deploymentInfo.deployedLibraries += findAppLibraries(appBundlePath);
|
||||||
deploymentInfo.deployedFrameworks = deploymentInfo.deployedFrameworks.toSet().toList();
|
deploymentInfo.deployedLibraries = deploymentInfo.deployedLibraries.toSet().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugins && !deploymentInfo.qtPath.isEmpty()) {
|
if (plugins && !deploymentInfo.qtPath.isEmpty()) {
|
||||||
|
|||||||
+99
-99
@@ -50,21 +50,21 @@ bool alwaysOwerwriteEnabled = false;
|
|||||||
QStringList librarySearchPath;
|
QStringList librarySearchPath;
|
||||||
bool appstoreCompliant = false;
|
bool appstoreCompliant = false;
|
||||||
int logLevel = 1;
|
int logLevel = 1;
|
||||||
bool deployFramework = false;
|
bool deployLibrary = false;
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
||||||
bool operator==(const FrameworkInfo &a, const FrameworkInfo &b)
|
bool operator==(const LibraryInfo &a, const LibraryInfo &b)
|
||||||
{
|
{
|
||||||
return ((a.frameworkPath == b.frameworkPath) && (a.binaryPath == b.binaryPath));
|
return ((a.libraryPath == b.libraryPath) && (a.binaryPath == b.binaryPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const FrameworkInfo &info)
|
QDebug operator<<(QDebug debug, const LibraryInfo &info)
|
||||||
{
|
{
|
||||||
debug << "Framework name" << info.frameworkName << "\n";
|
debug << "Library name" << info.libraryName << "\n";
|
||||||
debug << "Framework directory" << info.frameworkDirectory << "\n";
|
debug << "Library directory" << info.libraryDirectory << "\n";
|
||||||
debug << "Framework path" << info.frameworkPath << "\n";
|
debug << "Library path" << info.libraryPath << "\n";
|
||||||
debug << "Binary directory" << info.binaryDirectory << "\n";
|
debug << "Binary directory" << info.binaryDirectory << "\n";
|
||||||
debug << "Binary name" << info.binaryName << "\n";
|
debug << "Binary name" << info.binaryName << "\n";
|
||||||
debug << "Binary path" << info.binaryPath << "\n";
|
debug << "Binary path" << info.binaryPath << "\n";
|
||||||
@@ -72,13 +72,13 @@ QDebug operator<<(QDebug debug, const FrameworkInfo &info)
|
|||||||
debug << "Install name" << info.installName << "\n";
|
debug << "Install name" << info.installName << "\n";
|
||||||
debug << "Deployed install name" << info.deployedInstallName << "\n";
|
debug << "Deployed install name" << info.deployedInstallName << "\n";
|
||||||
debug << "Source file Path" << info.sourceFilePath << "\n";
|
debug << "Source file Path" << info.sourceFilePath << "\n";
|
||||||
debug << "Framework Destination Directory (relative to bundle)" << info.frameworkDestinationDirectory << "\n";
|
debug << "Library Destination Directory (relative to bundle)" << info.libraryDestinationDirectory << "\n";
|
||||||
debug << "Binary Destination Directory (relative to bundle)" << info.binaryDestinationDirectory << "\n";
|
debug << "Binary Destination Directory (relative to bundle)" << info.binaryDestinationDirectory << "\n";
|
||||||
|
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString bundleFrameworkDirectory = "lib"; // the same directory as the main executable; could define a relative subdirectory here
|
const QString bundleLibraryDirectory = "lib"; // the same directory as the main executable; could define a relative subdirectory here
|
||||||
|
|
||||||
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info)
|
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info)
|
||||||
{
|
{
|
||||||
@@ -209,9 +209,9 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
LibraryInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
FrameworkInfo info;
|
LibraryInfo info;
|
||||||
QString trimmed = line.trimmed();
|
QString trimmed = line.trimmed();
|
||||||
|
|
||||||
LogDebug() << "parsing" << trimmed;
|
LogDebug() << "parsing" << trimmed;
|
||||||
@@ -225,14 +225,14 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl
|
|||||||
if (trimmed.startsWith("/lib"))
|
if (trimmed.startsWith("/lib"))
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
enum State {QtPath, FrameworkName, LibraryName, Version, End};
|
enum State {QtPath, LibraryName, Version, End};
|
||||||
State state = QtPath;
|
State state = QtPath;
|
||||||
int part = 0;
|
int part = 0;
|
||||||
QString name;
|
QString name;
|
||||||
QString qtPath;
|
QString qtPath;
|
||||||
QString suffix = useDebugLibs ? "_debug" : "";
|
QString suffix = useDebugLibs ? "_debug" : "";
|
||||||
|
|
||||||
// Split the line into [Qt-path]/lib/qt[Module].framework/Versions/[Version]/
|
// Split the line into [Qt-path]/lib/qt[Module].library/Versions/[Version]/
|
||||||
QStringList parts = trimmed.split("/");
|
QStringList parts = trimmed.split("/");
|
||||||
while (part < parts.count()) {
|
while (part < parts.count()) {
|
||||||
const QString currentPart = parts.at(part).simplified() ;
|
const QString currentPart = parts.at(part).simplified() ;
|
||||||
@@ -243,8 +243,8 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl
|
|||||||
if (state == QtPath) {
|
if (state == QtPath) {
|
||||||
// Check for library name part
|
// Check for library name part
|
||||||
if (part < parts.count() && parts.at(part).contains(".so")) {
|
if (part < parts.count() && parts.at(part).contains(".so")) {
|
||||||
info.frameworkDirectory += "/" + (qtPath + currentPart + "/").simplified();
|
info.libraryDirectory += "/" + (qtPath + currentPart + "/").simplified();
|
||||||
LogDebug() << "info.frameworkDirectory:" << info.frameworkDirectory;
|
LogDebug() << "info.libraryDirectory:" << info.libraryDirectory;
|
||||||
state = LibraryName;
|
state = LibraryName;
|
||||||
continue;
|
continue;
|
||||||
} else if (trimmed.startsWith("/") == false) { // If the line does not contain a full path, the app is using a binary Qt package.
|
} else if (trimmed.startsWith("/") == false) { // If the line does not contain a full path, the app is using a binary Qt package.
|
||||||
@@ -255,14 +255,14 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl
|
|||||||
path += '/';
|
path += '/';
|
||||||
QString nameInPath = path + parts.join("/");
|
QString nameInPath = path + parts.join("/");
|
||||||
if (QFile::exists(nameInPath)) {
|
if (QFile::exists(nameInPath)) {
|
||||||
info.frameworkDirectory = path + partsCopy.join("/");
|
info.libraryDirectory = path + partsCopy.join("/");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.frameworkDirectory.isEmpty())
|
if (info.libraryDirectory.isEmpty())
|
||||||
info.frameworkDirectory = "/usr/lib/" + partsCopy.join("/");
|
info.libraryDirectory = "/usr/lib/" + partsCopy.join("/");
|
||||||
if (!info.frameworkDirectory.endsWith("/"))
|
if (!info.libraryDirectory.endsWith("/"))
|
||||||
info.frameworkDirectory += "/";
|
info.libraryDirectory += "/";
|
||||||
state = LibraryName;
|
state = LibraryName;
|
||||||
--part;
|
--part;
|
||||||
continue;
|
continue;
|
||||||
@@ -272,15 +272,15 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl
|
|||||||
} if (state == LibraryName) {
|
} if (state == LibraryName) {
|
||||||
name = currentPart;
|
name = currentPart;
|
||||||
info.isDylib = true;
|
info.isDylib = true;
|
||||||
info.frameworkName = name;
|
info.libraryName = name;
|
||||||
info.binaryName = name.left(name.indexOf('.')) + suffix + name.mid(name.indexOf('.'));
|
info.binaryName = name.left(name.indexOf('.')) + suffix + name.mid(name.indexOf('.'));
|
||||||
info.deployedInstallName = "$ORIGIN"; // + info.binaryName;
|
info.deployedInstallName = "$ORIGIN"; // + info.binaryName;
|
||||||
info.frameworkPath = info.frameworkDirectory + info.binaryName;
|
info.libraryPath = info.libraryDirectory + info.binaryName;
|
||||||
info.sourceFilePath = info.frameworkPath;
|
info.sourceFilePath = info.libraryPath;
|
||||||
info.frameworkDestinationDirectory = bundleFrameworkDirectory + "/";
|
info.libraryDestinationDirectory = bundleLibraryDirectory + "/";
|
||||||
info.binaryDestinationDirectory = info.frameworkDestinationDirectory;
|
info.binaryDestinationDirectory = info.libraryDestinationDirectory;
|
||||||
info.binaryDirectory = info.frameworkDirectory;
|
info.binaryDirectory = info.libraryDirectory;
|
||||||
info.binaryPath = info.frameworkPath;
|
info.binaryPath = info.libraryPath;
|
||||||
state = End;
|
state = End;
|
||||||
++part;
|
++part;
|
||||||
continue;
|
continue;
|
||||||
@@ -354,13 +354,13 @@ QStringList findAppBundleFiles(const QString &appBundlePath, bool absolutePath =
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FrameworkInfo> getQtFrameworks(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
QList<LibraryInfo> getQtLibraries(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
QList<FrameworkInfo> libraries;
|
QList<LibraryInfo> libraries;
|
||||||
for (const DylibInfo &dylibInfo : dependencies) {
|
for (const DylibInfo &dylibInfo : dependencies) {
|
||||||
FrameworkInfo info = parseOtoolLibraryLine(dylibInfo.binaryPath, appBundlePath, rpaths, useDebugLibs);
|
LibraryInfo info = parseOtoolLibraryLine(dylibInfo.binaryPath, appBundlePath, rpaths, useDebugLibs);
|
||||||
if (info.frameworkName.isEmpty() == false) {
|
if (info.libraryName.isEmpty() == false) {
|
||||||
LogDebug() << "Adding framework:";
|
LogDebug() << "Adding library:";
|
||||||
LogDebug() << info;
|
LogDebug() << info;
|
||||||
libraries.append(info);
|
libraries.append(info);
|
||||||
}
|
}
|
||||||
@@ -405,21 +405,21 @@ 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<LibraryInfo> getQtLibraries(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
const OtoolInfo info = findDependencyInfo(path);
|
const OtoolInfo info = findDependencyInfo(path);
|
||||||
return getQtFrameworks(info.dependencies, appBundlePath, rpaths + getBinaryRPaths(path), useDebugLibs);
|
return getQtLibraries(info.dependencies, appBundlePath, rpaths + getBinaryRPaths(path), useDebugLibs);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FrameworkInfo> getQtFrameworksForPaths(const QStringList &paths, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
QList<LibraryInfo> getQtLibrariesForPaths(const QStringList &paths, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
QList<FrameworkInfo> result;
|
QList<LibraryInfo> result;
|
||||||
QSet<QString> existing;
|
QSet<QString> existing;
|
||||||
|
|
||||||
foreach (const QString &path, paths) {
|
foreach (const QString &path, paths) {
|
||||||
foreach (const FrameworkInfo &info, getQtFrameworks(path, appBundlePath, rpaths, useDebugLibs)) {
|
foreach (const LibraryInfo &info, getQtLibraries(path, appBundlePath, rpaths, useDebugLibs)) {
|
||||||
if (!existing.contains(info.frameworkPath)) { // avoid duplicates
|
if (!existing.contains(info.libraryPath)) { // avoid duplicates
|
||||||
existing.insert(info.frameworkPath);
|
existing.insert(info.libraryPath);
|
||||||
result << info;
|
result << info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,17 +521,17 @@ void recursiveCopyAndDeploy(const QString &appBundlePath, const QSet<QString> &r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString copyDylib(const FrameworkInfo &framework, const QString path)
|
QString copyDylib(const LibraryInfo &library, const QString path)
|
||||||
{
|
{
|
||||||
if (!QFile::exists(framework.sourceFilePath)) {
|
if (!QFile::exists(library.sourceFilePath)) {
|
||||||
LogError() << "no file at" << framework.sourceFilePath;
|
LogError() << "no file at" << library.sourceFilePath;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct destination paths. The full path typically looks like
|
// Construct destination paths. The full path typically looks like
|
||||||
// MyApp.app/Contents/Frameworks/libfoo.dylib
|
// MyApp.app/Contents/Libraries/libfoo.dylib
|
||||||
QString dylibDestinationDirectory = path + QLatin1Char('/') + framework.frameworkDestinationDirectory;
|
QString dylibDestinationDirectory = path + QLatin1Char('/') + library.libraryDestinationDirectory;
|
||||||
QString dylibDestinationBinaryPath = dylibDestinationDirectory + QLatin1Char('/') + framework.binaryName;
|
QString dylibDestinationBinaryPath = dylibDestinationDirectory + QLatin1Char('/') + library.binaryName;
|
||||||
|
|
||||||
// Create destination directory
|
// Create destination directory
|
||||||
if (!QDir().mkpath(dylibDestinationDirectory)) {
|
if (!QDir().mkpath(dylibDestinationDirectory)) {
|
||||||
@@ -544,7 +544,7 @@ QString copyDylib(const FrameworkInfo &framework, const QString path)
|
|||||||
return dylibDestinationBinaryPath;
|
return dylibDestinationBinaryPath;
|
||||||
|
|
||||||
// Copy dylib binary
|
// Copy dylib binary
|
||||||
copyFilePrintStatus(framework.sourceFilePath, dylibDestinationBinaryPath);
|
copyFilePrintStatus(library.sourceFilePath, dylibDestinationBinaryPath);
|
||||||
return dylibDestinationBinaryPath;
|
return dylibDestinationBinaryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,83 +602,83 @@ void stripAppBinary(const QString &bundlePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Deploys the the listed frameworks listed into an app bundle.
|
Deploys the the libraries listed into an app bundle.
|
||||||
The frameworks are searched for dependencies, which are also deployed.
|
The libraries are searched for dependencies, which are also deployed.
|
||||||
(deploying Qt3Support will also deploy QtNetwork and QtSql for example.)
|
(deploying Qt3Support will also deploy QtNetwork and QtSql for example.)
|
||||||
Returns a DeploymentInfo structure containing the Qt path used and a
|
Returns a DeploymentInfo structure containing the Qt path used and a
|
||||||
a list of actually deployed frameworks.
|
a list of actually deployed libraries.
|
||||||
*/
|
*/
|
||||||
DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
|
DeploymentInfo deployQtLibraries(QList<LibraryInfo> libraries,
|
||||||
const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs,
|
const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs,
|
||||||
bool useLoaderPath)
|
bool useLoaderPath)
|
||||||
{
|
{
|
||||||
LogNormal();
|
LogNormal();
|
||||||
LogNormal() << "Deploying libraries found inside:" << binaryPaths;
|
LogNormal() << "Deploying libraries found inside:" << binaryPaths;
|
||||||
QStringList copiedFrameworks;
|
QStringList copiedLibraries;
|
||||||
DeploymentInfo deploymentInfo;
|
DeploymentInfo deploymentInfo;
|
||||||
deploymentInfo.useLoaderPath = useLoaderPath;
|
deploymentInfo.useLoaderPath = useLoaderPath;
|
||||||
QSet<QString> rpathsUsed;
|
QSet<QString> rpathsUsed;
|
||||||
|
|
||||||
while (frameworks.isEmpty() == false) {
|
while (libraries.isEmpty() == false) {
|
||||||
const FrameworkInfo framework = frameworks.takeFirst();
|
const LibraryInfo library = libraries.takeFirst();
|
||||||
copiedFrameworks.append(framework.frameworkName);
|
copiedLibraries.append(library.libraryName);
|
||||||
|
|
||||||
if(framework.frameworkName.contains("libQt") and framework.frameworkName.contains("Core.so")) {
|
if(library.libraryName.contains("libQt") and library.libraryName.contains("Core.so")) {
|
||||||
LogNormal() << "Setting deploymentInfo.qtPath to:" << framework.frameworkDirectory;
|
LogNormal() << "Setting deploymentInfo.qtPath to:" << library.libraryDirectory;
|
||||||
deploymentInfo.qtPath = framework.frameworkDirectory;
|
deploymentInfo.qtPath = library.libraryDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (framework.frameworkDirectory.startsWith(bundlePath)) {
|
if (library.libraryDirectory.startsWith(bundlePath)) {
|
||||||
qDebug() << framework.frameworkName << "already deployed, skipping.";
|
qDebug() << library.libraryName << "already deployed, skipping.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framework.rpathUsed.isEmpty() != true) {
|
if (library.rpathUsed.isEmpty() != true) {
|
||||||
rpathsUsed << framework.rpathUsed;
|
rpathsUsed << library.rpathUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the framework/dylib to the app bundle.
|
// Copy the library/dylib to the app bundle.
|
||||||
const QString deployedBinaryPath = copyDylib(framework, bundlePath);
|
const QString deployedBinaryPath = copyDylib(library, bundlePath);
|
||||||
// Skip the rest if already was deployed.
|
// Skip the rest if already was deployed.
|
||||||
if (deployedBinaryPath.isNull())
|
if (deployedBinaryPath.isNull())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
runStrip(deployedBinaryPath);
|
runStrip(deployedBinaryPath);
|
||||||
|
|
||||||
if (!framework.rpathUsed.length()) {
|
if (!library.rpathUsed.length()) {
|
||||||
changeIdentification(framework.deployedInstallName, deployedBinaryPath);
|
changeIdentification(library.deployedInstallName, deployedBinaryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for framework dependencies
|
// Check for library dependencies
|
||||||
QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath, bundlePath, rpathsUsed, useDebugLibs);
|
QList<LibraryInfo> dependencies = getQtLibraries(deployedBinaryPath, bundlePath, rpathsUsed, useDebugLibs);
|
||||||
|
|
||||||
foreach (FrameworkInfo dependency, dependencies) {
|
foreach (LibraryInfo dependency, dependencies) {
|
||||||
if (dependency.rpathUsed.isEmpty() != true) {
|
if (dependency.rpathUsed.isEmpty() != true) {
|
||||||
rpathsUsed << dependency.rpathUsed;
|
rpathsUsed << dependency.rpathUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deploy framework if necessary.
|
// Deploy library if necessary.
|
||||||
if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) {
|
if (copiedLibraries.contains(dependency.libraryName) == false && libraries.contains(dependency) == false) {
|
||||||
frameworks.append(dependency);
|
libraries.append(dependency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deploymentInfo.deployedFrameworks = copiedFrameworks;
|
deploymentInfo.deployedLibraries = copiedLibraries;
|
||||||
|
|
||||||
deploymentInfo.rpathsUsed += rpathsUsed;
|
deploymentInfo.rpathsUsed += rpathsUsed;
|
||||||
|
|
||||||
return deploymentInfo;
|
return deploymentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs)
|
DeploymentInfo deployQtLibraries(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
ApplicationBundleInfo applicationBundle;
|
ApplicationBundleInfo applicationBundle;
|
||||||
applicationBundle.path = appBundlePath;
|
applicationBundle.path = appBundlePath;
|
||||||
LogDebug() << "applicationBundle.path:" << applicationBundle.path;
|
LogDebug() << "applicationBundle.path:" << applicationBundle.path;
|
||||||
applicationBundle.binaryPath = findAppBinary(appBundlePath);
|
applicationBundle.binaryPath = findAppBinary(appBundlePath);
|
||||||
LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath;
|
LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath;
|
||||||
changeIdentification("$ORIGIN/" + bundleFrameworkDirectory, applicationBundle.binaryPath);
|
changeIdentification("$ORIGIN/" + bundleLibraryDirectory, applicationBundle.binaryPath);
|
||||||
applicationBundle.libraryPaths = findAppLibraries(appBundlePath);
|
applicationBundle.libraryPaths = findAppLibraries(appBundlePath);
|
||||||
LogDebug() << "applicationBundle.libraryPaths:" << applicationBundle.libraryPaths;
|
LogDebug() << "applicationBundle.libraryPaths:" << applicationBundle.libraryPaths;
|
||||||
|
|
||||||
@@ -693,15 +693,15 @@ DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringLis
|
|||||||
|
|
||||||
LogDebug() << "allLibraryPaths:" << allLibraryPaths;
|
LogDebug() << "allLibraryPaths:" << allLibraryPaths;
|
||||||
|
|
||||||
QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(allBinaryPaths, appBundlePath, allLibraryPaths, useDebugLibs);
|
QList<LibraryInfo> libraries = getQtLibrariesForPaths(allBinaryPaths, appBundlePath, allLibraryPaths, useDebugLibs);
|
||||||
if (frameworks.isEmpty() && !alwaysOwerwriteEnabled) {
|
if (libraries.isEmpty() && !alwaysOwerwriteEnabled) {
|
||||||
LogWarning();
|
LogWarning();
|
||||||
LogWarning() << "Could not find any external Qt frameworks to deploy in" << appBundlePath;
|
LogWarning() << "Could not find any external Qt libraries to deploy in" << appBundlePath;
|
||||||
LogWarning() << "Perhaps linuxdeployqt was already used on" << appBundlePath << "?";
|
LogWarning() << "Perhaps linuxdeployqt was already used on" << appBundlePath << "?";
|
||||||
LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again.";
|
LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again.";
|
||||||
return DeploymentInfo();
|
return DeploymentInfo();
|
||||||
} else {
|
} else {
|
||||||
return deployQtFrameworks(frameworks, applicationBundle.path, allBinaryPaths, useDebugLibs, !additionalExecutables.isEmpty());
|
return deployQtLibraries(libraries, applicationBundle.path, allBinaryPaths, useDebugLibs, !additionalExecutables.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,33 +724,33 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
|||||||
pluginList.append("printsupport/libcupsprintersupport.so");
|
pluginList.append("printsupport/libcupsprintersupport.so");
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtNetwork"))) {
|
if (deploymentInfo.deployedLibraries.contains(QStringLiteral("QtNetwork"))) {
|
||||||
QStringList bearerPlugins = QDir(pluginSourcePath + QStringLiteral("/bearer")).entryList(QStringList() << QStringLiteral("*.so"));
|
QStringList bearerPlugins = QDir(pluginSourcePath + QStringLiteral("/bearer")).entryList(QStringList() << QStringLiteral("*.so"));
|
||||||
foreach (const QString &plugin, bearerPlugins) {
|
foreach (const QString &plugin, bearerPlugins) {
|
||||||
pluginList.append(QStringLiteral("bearer/") + plugin);
|
pluginList.append(QStringLiteral("bearer/") + plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All image formats (svg if QtSvg.framework is used)
|
// All image formats (svg if QtSvg.library is used)
|
||||||
QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.so"));
|
QStringList imagePlugins = QDir(pluginSourcePath + QStringLiteral("/imageformats")).entryList(QStringList() << QStringLiteral("*.so"));
|
||||||
foreach (const QString &plugin, imagePlugins) {
|
foreach (const QString &plugin, imagePlugins) {
|
||||||
if (plugin.contains(QStringLiteral("qsvg"))) {
|
if (plugin.contains(QStringLiteral("qsvg"))) {
|
||||||
if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSvg")))
|
if (deploymentInfo.deployedLibraries.contains(QStringLiteral("QtSvg")))
|
||||||
pluginList.append(QStringLiteral("imageformats/") + plugin);
|
pluginList.append(QStringLiteral("imageformats/") + plugin);
|
||||||
pluginList.append(QStringLiteral("imageformats/") + plugin);
|
pluginList.append(QStringLiteral("imageformats/") + plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sql plugins if QtSql.framework is in use
|
// Sql plugins if QtSql.library is in use
|
||||||
if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtSql"))) {
|
if (deploymentInfo.deployedLibraries.contains(QStringLiteral("QtSql"))) {
|
||||||
QStringList sqlPlugins = QDir(pluginSourcePath + QStringLiteral("/sqldrivers")).entryList(QStringList() << QStringLiteral("*.so"));
|
QStringList sqlPlugins = QDir(pluginSourcePath + QStringLiteral("/sqldrivers")).entryList(QStringList() << QStringLiteral("*.so"));
|
||||||
foreach (const QString &plugin, sqlPlugins) {
|
foreach (const QString &plugin, sqlPlugins) {
|
||||||
pluginList.append(QStringLiteral("sqldrivers/") + plugin);
|
pluginList.append(QStringLiteral("sqldrivers/") + plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// multimedia plugins if QtMultimedia.framework is in use
|
// multimedia plugins if QtMultimedia.library is in use
|
||||||
if (deploymentInfo.deployedFrameworks.contains(QStringLiteral("QtMultimedia"))) {
|
if (deploymentInfo.deployedLibraries.contains(QStringLiteral("QtMultimedia"))) {
|
||||||
QStringList plugins = QDir(pluginSourcePath + QStringLiteral("/mediaservice")).entryList(QStringList() << QStringLiteral("*.so"));
|
QStringList plugins = QDir(pluginSourcePath + QStringLiteral("/mediaservice")).entryList(QStringList() << QStringLiteral("*.so"));
|
||||||
foreach (const QString &plugin, plugins) {
|
foreach (const QString &plugin, plugins) {
|
||||||
pluginList.append(QStringLiteral("mediaservice/") + plugin);
|
pluginList.append(QStringLiteral("mediaservice/") + plugin);
|
||||||
@@ -770,8 +770,8 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
|
|||||||
|
|
||||||
if (copyFilePrintStatus(sourcePath, destinationPath)) {
|
if (copyFilePrintStatus(sourcePath, destinationPath)) {
|
||||||
runStrip(destinationPath);
|
runStrip(destinationPath);
|
||||||
QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, appBundleInfo.path, deploymentInfo.rpathsUsed, useDebugLibs);
|
QList<LibraryInfo> libraries = getQtLibraries(destinationPath, appBundleInfo.path, deploymentInfo.rpathsUsed, useDebugLibs);
|
||||||
deployQtFrameworks(frameworks, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath);
|
deployQtLibraries(libraries, appBundleInfo.path, QStringList() << destinationPath, useDebugLibs, deploymentInfo.useLoaderPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,11 +936,11 @@ bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInf
|
|||||||
// Special case:
|
// Special case:
|
||||||
// Use of QtQuick.PrivateWidgets is not discoverable at deploy-time.
|
// Use of QtQuick.PrivateWidgets is not discoverable at deploy-time.
|
||||||
// Recreate the run-time logic here as best as we can - deploy it iff
|
// Recreate the run-time logic here as best as we can - deploy it iff
|
||||||
// 1) QtWidgets.framework is used
|
// 1) QtWidgets.library is used
|
||||||
// 2) QtQuick.Controls is used
|
// 2) QtQuick.Controls is used
|
||||||
// The intended failure mode is that libwidgetsplugin.dylib will be present
|
// The intended failure mode is that libwidgetsplugin.dylib will be present
|
||||||
// in the app bundle but not used at run-time.
|
// in the app bundle but not used at run-time.
|
||||||
if (deploymentInfo.deployedFrameworks.contains("QtWidgets.framework") && qtQuickContolsInUse) {
|
if (deploymentInfo.deployedLibraries.contains("QtWidgets.library") && qtQuickContolsInUse) {
|
||||||
LogNormal() << "Deploying QML import QtQuick.PrivateWidgets";
|
LogNormal() << "Deploying QML import QtQuick.PrivateWidgets";
|
||||||
QString name = "QtQuick/PrivateWidgets";
|
QString name = "QtQuick/PrivateWidgets";
|
||||||
QString path = qmlImportsPath + QLatin1Char('/') + name;
|
QString path = qmlImportsPath + QLatin1Char('/') + name;
|
||||||
@@ -950,33 +950,33 @@ bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInf
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QStringList &binaryPaths, const QString &absoluteQtPath)
|
void changeQtLibraries(const QList<LibraryInfo> libraries, const QStringList &binaryPaths, const QString &absoluteQtPath)
|
||||||
{
|
{
|
||||||
LogNormal() << "Changing" << binaryPaths << "to link against";
|
LogNormal() << "Changing" << binaryPaths << "to link against";
|
||||||
LogNormal() << "Qt in" << absoluteQtPath;
|
LogNormal() << "Qt in" << absoluteQtPath;
|
||||||
QString finalQtPath = absoluteQtPath;
|
QString finalQtPath = absoluteQtPath;
|
||||||
|
|
||||||
if (!absoluteQtPath.startsWith("/Library/Frameworks"))
|
if (!absoluteQtPath.startsWith("/Library/Libraries"))
|
||||||
finalQtPath += "/lib/";
|
finalQtPath += "/lib/";
|
||||||
|
|
||||||
foreach (FrameworkInfo framework, frameworks) {
|
foreach (LibraryInfo library, libraries) {
|
||||||
const QString oldBinaryId = framework.installName;
|
const QString oldBinaryId = library.installName;
|
||||||
const QString newBinaryId = finalQtPath + framework.frameworkName + framework.binaryPath;
|
const QString newBinaryId = finalQtPath + library.libraryName + library.binaryPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs)
|
void changeQtLibraries(const QString appPath, const QString &qtPath, bool useDebugLibs)
|
||||||
{
|
{
|
||||||
const QString appBinaryPath = findAppBinary(appPath);
|
const QString appBinaryPath = findAppBinary(appPath);
|
||||||
const QStringList libraryPaths = findAppLibraries(appPath);
|
const QStringList libraryPaths = findAppLibraries(appPath);
|
||||||
const QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(QStringList() << appBinaryPath << libraryPaths, appPath, getBinaryRPaths(appBinaryPath, true), useDebugLibs);
|
const QList<LibraryInfo> libraries = getQtLibrariesForPaths(QStringList() << appBinaryPath << libraryPaths, appPath, getBinaryRPaths(appBinaryPath, true), useDebugLibs);
|
||||||
if (frameworks.isEmpty()) {
|
if (libraries.isEmpty()) {
|
||||||
LogWarning();
|
LogWarning();
|
||||||
LogWarning() << "Could not find any _external_ Qt frameworks to change in" << appPath;
|
LogWarning() << "Could not find any _external_ Qt libraries to change in" << appPath;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const QString absoluteQtPath = QDir(qtPath).absolutePath();
|
const QString absoluteQtPath = QDir(qtPath).absolutePath();
|
||||||
changeQtFrameworks(frameworks, QStringList() << appBinaryPath << libraryPaths, absoluteQtPath);
|
changeQtLibraries(libraries, QStringList() << appBinaryPath << libraryPaths, absoluteQtPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -43,13 +43,13 @@ extern int logLevel;
|
|||||||
|
|
||||||
extern bool runStripEnabled;
|
extern bool runStripEnabled;
|
||||||
|
|
||||||
class FrameworkInfo
|
class LibraryInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isDylib;
|
bool isDylib;
|
||||||
QString frameworkDirectory;
|
QString libraryDirectory;
|
||||||
QString frameworkName;
|
QString libraryName;
|
||||||
QString frameworkPath;
|
QString libraryPath;
|
||||||
QString binaryDirectory;
|
QString binaryDirectory;
|
||||||
QString binaryName;
|
QString binaryName;
|
||||||
QString binaryPath;
|
QString binaryPath;
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
QString installName;
|
QString installName;
|
||||||
QString deployedInstallName;
|
QString deployedInstallName;
|
||||||
QString sourceFilePath;
|
QString sourceFilePath;
|
||||||
QString frameworkDestinationDirectory;
|
QString libraryDestinationDirectory;
|
||||||
QString binaryDestinationDirectory;
|
QString binaryDestinationDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,8 +80,8 @@ public:
|
|||||||
QList<DylibInfo> dependencies;
|
QList<DylibInfo> dependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const FrameworkInfo &a, const FrameworkInfo &b);
|
bool operator==(const LibraryInfo &a, const LibraryInfo &b);
|
||||||
QDebug operator<<(QDebug debug, const FrameworkInfo &info);
|
QDebug operator<<(QDebug debug, const LibraryInfo &info);
|
||||||
|
|
||||||
class ApplicationBundleInfo
|
class ApplicationBundleInfo
|
||||||
{
|
{
|
||||||
@@ -96,25 +96,25 @@ class DeploymentInfo
|
|||||||
public:
|
public:
|
||||||
QString qtPath;
|
QString qtPath;
|
||||||
QString pluginPath;
|
QString pluginPath;
|
||||||
QStringList deployedFrameworks;
|
QStringList deployedLibraries;
|
||||||
QSet<QString> rpathsUsed;
|
QSet<QString> rpathsUsed;
|
||||||
bool useLoaderPath;
|
bool useLoaderPath;
|
||||||
bool isFramework;
|
bool isLibrary;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info);
|
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info);
|
||||||
|
|
||||||
void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs);
|
void changeQtLibraries(const QString appPath, const QString &qtPath, bool useDebugLibs);
|
||||||
void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QStringList &binaryPaths, const QString &qtPath);
|
void changeQtLibraries(const QList<LibraryInfo> libraries, const QStringList &binaryPaths, const QString &qtPath);
|
||||||
|
|
||||||
OtoolInfo findDependencyInfo(const QString &binaryPath);
|
OtoolInfo findDependencyInfo(const QString &binaryPath);
|
||||||
FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs);
|
LibraryInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<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<LibraryInfo> getQtLibraries(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs);
|
||||||
QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs);
|
QList<LibraryInfo> getQtLibraries(const QStringList &otoolLines, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs);
|
||||||
QString copyFramework(const FrameworkInfo &framework, const QString path);
|
QString copyLibrary(const LibraryInfo &library, const QString path);
|
||||||
DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs);
|
DeploymentInfo deployQtLibraries(const QString &appBundlePath, const QStringList &additionalExecutables, bool useDebugLibs);
|
||||||
DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs, bool useLoaderPath);
|
DeploymentInfo deployQtLibraries(QList<LibraryInfo> libraries,const QString &bundlePath, const QStringList &binaryPaths, bool useDebugLibs, bool useLoaderPath);
|
||||||
void createQtConf(const QString &appBundlePath);
|
void createQtConf(const QString &appBundlePath);
|
||||||
void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs);
|
void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs);
|
||||||
bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInfo, QStringList &qmlDirs);
|
bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInfo, QStringList &qmlDirs);
|
||||||
|
|||||||
Reference in New Issue
Block a user