From f6664faaf90a6bf72ee9fe2e62d4bebe5733b10d Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 20 May 2017 14:58:51 +0200 Subject: [PATCH 01/10] Update shared.cpp --- shared/shared.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/shared.cpp b/shared/shared.cpp index c4e1e8f..bd139c9 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -929,6 +929,7 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a } QString output = captureOutput(qmakePath + " -query"); + LogDebug() << "-query output from qmake:" << output; QStringList outputLines = output.split("\n", QString::SkipEmptyParts); foreach (const QString &outputLine, outputLines) { From bb3968318737a3786b5e470107c120e6a9be7632 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 20 May 2017 15:16:08 +0200 Subject: [PATCH 02/10] Try patchelf 0.9 = 44b7f95 --- tests/tests-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 83254b1..68022dd 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -5,7 +5,7 @@ set -e sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty sudo apt-get update -qq -git clone https://github.com/NixOS/patchelf.git +git clone -o 44b7f95 https://github.com/NixOS/patchelf.git cd patchelf bash ./bootstrap.sh ./configure From 85b2b44f3437d23c63bc3bbb6e3a15ebaf084a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Krzemi=C5=84ski?= Date: Sat, 20 May 2017 23:14:05 +0200 Subject: [PATCH 03/10] add QNapi to project list that uses linuxdeployqt (#119) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4083e69..4b406aa 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ These projects are already using [Travis CI](http://travis-ci.org/) and linuxdep - https://github.com/crapp/labpowerqt/ - https://github.com/probonopd/linuxdeployqt/ obviously ;-) - https://github.com/xdgurl/xdgurl +- https://github.com/QNapi/qnapi This project is already using linuxdeployqt in a custom Jenkins workflow: - https://github.com/appimage-packages/ From b0cb33c9de17616f4e39cbd14895a5c9559c5b25 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 12:51:53 +0200 Subject: [PATCH 04/10] Revert "No longer generate qt.conf since we use qt_prfxpath now" Possible workaround for #98, #99, #122 This reverts commit 5df50f332b19310fd9ebd8937d49fe0cfc7bbf06. --- linuxdeployqt/main.cpp | 1 + shared/shared.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++ shared/shared.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/linuxdeployqt/main.cpp b/linuxdeployqt/main.cpp index 0d203ae..1c1ab2b 100644 --- a/linuxdeployqt/main.cpp +++ b/linuxdeployqt/main.cpp @@ -395,6 +395,7 @@ int main(int argc, char **argv) if (deploymentInfo.pluginPath.isEmpty()) deploymentInfo.pluginPath = QDir::cleanPath(deploymentInfo.qtPath + "/../plugins"); deployPlugins(appDirPath, deploymentInfo); + createQtConf(appDirPath); } if (runStripEnabled) diff --git a/shared/shared.cpp b/shared/shared.cpp index bd139c9..eaaee4a 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -1104,6 +1104,8 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath sourcePath = QDir::cleanPath(qtLibexecPath + "/QtWebEngineProcess"); destinationPath = QDir::cleanPath(dstLibexec + "/QtWebEngineProcess"); copyFilePrintStatus(sourcePath, destinationPath); + // put qt.conf file next to browser process so it can also make use of our local Qt resources + createQtConfForQtWebEngineProcess(dstLibexec); // Resources: sourcePath = QDir::cleanPath(qtDataPath + "/resources/qtwebengine_resources.pak"); destinationPath = QDir::cleanPath(dstResources + "/qtwebengine_resources.pak"); @@ -1149,6 +1151,75 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath } } +void createQtConf(const QString &appDirPath) +{ + // Set Plugins and imports paths. These are relative to QCoreApplication::applicationDirPath() + // which is where the main executable resides; see http://doc.qt.io/qt-5/qt-conf.html + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; + + // Workaround for: https://github.com/probonopd/linuxdeployqt/issues/75 + if(fhsLikeMode == true){ + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ../../\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; + } + + QString filePath = appDirPath + "/"; // Is picked up when placed next to the main executable + QString fileName = QDir::cleanPath(appBinaryPath + "/../qt.conf"); + + QDir().mkpath(filePath); + + QFile qtconf(fileName); + if (qtconf.exists() && !alwaysOwerwriteEnabled) { + + LogWarning() << fileName << "already exists, will not overwrite."; + LogWarning() << "To make sure the plugins are loaded from the correct location,"; + LogWarning() << "please make sure qt.conf contains the following lines:"; + LogWarning() << "[Paths]"; + LogWarning() << " Plugins = plugins"; + return; + } + + qtconf.open(QIODevice::WriteOnly); + if (qtconf.write(contents) != -1) { + LogNormal() << "Created configuration file:" << fileName; + LogNormal() << "This file sets the plugin search path to" << appDirPath + "/plugins"; + } +} + +void createQtConfForQtWebEngineProcess(const QString &appDirPath) +{ + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ../\n"; + QString filePath = appDirPath + "/"; + QString fileName = filePath + "qt.conf"; + + QDir().mkpath(filePath); + + QFile qtconf(fileName); + if (qtconf.exists() && !alwaysOwerwriteEnabled) { + LogWarning() << fileName << "already exists, will not overwrite."; + return; + } + + qtconf.open(QIODevice::WriteOnly); + if (qtconf.write(contents) != -1) { + LogNormal() << "Created configuration file for Qt WebEngine process:" << fileName; + LogNormal() << "This file sets the prefix option to parent directory of browser process executable"; + } +} + void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo) { AppDirInfo applicationBundle; diff --git a/shared/shared.h b/shared/shared.h index 9e0ff6d..ff00ef9 100644 --- a/shared/shared.h +++ b/shared/shared.h @@ -114,6 +114,8 @@ QList getQtLibraries(const QStringList &lddLines, const QString &ap QString copyLibrary(const LibraryInfo &library, const QString path); DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables); DeploymentInfo deployQtLibraries(QList libraries,const QString &bundlePath, const QStringList &binaryPaths, bool useLoaderPath); +void createQtConf(const QString &appDirPath); +void createQtConfForQtWebEngineProcess(const QString &appDirPath); void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo); bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QStringList &qmlDirs); void changeIdentification(const QString &id, const QString &binaryPath); From e5b7c2f43393e58efb1c2442e0becfe29c33708a Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 13:17:45 +0200 Subject: [PATCH 05/10] Try Qt 5.7.1 to see whether it also segfaults on Travis CI --- tests/tests-environment.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index 68022dd..d21e0cf 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -2,7 +2,7 @@ set -e -sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty +sudo add-apt-repository --yes ppa:beineri/opt-qt571-trusty sudo apt-get update -qq git clone -o 44b7f95 https://github.com/NixOS/patchelf.git @@ -21,4 +21,4 @@ chmod +x appimagetool*AppImage sudo cp squashfs-root/usr/bin/* /usr/local/bin cd - -sudo apt-get -y install qt58base qt58declarative qt58webengine binutils xpra +sudo apt-get -y install qt57base qt57declarative qt57webengine binutils xpra From 731c08ad89130bea6d2217cc69cd163b6558be8f Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 13:28:29 +0200 Subject: [PATCH 06/10] Modify qt.conf --- shared/shared.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index eaaee4a..54cfa1c 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -1155,22 +1155,23 @@ void createQtConf(const QString &appDirPath) { // Set Plugins and imports paths. These are relative to QCoreApplication::applicationDirPath() // which is where the main executable resides; see http://doc.qt.io/qt-5/qt-conf.html - QByteArray contents = "# Generated by linuxdeployqt\n" - "# https://github.com/probonopd/linuxdeployqt/\n" - "[Paths]\n" - "Plugins = plugins\n" - "Imports = qml\n" - "Qml2Imports = qml\n"; - - // Workaround for: https://github.com/probonopd/linuxdeployqt/issues/75 - if(fhsLikeMode == true){ - QByteArray contents = "# Generated by linuxdeployqt\n" - "# https://github.com/probonopd/linuxdeployqt/\n" - "[Paths]\n" - "Prefix = ../../\n" - "Plugins = plugins\n" - "Imports = qml\n" - "Qml2Imports = qml\n"; + // See https://github.com/probonopd/linuxdeployqt/issues/ 75, 98, 99 + + if(fhsLikeMode){ + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Prefix = ../\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; + } else { + QByteArray contents = "# Generated by linuxdeployqt\n" + "# https://github.com/probonopd/linuxdeployqt/\n" + "[Paths]\n" + "Plugins = plugins\n" + "Imports = qml\n" + "Qml2Imports = qml\n"; } QString filePath = appDirPath + "/"; // Is picked up when placed next to the main executable From c79654e7e8e8fc3e3ed73d572ef7ab7dc976c400 Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 13:32:10 +0200 Subject: [PATCH 07/10] Revert "Try Qt 5.7.1 to see whether it also segfaults on Travis CI" It does. Using Qt 5.7.1 makes no difference This reverts commit e5b7c2f43393e58efb1c2442e0becfe29c33708a. --- tests/tests-environment.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests-environment.sh b/tests/tests-environment.sh index d21e0cf..68022dd 100755 --- a/tests/tests-environment.sh +++ b/tests/tests-environment.sh @@ -2,7 +2,7 @@ set -e -sudo add-apt-repository --yes ppa:beineri/opt-qt571-trusty +sudo add-apt-repository --yes ppa:beineri/opt-qt58-trusty sudo apt-get update -qq git clone -o 44b7f95 https://github.com/NixOS/patchelf.git @@ -21,4 +21,4 @@ chmod +x appimagetool*AppImage sudo cp squashfs-root/usr/bin/* /usr/local/bin cd - -sudo apt-get -y install qt57base qt57declarative qt57webengine binutils xpra +sudo apt-get -y install qt58base qt58declarative qt58webengine binutils xpra From 08d091725cdc5d9d5ebc63644705033c44f0936f Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 13:41:35 +0200 Subject: [PATCH 08/10] Update shared.cpp --- shared/shared.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index 54cfa1c..3c0f281 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -1156,9 +1156,9 @@ void createQtConf(const QString &appDirPath) // Set Plugins and imports paths. These are relative to QCoreApplication::applicationDirPath() // which is where the main executable resides; see http://doc.qt.io/qt-5/qt-conf.html // See https://github.com/probonopd/linuxdeployqt/issues/ 75, 98, 99 - + QByteArray contents; if(fhsLikeMode){ - QByteArray contents = "# Generated by linuxdeployqt\n" + contents = "# Generated by linuxdeployqt\n" "# https://github.com/probonopd/linuxdeployqt/\n" "[Paths]\n" "Prefix = ../\n" @@ -1166,9 +1166,10 @@ void createQtConf(const QString &appDirPath) "Imports = qml\n" "Qml2Imports = qml\n"; } else { - QByteArray contents = "# Generated by linuxdeployqt\n" + contents = "# Generated by linuxdeployqt\n" "# https://github.com/probonopd/linuxdeployqt/\n" "[Paths]\n" + "Prefix = ./\n" "Plugins = plugins\n" "Imports = qml\n" "Qml2Imports = qml\n"; @@ -1183,17 +1184,12 @@ void createQtConf(const QString &appDirPath) if (qtconf.exists() && !alwaysOwerwriteEnabled) { LogWarning() << fileName << "already exists, will not overwrite."; - LogWarning() << "To make sure the plugins are loaded from the correct location,"; - LogWarning() << "please make sure qt.conf contains the following lines:"; - LogWarning() << "[Paths]"; - LogWarning() << " Plugins = plugins"; return; } qtconf.open(QIODevice::WriteOnly); if (qtconf.write(contents) != -1) { LogNormal() << "Created configuration file:" << fileName; - LogNormal() << "This file sets the plugin search path to" << appDirPath + "/plugins"; } } From 1c852a19ae4447a9d5afea6a0575c6c133ab548d Mon Sep 17 00:00:00 2001 From: probonopd Date: Thu, 25 May 2017 22:53:42 +0200 Subject: [PATCH 09/10] Skip QML imports if no Qt detected --- shared/shared.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index 3c0f281..023058e 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -54,6 +54,7 @@ bool alwaysOwerwriteEnabled = false; QStringList librarySearchPath; bool appstoreCompliant = false; int logLevel = 1; +int qtDetected = 0; bool deployLibrary = false; using std::cout; @@ -889,7 +890,6 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath; // Find out whether Qt is a dependency of the application to be bundled - int qtDetected = 0; LddInfo lddInfo = findDependencyInfo(appBinaryPath); foreach (const DylibInfo dep, lddInfo.dependencies) { LogDebug() << "dep.binaryPath" << dep.binaryPath; @@ -1260,6 +1260,11 @@ void deployQmlImport(const QString &appDirPath, const QSet &rpaths, con // Scan qml files in qmldirs for import statements, deploy used imports from Qml2ImportsPath to ./qml. bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QStringList &qmlDirs) { + if(!qtDetected){ + LogDebug() << "Skipping QML imports since no Qt detected"; + return false; + } + LogNormal() << ""; LogNormal() << "Deploying QML imports "; LogNormal() << "Application QML file search path(s) is" << qmlDirs; From 195b793686ee047772a82c77ab7b222c246c1881 Mon Sep 17 00:00:00 2001 From: probonopd Date: Fri, 26 May 2017 01:50:34 +0200 Subject: [PATCH 10/10] Do not exit if qmlimportscanner is not found --- shared/shared.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/shared.cpp b/shared/shared.cpp index 023058e..316ba5a 100644 --- a/shared/shared.cpp +++ b/shared/shared.cpp @@ -1282,8 +1282,8 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, // Verify that we found a qmlimportscanner binary if (!QFile(qmlImportScannerPath).exists()) { LogError() << "qmlimportscanner not found at" << qmlImportScannerPath; - LogError() << "Rebuild qtdeclarative/tools/qmlimportscanner"; - return false; + LogError() << "Please install it if you want to bundle QML based applications."; + return true; } // build argument list for qmlimportsanner: "-rootPath foo/ -rootPath bar/ -importPath path/to/qt/qml"